C++ 如何将libvlcpp嵌入wx(v3)面板/框架

C++ 如何将libvlcpp嵌入wx(v3)面板/框架,c++,wxwidgets,libvlc,C++,Wxwidgets,Libvlc,我想使用wx(版本3及以上)和libvlcpp制作一个简单的跨平台播放器,但我不知道如何将libvlcpp窗口绑定到wx中的一个面板(位于框架内) 一些产出: [h264 @ 0x7f6b087ffd00] [0000000002454130] main input error: input control fifo overflow, trashing type=0 thread_get_buffer() failed [0000000002454130] main input error:

我想使用wx(版本3及以上)和libvlcpp制作一个简单的跨平台播放器,但我不知道如何将libvlcpp窗口绑定到wx中的一个面板(位于框架内)

一些产出:

[h264 @ 0x7f6b087ffd00] [0000000002454130] main input error: input control fifo overflow, trashing type=0
thread_get_buffer() failed
[0000000002454130] main input error: input control fifo overflow, trashing type=0
[h264 @ 0x7f6b087ffd00] decode_slice_header error
[h264 @ 0x7f6b087ffd00] no frame!
[0000000002454130] main input error: input control fifo overflow, trashing type=0```
下面是使用vlcpp绘制wxWidgets窗口的完整示例(至少对于windows)。它是基于的,只是我把它改为使用vlcpp,并使用了一些稍微现代一些的wxWidgets特性

#include <wx/wx.h>
#include <wx/filename.h>

#ifdef __WXGTK__
    #include <gdk/gdkx.h>
    #include <gtk/gtk.h>
#endif

#include <vlcpp/vlc.hpp>

#include <climits>

#define TIMELINE_MAX (INT_MAX-9)
#define VOLUME_MAX 100

wxDEFINE_EVENT(vlcEVT_POS,wxThreadEvent);
wxDEFINE_EVENT(vlcEVT_END,wxThreadEvent);

static wxEvtHandler* gs_handler = NULL;

void OnPositionChanged_VLC(float f)
{
    if ( gs_handler )
    {
        wxThreadEvent* event = new wxThreadEvent(vlcEVT_POS);
        event->SetPayload<float>(f);
        wxQueueEvent(gs_handler,event);
    }
}

void OnEndReached_VLC()
{
    if ( gs_handler )
    {
        wxThreadEvent* event = new wxThreadEvent(vlcEVT_END);
        wxQueueEvent(gs_handler,event);
    }
}

class MainWindow : public wxFrame {
public:
    MainWindow(const wxString& title);

private:
    // Event handlers
    void OnPositionChanged(wxThreadEvent& event);
    void OnEndReached(wxThreadEvent& event);

    void OnOpen(wxCommandEvent& event);
    void OnPlayPause(wxCommandEvent& event);
    void OnStop(wxCommandEvent& event);
    void OnPositionChanged_USR(wxCommandEvent& event);
    void OnVolumeChanged(wxCommandEvent& event);
    void OnVolumeClicked(wxMouseEvent& event);
    void OnTimelineClicked(wxMouseEvent& event);
    void OnRendererWinCreated(wxWindowCreateEvent& event);

    // Helper functions.
    void Play();
    void Pause();
    void Stop();
    void SetTimeline(float value);
    void BindTimeline();
    void UnbindTimeline();

    // Video player controls.
    wxButton* m_playPauseButton;
    wxButton* m_stopButton;
    wxSlider* m_timeline;
    wxSlider* m_volumeSlider;
    wxWindow* m_playerWidget;

    // VLC objects
    VLC::Instance m_vlc;
    VLC::MediaPlayer m_player;
};

MainWindow::MainWindow(const wxString& title) : wxFrame(NULL, wxID_ANY, title)
{
    // Setup menubar.
    wxMenuBar* menubar = new wxMenuBar;
    wxMenu*file = new wxMenu;
    file->Append(wxID_OPEN, "&Open");
    menubar->Append(file, "&File");
    SetMenuBar(menubar);
    Bind(wxEVT_MENU, &MainWindow::OnOpen, this, wxID_OPEN, wxID_OPEN);

    // Create the main background panel for the frame.
    wxPanel* bgPanel = new wxPanel(this, wxID_ANY);

    // Create the window the VLC will draw to.
    m_playerWidget = new wxWindow(bgPanel, wxID_ANY);

    // Create the timeline slider.
    m_timeline = new wxSlider(bgPanel, wxID_ANY, 0, 0, TIMELINE_MAX);

    // Create play button, the stop button, and the volume slider.
    m_playPauseButton = new wxButton(bgPanel, wxID_ANY, "Play");
    m_stopButton = new wxButton(bgPanel, wxID_ANY, "Stop");
    m_volumeSlider = new wxSlider(bgPanel, wxID_ANY, VOLUME_MAX, 0, VOLUME_MAX);


    // Set the video window black and disable the timeline and buttons.
    m_playerWidget->SetBackgroundColour(*wxBLACK);
    m_timeline->Enable(false);
    m_playPauseButton->Enable(false);
    m_stopButton->Enable(false);


    // Use sizers to arrange the controls on the frame.
    wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
    vbox->Add(m_playerWidget, wxSizerFlags(1).Expand().Border(wxALL));
    vbox->Add(m_timeline, wxSizerFlags(0).Expand().Border(wxLEFT|wxRIGHT|wxBOTTOM));

    wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
    hbox->Add(m_playPauseButton, wxSizerFlags(0).Border(wxLEFT|wxRIGHT|wxBOTTOM));
    hbox->Add(m_stopButton,wxSizerFlags(0).Border(wxRIGHT|wxBOTTOM));
    hbox->AddStretchSpacer();
    hbox->Add(m_volumeSlider,wxSizerFlags(0).Border(wxRIGHT|wxBOTTOM));
    vbox->Add(hbox,wxSizerFlags(0).Expand());

    bgPanel->SetSizer(vbox);
    Layout();


    // Bind event handlers for the wxWidgets controls.
    m_playPauseButton->Bind(wxEVT_BUTTON, &MainWindow::OnPlayPause, this);
    m_stopButton->Bind(wxEVT_BUTTON, &MainWindow::OnStop, this);
    m_volumeSlider->Bind(wxEVT_SLIDER,&MainWindow::OnVolumeChanged,this);

    BindTimeline();
    m_timeline->Bind(wxEVT_LEFT_UP, &MainWindow::OnTimelineClicked,this);
    m_volumeSlider->Bind(wxEVT_LEFT_UP, &MainWindow::OnVolumeClicked,this);

    // Bind the events that will be thrown from VLC callbacks.
    Bind(vlcEVT_POS, &MainWindow::OnPositionChanged, this);
    Bind(vlcEVT_END, &MainWindow::OnEndReached, this);


    // Set up the VLC objects.
    m_vlc = VLC::Instance(0, nullptr);
    m_player = VLC::MediaPlayer(m_vlc);

#ifdef __WXGTK__
    // On GTK+, we have to wait until the window is actually created before we
    // can tell VLC to use it for output. So wait for the window create event.
    m_playerWidget->Bind(wxEVT_CREATE, &MainWindow::OnRendererWinCreated, this);
#elif defined(__WXMSW__)
    m_player.setHwnd(m_playerWidget->GetHandle());
#endif

    // Get the player's event manager and register to callbacks.
    VLC::MediaPlayerEventManager& eventManager = m_player.eventManager();
    eventManager.onPositionChanged(OnPositionChanged_VLC);
    eventManager.onEndReached(OnEndReached_VLC);

    // Set this frame to a global varriable so that it can be used with the
    // VLC callbacks.
    gs_handler = this;
}

void MainWindow::OnRendererWinCreated(wxWindowCreateEvent& event)
{
#ifdef __WXGTK__
    m_player.setXwindow(gdk_x11_window_get_xid(gtk_widget_get_window(m_playerWidget->GetHandle())));

    m_playerWidget->Unbind(wxEVT_CREATE,&MainWindow::OnRendererWinCreated,this);
#endif
}

void MainWindow::OnPositionChanged(wxThreadEvent& event)
{
    float factor = event.GetPayload<float>();
    SetTimeline(factor);
}

void MainWindow::OnEndReached(wxThreadEvent& event)
{
    Stop();
}

void MainWindow::OnOpen(wxCommandEvent& event)
{
    wxFileDialog openFileDialog(this, "Choose File");

    if (openFileDialog.ShowModal() == wxID_CANCEL)
    {
        return;
    }
    else
    {
        wxFileName filename = wxFileName::FileName(openFileDialog.GetPath());
        filename.MakeRelativeTo();
        std::string s2(filename.GetFullPath().utf8_str());

        VLC::Media media(m_vlc, s2, VLC::Media::FromPath);
        m_player.setMedia(media);
        Play();
    }
}

void MainWindow::OnPlayPause(wxCommandEvent& event)
{
    if ( m_player.isPlaying () )
    {
        Pause();
    }
    else
    {
        Play();
    }
}

void MainWindow::OnStop(wxCommandEvent& event)
{
    Stop();
}

void MainWindow::OnPositionChanged_USR(wxCommandEvent& event)
{
    m_player.setPosition((float) event.GetInt() / (float) TIMELINE_MAX);
}

void MainWindow::OnVolumeChanged(wxCommandEvent& event)
{
    m_player.setVolume(m_volumeSlider->GetValue());
}

void MainWindow::OnVolumeClicked(wxMouseEvent& event)
{
    wxSize size = m_volumeSlider->GetSize();
    float position = (float) event.GetX() / (float) size.GetWidth();
    int volume = static_cast<int>(position*VOLUME_MAX);
    m_volumeSlider->SetValue(volume);
    m_player.setVolume(volume);
    event.Skip();
}

void MainWindow::OnTimelineClicked(wxMouseEvent& event)
{
    wxSize size = m_timeline->GetSize();
    float position = (float) event.GetX() / (float) size.GetWidth();
    m_player.setPosition(position);
    SetTimeline(position);
    event.Skip();
}

void MainWindow::Play()
{;
    m_player.play();
    m_playPauseButton->SetLabel("Pause");
    m_playPauseButton->Enable(true);
    m_stopButton->Enable(true);
    m_timeline->Enable(true);
}

void MainWindow::Pause()
{
    m_player.pause();
    m_playPauseButton->SetLabel("Play");
}

void MainWindow::Stop()
{
    Pause();
#if LIBVLC_VERSION_INT >= LIBVLC_VERSION(4, 0, 0, 0)
    m_player.stopAsync();
#else
    m_player.stop();
#endif
    m_stopButton->Enable(false);
    SetTimeline(0.0);
    m_timeline->Enable(false);
}

void MainWindow::SetTimeline(float value) {
    if ( value < 0.0 )
    {
        value = 0.0;
    }
    if ( value > 1.0 )
    {
        value = 1.0;
    }

    UnbindTimeline();
    m_timeline->SetValue((int) (value * TIMELINE_MAX));
    BindTimeline();
}

void MainWindow::BindTimeline()
{
    m_timeline->Bind(wxEVT_SLIDER, &MainWindow::OnPositionChanged_USR, this);
}

void MainWindow::UnbindTimeline()
{
    m_timeline->Unbind(wxEVT_SLIDER, &MainWindow::OnPositionChanged_USR, this);
}

class MyApp : public wxApp {
    public:
        virtual bool OnInit();
};

bool MyApp::OnInit() {
    MainWindow* mainWindow = new MainWindow("wxWidgets libVLC demo");
    mainWindow->Show();
    return true;
}

wxIMPLEMENT_APP(MyApp);

#包括
#包括
#ifdef_uuwxgtk__
#包括
#包括
#恩迪夫
#包括
#包括
#定义时间线最大值(整数最大值-9)
#定义卷的最大值为100
wxDEFINE_事件(vlcEVT_位置,wxThreadEvent);
wxDEFINE_事件(vlcEVT_END,wxThreadEvent);
静态wxEvtHandler*gs_handler=NULL;
无效位置更改\u VLC(浮动f)
{
if(gs_处理器)
{
wxThreadEvent*事件=新的wxThreadEvent(vlcEVT_POS);
事件->设置有效载荷(f);
wxQueueEvent(gs_处理程序,事件);
}
}
void OnEndReached_VLC()
{
if(gs_处理器)
{
wxThreadEvent*事件=新的wxThreadEvent(vlcEVT_END);
wxQueueEvent(gs_处理程序,事件);
}
}
类主窗口:公共wxFrame{
公众:
主窗口(常量WX字符串和标题);
私人:
//事件处理程序
void OnPositionChanged(wxthread事件和事件);
void OnEndReached(wxthread事件和事件);
无效开放(wxCommandEvent&event);
无效播放暂停(wxCommandEvent&event);
顶部无效(wxCommandEvent&event);
职位变更无效(wxCommandEvent&event);
体积更改无效(wxCommandEvent&event);
VolumeClicked无效(wxMouseEvent和event);
void OnTimelineClicked(wxmousevent&event);
void onrenderwincreated(wxWindowCreateEvent&event);
//辅助函数。
无效播放();
无效暂停();
无效停止();
void SetTimeline(浮动值);
void BindTimeline();
void unbind timeline();
//视频播放器控件。
wxButton*m_播放暂停按钮;
wxButton*m_停止按钮;
wxSlider*m_时间线;
wxSlider*m_体积滑块;
wxWindow*m_playerWidget;
//VLC对象
VLC::实例m_VLC;
VLC::媒体播放器m_播放器;
};
MainWindow::MainWindow(常量wxString和title):wxFrame(NULL,wxID_ANY,title)
{
//设置菜单栏。
wxMenuBar*菜单栏=新的wxMenuBar;
wxMenu*文件=新的wxMenu;
文件->附加(wxID_OPEN,“&OPEN”);
菜单栏->附加(文件“&file”);
设置菜单栏(菜单栏);
绑定(wxEVT_菜单和主窗口::OnOpen、this、wxID_OPEN、wxID_OPEN);
//为框架创建主背景面板。
wxPanel*bgPanel=新的wxPanel(这个,wxID_ANY);
//创建VLC将绘制到的窗口。
m_playerWidget=新的wxWindow(bgPanel,wxID_ANY);
//创建时间轴滑块。
m_timeline=新的wxSlider(bgPanel,wxID_ANY,0,0,timeline_MAX);
//创建播放按钮、停止按钮和音量滑块。
m_playbausebutton=新的wxButton(bgPanel,wxID_ANY,“Play”);
m_stopButton=新的WX按钮(bgPanel,wxID_ANY,“停止”);
m_volumeSlider=新的wxSlider(bgPanel,wxID_ANY,VOLUME_MAX,0,VOLUME_MAX);
//将视频窗口设置为黑色,并禁用时间线和按钮。
m_playerWidget->SetbackgroundColor(*wxBLACK);
m_时间轴->启用(假);
m_playbausebutton->Enable(假);
m_停止按钮->启用(错误);
//使用大小调整器在框架上排列控件。
wxBoxSizer*vbox=新的wxBoxSizer(wxVERTICAL);
vbox->Add(m_playerWidget,wxSizerFlags(1).Expand().Border(wxALL));
vbox->Add(m_timeline,wxSizerFlags(0).Expand().Border(wxLEFT | wxRIGHT | wxBOTTOM));
wxBoxSizer*hbox=新的wxBoxSizer(wxHORIZONTAL);
hbox->Add(m_playbausebutton,wxSizerFlags(0).Border(wxLEFT | wxRIGHT | wxBOTTOM));
hbox->Add(m|u停止按钮,wxSizerFlags(0).Border(wxRIGHT | wxBOTTOM));
hbox->AddStretchSpacer();
hbox->Add(m_volumeSlider,wxSizerFlags(0).Border(wxRIGHT | wxBOTTOM));
vbox->Add(hbox,wxSizerFlags(0.Expand());
bgPanel->SetSizer(vbox);
布局();
//wxWidgets控件的绑定事件处理程序。
m_播放暂停按钮->绑定(wxEVT_按钮和主窗口::OnPlayPause,此按钮);
m_stopButton->Bind(wxEVT_按钮,&main窗口::在顶部,此按钮);
m_volumeSlider->Bind(wxEVT_滑块和主窗口::OnVolumeChanged,此);
BindTimeline();
m_timeline->Bind(wxEVT_LEFT_向上,&main窗口::ontimeline单击,此按钮);
m_volumeSlider->Bind(wxEVT_LEFT_向上,&main窗口::OnVolumeClicked,this);
//绑定将从VLC回调中抛出的事件。
绑定(vlcEVT_POS,&主窗口::OnPositionChanged,this);
绑定(vlcEVT_END,&主窗口::OnEndReached,this);
//设置VLC对象。
m_vlc=vlc::Instance(0,nullptr);
m_-player=VLC::MediaPlayer(m_-VLC);
#ifdef_uuwxgtk__
//在GTK+上,我们必须等到实际创建了窗口之后才能继续
//可以告诉VLC将其用于输出。所以等待窗口创建事件。
m_playerWidget->Bind(wxEVT_创建和主窗口::onrenderwincreated,此);
#已定义的elif(uuwxmsw_uuuuu)
m_player.setHwnd(m_playerWidget->GetHandle());
#恩迪夫
//获取玩家的事件管理器并注册回调。
VLC::MediaPlayerEventManager&eventManager=m_player.eventManager();
eventManager.onPositionChanged(onPositionChanged_VLC);
eventManager.onEndReached(onEndReached_VLC);
//将此框架设置为全局变量,以便与
//VLC回调。
gs_handler=这个;
}
void MainWindow::OnRenderWinCreated(wxWindowCreateEvent&event)
{
#ifdef_uuwxgtk__
m_player.setXwindow(gdk_x11_window_get_xid(gtk_widget_get_window(m_playerWidget->GetHandle());
m_playerWidget->Unbind(wxEVT_CREATE,&main窗口::onrenderwincreated,this);
#恩迪夫
}
void主窗口::OnPositionChanged(wxThreadEvent&event)
{
浮动系数=event.GetPayload();
时间线(因子);
}
void主窗口::OnEndReached(wxthreadeevent和event)
{
停止();
}
void主窗口::OnOpen(wxCommandEvent和event)
{
wxFileDialog openFileDialog(这是“选择文件”);
if(openFileDialog.showmodel()==wxID\u取消)
#include <wx/wx.h>
#include <wx/filename.h>

#ifdef __WXGTK__
    #include <gdk/gdkx.h>
    #include <gtk/gtk.h>
#endif

#include <vlcpp/vlc.hpp>

#include <climits>

#define TIMELINE_MAX (INT_MAX-9)
#define VOLUME_MAX 100

wxDEFINE_EVENT(vlcEVT_POS,wxThreadEvent);
wxDEFINE_EVENT(vlcEVT_END,wxThreadEvent);

static wxEvtHandler* gs_handler = NULL;

void OnPositionChanged_VLC(float f)
{
    if ( gs_handler )
    {
        wxThreadEvent* event = new wxThreadEvent(vlcEVT_POS);
        event->SetPayload<float>(f);
        wxQueueEvent(gs_handler,event);
    }
}

void OnEndReached_VLC()
{
    if ( gs_handler )
    {
        wxThreadEvent* event = new wxThreadEvent(vlcEVT_END);
        wxQueueEvent(gs_handler,event);
    }
}

class MainWindow : public wxFrame {
public:
    MainWindow(const wxString& title);

private:
    // Event handlers
    void OnPositionChanged(wxThreadEvent& event);
    void OnEndReached(wxThreadEvent& event);

    void OnOpen(wxCommandEvent& event);
    void OnPlayPause(wxCommandEvent& event);
    void OnStop(wxCommandEvent& event);
    void OnPositionChanged_USR(wxCommandEvent& event);
    void OnVolumeChanged(wxCommandEvent& event);
    void OnVolumeClicked(wxMouseEvent& event);
    void OnTimelineClicked(wxMouseEvent& event);
    void OnRendererWinCreated(wxWindowCreateEvent& event);

    // Helper functions.
    void Play();
    void Pause();
    void Stop();
    void SetTimeline(float value);
    void BindTimeline();
    void UnbindTimeline();

    // Video player controls.
    wxButton* m_playPauseButton;
    wxButton* m_stopButton;
    wxSlider* m_timeline;
    wxSlider* m_volumeSlider;
    wxWindow* m_playerWidget;

    // VLC objects
    VLC::Instance m_vlc;
    VLC::MediaPlayer m_player;
};

MainWindow::MainWindow(const wxString& title) : wxFrame(NULL, wxID_ANY, title)
{
    // Setup menubar.
    wxMenuBar* menubar = new wxMenuBar;
    wxMenu*file = new wxMenu;
    file->Append(wxID_OPEN, "&Open");
    menubar->Append(file, "&File");
    SetMenuBar(menubar);
    Bind(wxEVT_MENU, &MainWindow::OnOpen, this, wxID_OPEN, wxID_OPEN);

    // Create the main background panel for the frame.
    wxPanel* bgPanel = new wxPanel(this, wxID_ANY);

    // Create the window the VLC will draw to.
    m_playerWidget = new wxWindow(bgPanel, wxID_ANY);

    // Create the timeline slider.
    m_timeline = new wxSlider(bgPanel, wxID_ANY, 0, 0, TIMELINE_MAX);

    // Create play button, the stop button, and the volume slider.
    m_playPauseButton = new wxButton(bgPanel, wxID_ANY, "Play");
    m_stopButton = new wxButton(bgPanel, wxID_ANY, "Stop");
    m_volumeSlider = new wxSlider(bgPanel, wxID_ANY, VOLUME_MAX, 0, VOLUME_MAX);


    // Set the video window black and disable the timeline and buttons.
    m_playerWidget->SetBackgroundColour(*wxBLACK);
    m_timeline->Enable(false);
    m_playPauseButton->Enable(false);
    m_stopButton->Enable(false);


    // Use sizers to arrange the controls on the frame.
    wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
    vbox->Add(m_playerWidget, wxSizerFlags(1).Expand().Border(wxALL));
    vbox->Add(m_timeline, wxSizerFlags(0).Expand().Border(wxLEFT|wxRIGHT|wxBOTTOM));

    wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
    hbox->Add(m_playPauseButton, wxSizerFlags(0).Border(wxLEFT|wxRIGHT|wxBOTTOM));
    hbox->Add(m_stopButton,wxSizerFlags(0).Border(wxRIGHT|wxBOTTOM));
    hbox->AddStretchSpacer();
    hbox->Add(m_volumeSlider,wxSizerFlags(0).Border(wxRIGHT|wxBOTTOM));
    vbox->Add(hbox,wxSizerFlags(0).Expand());

    bgPanel->SetSizer(vbox);
    Layout();


    // Bind event handlers for the wxWidgets controls.
    m_playPauseButton->Bind(wxEVT_BUTTON, &MainWindow::OnPlayPause, this);
    m_stopButton->Bind(wxEVT_BUTTON, &MainWindow::OnStop, this);
    m_volumeSlider->Bind(wxEVT_SLIDER,&MainWindow::OnVolumeChanged,this);

    BindTimeline();
    m_timeline->Bind(wxEVT_LEFT_UP, &MainWindow::OnTimelineClicked,this);
    m_volumeSlider->Bind(wxEVT_LEFT_UP, &MainWindow::OnVolumeClicked,this);

    // Bind the events that will be thrown from VLC callbacks.
    Bind(vlcEVT_POS, &MainWindow::OnPositionChanged, this);
    Bind(vlcEVT_END, &MainWindow::OnEndReached, this);


    // Set up the VLC objects.
    m_vlc = VLC::Instance(0, nullptr);
    m_player = VLC::MediaPlayer(m_vlc);

#ifdef __WXGTK__
    // On GTK+, we have to wait until the window is actually created before we
    // can tell VLC to use it for output. So wait for the window create event.
    m_playerWidget->Bind(wxEVT_CREATE, &MainWindow::OnRendererWinCreated, this);
#elif defined(__WXMSW__)
    m_player.setHwnd(m_playerWidget->GetHandle());
#endif

    // Get the player's event manager and register to callbacks.
    VLC::MediaPlayerEventManager& eventManager = m_player.eventManager();
    eventManager.onPositionChanged(OnPositionChanged_VLC);
    eventManager.onEndReached(OnEndReached_VLC);

    // Set this frame to a global varriable so that it can be used with the
    // VLC callbacks.
    gs_handler = this;
}

void MainWindow::OnRendererWinCreated(wxWindowCreateEvent& event)
{
#ifdef __WXGTK__
    m_player.setXwindow(gdk_x11_window_get_xid(gtk_widget_get_window(m_playerWidget->GetHandle())));

    m_playerWidget->Unbind(wxEVT_CREATE,&MainWindow::OnRendererWinCreated,this);
#endif
}

void MainWindow::OnPositionChanged(wxThreadEvent& event)
{
    float factor = event.GetPayload<float>();
    SetTimeline(factor);
}

void MainWindow::OnEndReached(wxThreadEvent& event)
{
    Stop();
}

void MainWindow::OnOpen(wxCommandEvent& event)
{
    wxFileDialog openFileDialog(this, "Choose File");

    if (openFileDialog.ShowModal() == wxID_CANCEL)
    {
        return;
    }
    else
    {
        wxFileName filename = wxFileName::FileName(openFileDialog.GetPath());
        filename.MakeRelativeTo();
        std::string s2(filename.GetFullPath().utf8_str());

        VLC::Media media(m_vlc, s2, VLC::Media::FromPath);
        m_player.setMedia(media);
        Play();
    }
}

void MainWindow::OnPlayPause(wxCommandEvent& event)
{
    if ( m_player.isPlaying () )
    {
        Pause();
    }
    else
    {
        Play();
    }
}

void MainWindow::OnStop(wxCommandEvent& event)
{
    Stop();
}

void MainWindow::OnPositionChanged_USR(wxCommandEvent& event)
{
    m_player.setPosition((float) event.GetInt() / (float) TIMELINE_MAX);
}

void MainWindow::OnVolumeChanged(wxCommandEvent& event)
{
    m_player.setVolume(m_volumeSlider->GetValue());
}

void MainWindow::OnVolumeClicked(wxMouseEvent& event)
{
    wxSize size = m_volumeSlider->GetSize();
    float position = (float) event.GetX() / (float) size.GetWidth();
    int volume = static_cast<int>(position*VOLUME_MAX);
    m_volumeSlider->SetValue(volume);
    m_player.setVolume(volume);
    event.Skip();
}

void MainWindow::OnTimelineClicked(wxMouseEvent& event)
{
    wxSize size = m_timeline->GetSize();
    float position = (float) event.GetX() / (float) size.GetWidth();
    m_player.setPosition(position);
    SetTimeline(position);
    event.Skip();
}

void MainWindow::Play()
{;
    m_player.play();
    m_playPauseButton->SetLabel("Pause");
    m_playPauseButton->Enable(true);
    m_stopButton->Enable(true);
    m_timeline->Enable(true);
}

void MainWindow::Pause()
{
    m_player.pause();
    m_playPauseButton->SetLabel("Play");
}

void MainWindow::Stop()
{
    Pause();
#if LIBVLC_VERSION_INT >= LIBVLC_VERSION(4, 0, 0, 0)
    m_player.stopAsync();
#else
    m_player.stop();
#endif
    m_stopButton->Enable(false);
    SetTimeline(0.0);
    m_timeline->Enable(false);
}

void MainWindow::SetTimeline(float value) {
    if ( value < 0.0 )
    {
        value = 0.0;
    }
    if ( value > 1.0 )
    {
        value = 1.0;
    }

    UnbindTimeline();
    m_timeline->SetValue((int) (value * TIMELINE_MAX));
    BindTimeline();
}

void MainWindow::BindTimeline()
{
    m_timeline->Bind(wxEVT_SLIDER, &MainWindow::OnPositionChanged_USR, this);
}

void MainWindow::UnbindTimeline()
{
    m_timeline->Unbind(wxEVT_SLIDER, &MainWindow::OnPositionChanged_USR, this);
}

class MyApp : public wxApp {
    public:
        virtual bool OnInit();
};

bool MyApp::OnInit() {
    MainWindow* mainWindow = new MainWindow("wxWidgets libVLC demo");
    mainWindow->Show();
    return true;
}

wxIMPLEMENT_APP(MyApp);