zoukankan      html  css  js  c++  java
  • 基于libvlc和wxWidgets的简单播放器代码阅读

    源代码来自 http://git.videolan.org/?p=vlc.git;a=blob_plain;f=doc/libvlc/wx_player.cpp

    // g++ wx_player.cpp `wx-config --libs` `wx-config --cxxflags` `pkg-config --cflags gtk+-2.0 libvlc` `pkg-config --libs gtk+-2.0 libvlc` -o wx_player
    
    /* License WTFPL http://sam.zoy.org/wtfpl/ */
    /* Written by Vincent Schüßler */
    
    #include <wx/wx.h>
    #include <wx/filename.h>
    #include <vlc/vlc.h>
    #include <climits>
    
    #ifdef __WXGTK__
        #include <gdk/gdkx.h>
        #include <gtk/gtk.h>
        #include <wx/gtk/win_gtk.h>
        #define GET_XID(window) GDK_WINDOW_XWINDOW(GTK_PIZZA(window->m_wxwindow)->bin_window)
    #endif
    
    #define myID_PLAYPAUSE wxID_HIGHEST+1
    #define myID_STOP wxID_HIGHEST+2
    #define myID_TIMELINE wxID_HIGHEST+3
    #define myID_VOLUME wxID_HIGHEST+4
    
    #define TIMELINE_MAX (INT_MAX-9)
    #define VOLUME_MAX 100
    
    DECLARE_EVENT_TYPE(vlcEVT_END, -1)
    DECLARE_EVENT_TYPE(vlcEVT_POS, -1)
    DEFINE_EVENT_TYPE(vlcEVT_END)
    DEFINE_EVENT_TYPE(vlcEVT_POS)
    
    void OnPositionChanged_VLC(const libvlc_event_t *event, void *data);
    void OnEndReached_VLC(const libvlc_event_t *event, void *data);
    
    // 主窗口
    class MainWindow : public wxFrame {
        public:
            MainWindow(const wxString& title);
            ~MainWindow();
    
        private:
    		// 初始化VLC
            void initVLC();
    
            void OnOpen(wxCommandEvent& event);
            void OnPlayPause(wxCommandEvent& event);
            void OnStop(wxCommandEvent& event);
            void OnPositionChanged_USR(wxCommandEvent& event);
            void OnPositionChanged_VLC(wxCommandEvent& event);
            void OnEndReached_VLC(wxCommandEvent& event);
            void OnVolumeChanged(wxCommandEvent& event);
            void OnVolumeClicked(wxMouseEvent& event);
            void OnTimelineClicked(wxMouseEvent& event);
    
            void play();
            void pause();
            void stop();
            void setTimeline(float value);
            void connectTimeline();
    
            wxButton *playpause_button;	// 播放暂停按钮
            wxButton *stop_button;		// 停止按钮
            wxSlider *timeline;			// 进度控制滑块
            wxSlider *volume_slider;	// 音量控制滑块
            wxWindow *player_widget;	// 视频输出窗口
    
            libvlc_media_player_t *media_player;	// vlc媒体播放对象
            libvlc_instance_t *vlc_inst;			// vlc实例
            libvlc_event_manager_t *vlc_evt_man;	// vlc事件管理
    };
    
    MainWindow *mainWindow;
    
    MainWindow::MainWindow(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition) {
        // setup menubar
        wxMenuBar *menubar;
        wxMenu *file;
        menubar = new wxMenuBar;
        file = new wxMenu;
        file->Append(wxID_OPEN, wxT("&Open"));
        menubar->Append(file, wxT("&File"));
        SetMenuBar(menubar);
        Connect(wxID_OPEN, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindow::OnOpen));
    
        // setup vbox
        wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
        this->SetSizer(vbox);
    
        //setup player widget
        player_widget = new wxWindow(this, wxID_ANY);
        player_widget->SetBackgroundColour(wxColour(wxT("black")));	// 设置播放窗口颜色
        vbox->Add(player_widget, 1, wxEXPAND | wxALIGN_TOP);
    
        //setup timeline slider
        timeline = new wxSlider(this, myID_TIMELINE, 0, 0, TIMELINE_MAX);
        timeline->Enable(false);
        vbox->Add(timeline, 0, wxEXPAND);
        connectTimeline();
    	// 设置进度滑块鼠标事件回调
        timeline->Connect(myID_TIMELINE, wxEVT_LEFT_UP, wxMouseEventHandler(MainWindow::OnTimelineClicked));
    
        //setup control panel
        wxPanel *controlPanel = new wxPanel(this, wxID_ANY);
    
        //setup hbox
        wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
        controlPanel->SetSizer(hbox);
        vbox->Add(controlPanel, 0, wxEXPAND);
    
        //setup controls
        playpause_button = new wxButton(controlPanel, myID_PLAYPAUSE, wxT("Play"));
        stop_button = new wxButton(controlPanel, myID_STOP, wxT("Stop"));
        volume_slider = new wxSlider(controlPanel, myID_VOLUME, VOLUME_MAX, 0, VOLUME_MAX, wxDefaultPosition, wxSize(100, -1));
        playpause_button->Enable(false);
        stop_button->Enable(false);
        hbox->Add(playpause_button);
        hbox->Add(stop_button);
        hbox->AddStretchSpacer();
        hbox->Add(volume_slider);
        Connect(myID_PLAYPAUSE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainWindow::OnPlayPause));
        Connect(myID_STOP, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainWindow::OnStop));
        Connect(myID_VOLUME, wxEVT_COMMAND_SLIDER_UPDATED, wxCommandEventHandler(MainWindow::OnVolumeChanged));
        volume_slider->Connect(myID_VOLUME, wxEVT_LEFT_UP, wxMouseEventHandler(MainWindow::OnVolumeClicked));
    
        //setup vlc
    	// 创建vlc实例
        vlc_inst = libvlc_new(0, NULL);
    	// 创建媒体播放对象
        media_player = libvlc_media_player_new(vlc_inst);
    	// 创建vlc事件管理对象
        vlc_evt_man = libvlc_media_player_event_manager(media_player);
    	// 设置VLC事件属性
    	// 媒体播放结束事件
        libvlc_event_attach(vlc_evt_man, libvlc_MediaPlayerEndReached, ::OnEndReached_VLC, NULL);
    	// 媒体播放进度改变事件
        libvlc_event_attach(vlc_evt_man, libvlc_MediaPlayerPositionChanged, ::OnPositionChanged_VLC, NULL);
    	// wx的事件处理
    	// 处理vlcEVT_END事件
        Connect(wxID_ANY, vlcEVT_END, wxCommandEventHandler(MainWindow::OnEndReached_VLC));
    	// 处理vlcEVT_POS事件
        Connect(wxID_ANY, vlcEVT_POS, wxCommandEventHandler(MainWindow::OnPositionChanged_VLC));
    
        Show(true);
        initVLC();
    }
    
    MainWindow::~MainWindow() {
    	// 释放媒体播放对象
        libvlc_media_player_release(media_player);
        libvlc_release(vlc_inst);
    }
    
    void MainWindow::initVLC() {
        #ifdef __WXGTK__
    		// 设置视频输出的窗口
            libvlc_media_player_set_xwindow(media_player, GET_XID(this->player_widget));
        #else
    		// 这是在windows下的
            libvlc_media_player_set_hwnd(media_player, this->player_widget->GetHandle());
        #endif
    }
    
    void MainWindow::OnOpen(wxCommandEvent& event) {
        wxFileDialog openFileDialog(this, wxT("Choose File"));
    
        if (openFileDialog.ShowModal() == wxID_CANCEL) {
            return;
        }
        else {
            libvlc_media_t *media;
            wxFileName filename = wxFileName::FileName(openFileDialog.GetPath());
            filename.MakeRelativeTo();
    		// 使用本地文件创建vlc媒体对象
            media = libvlc_media_new_path(vlc_inst, filename.GetFullPath().mb_str());
    		// 给媒体播放对象设置一个媒体对象
            libvlc_media_player_set_media(media_player, media);
            play();	// 开始播放
            libvlc_media_release(media);
        }
    }
    
    void MainWindow::OnPlayPause(wxCommandEvent& event) {
        // 判断是不是播放状态
        if(libvlc_media_player_is_playing(media_player) == 1) {
            pause();
        }
        else {
            play();
        }
    }
    
    void MainWindow::OnStop(wxCommandEvent& event) {
        stop();
    }
    
    void MainWindow::OnPositionChanged_USR(wxCommandEvent& event) {
    	// 设置视频播放进度(播放位置)
        libvlc_media_player_set_position(media_player, (float) event.GetInt() / (float) TIMELINE_MAX);
    }
    
    void MainWindow::OnPositionChanged_VLC(wxCommandEvent& event) {
    	// 获取进度(获取到的是个比值,范围[0,1])
        float factor = libvlc_media_player_get_position(media_player);
        setTimeline(factor);
    }
    
    void MainWindow::OnEndReached_VLC(wxCommandEvent& event) {
        stop();
    }
    
    void MainWindow::OnVolumeChanged(wxCommandEvent& event) {
    	// 设置音量
        libvlc_audio_set_volume(media_player, volume_slider->GetValue());
    }
    
    void MainWindow::OnVolumeClicked(wxMouseEvent& event) {
        wxSize size = mainWindow->volume_slider->GetSize();
        float position = (float) event.GetX() / (float) size.GetWidth();
        mainWindow->volume_slider->SetValue(position*VOLUME_MAX);
        libvlc_audio_set_volume(mainWindow->media_player, position*VOLUME_MAX);
        event.Skip();
    }
    
    void MainWindow::OnTimelineClicked(wxMouseEvent& event) {
        wxSize size = mainWindow->timeline->GetSize();
        float position = (float) event.GetX() / (float) size.GetWidth();
        libvlc_media_player_set_position(mainWindow->media_player, position);
        mainWindow->setTimeline(position);
        event.Skip();
    }
    
    void MainWindow::play() {
    	// 媒体播放对象播放媒体
        libvlc_media_player_play(media_player);
        playpause_button->SetLabel(wxT("Pause"));
        playpause_button->Enable(true);
        stop_button->Enable(true);
        timeline->Enable(true);
    }
    
    void MainWindow::pause() {
    	// 暂停播放
        libvlc_media_player_pause(media_player);
        playpause_button->SetLabel(wxT("Play"));
    }
    
    void MainWindow::stop() {
        pause();	// 暂停
    	// 停止播放
        libvlc_media_player_stop(media_player);
        stop_button->Enable(false);
        setTimeline(0.0);
        timeline->Enable(false);
    }
    
    void MainWindow::setTimeline(float value) {
        if(value < 0.0) value = 0.0;
        if(value > 1.0) value = 1.0;
        Disconnect(myID_TIMELINE);
        timeline->SetValue((int) (value * TIMELINE_MAX));
        connectTimeline();
    }
    
    void MainWindow::connectTimeline() {
        Connect(myID_TIMELINE, wxEVT_COMMAND_SLIDER_UPDATED, wxCommandEventHandler(MainWindow::OnPositionChanged_USR));
    }
    
    class MyApp : public wxApp {
        public:
            virtual bool OnInit();
    };
    
    void OnPositionChanged_VLC(const libvlc_event_t *event, void *data) {
    	// VLC的进度改变事件(这个函数在VLC的事件处理中调用)
    	// 添加一个事件到wx
        wxCommandEvent evt(vlcEVT_POS, wxID_ANY);
        mainWindow->GetEventHandler()->AddPendingEvent(evt);
    }
    
    void OnEndReached_VLC(const libvlc_event_t *event, void *data) {
    	// VLC的播放结束事件(这个函数在VLC的事件处理中调用)
    	// 添加一个事件到wx
        wxCommandEvent evt(vlcEVT_END, wxID_ANY);
        mainWindow->GetEventHandler()->AddPendingEvent(evt);
    }
    
    bool MyApp::OnInit() {
        mainWindow = new MainWindow(wxT("wxWidgets libVLC demo"));
        return true;
    }
    
    IMPLEMENT_APP(MyApp)
    
  • 相关阅读:
    websocket使用nginx作为反向代理
    curl模拟http发送get或post接口测试
    linux tail -f messages查看控制台失败
    shell中使用>/dev/null 2>&1 丢弃信息
    mysql备份与还原
    计算机中RAM和ROM
    *C语言有关指针的变量声明中的几个易错点
    五种存储变量补充~作用域和存储时期
    typedef和#define的简单比较
    fopen()函数参数
  • 原文地址:https://www.cnblogs.com/oloroso/p/6229500.html
Copyright © 2011-2022 走看看