]> git.sesse.net Git - vlc/blob - doc/libvlc/wx_player.cpp
udp: fix locking (fixes #14234) and cancellation
[vlc] / doc / libvlc / wx_player.cpp
1 // 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
2
3 /* License WTFPL http://sam.zoy.org/wtfpl/ */
4 /* Written by Vincent Schüßler */
5
6 #include <wx/wx.h>
7 #include <wx/filename.h>
8 #include <vlc/vlc.h>
9 #include <climits>
10
11 #ifdef __WXGTK__
12     #include <gdk/gdkx.h>
13     #include <gtk/gtk.h>
14     #include <wx/gtk/win_gtk.h>
15     #define GET_XID(window) GDK_WINDOW_XWINDOW(GTK_PIZZA(window->m_wxwindow)->bin_window)
16 #endif
17
18 #define myID_PLAYPAUSE wxID_HIGHEST+1
19 #define myID_STOP wxID_HIGHEST+2
20 #define myID_TIMELINE wxID_HIGHEST+3
21 #define myID_VOLUME wxID_HIGHEST+4
22
23 #define TIMELINE_MAX (INT_MAX-9)
24 #define VOLUME_MAX 100
25
26 DECLARE_EVENT_TYPE(vlcEVT_END, -1)
27 DECLARE_EVENT_TYPE(vlcEVT_POS, -1)
28 DEFINE_EVENT_TYPE(vlcEVT_END)
29 DEFINE_EVENT_TYPE(vlcEVT_POS)
30
31 void OnPositionChanged_VLC(const libvlc_event_t *event, void *data);
32 void OnEndReached_VLC(const libvlc_event_t *event, void *data);
33
34 class MainWindow : public wxFrame {
35     public:
36         MainWindow(const wxString& title);
37         ~MainWindow();
38
39     private:
40         void initVLC();
41
42         void OnOpen(wxCommandEvent& event);
43         void OnPlayPause(wxCommandEvent& event);
44         void OnStop(wxCommandEvent& event);
45         void OnPositionChanged_USR(wxCommandEvent& event);
46         void OnPositionChanged_VLC(wxCommandEvent& event);
47         void OnEndReached_VLC(wxCommandEvent& event);
48         void OnVolumeChanged(wxCommandEvent& event);
49         void OnVolumeClicked(wxMouseEvent& event);
50         void OnTimelineClicked(wxMouseEvent& event);
51
52         void play();
53         void pause();
54         void stop();
55         void setTimeline(float value);
56         void connectTimeline();
57
58         wxButton *playpause_button;
59         wxButton *stop_button;
60         wxSlider *timeline;
61         wxSlider *volume_slider;
62         wxWindow *player_widget;
63
64         libvlc_media_player_t *media_player;
65         libvlc_instance_t *vlc_inst;
66         libvlc_event_manager_t *vlc_evt_man;
67 };
68
69 MainWindow *mainWindow;
70
71 MainWindow::MainWindow(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition) {
72     // setup menubar
73     wxMenuBar *menubar;
74     wxMenu *file;
75     menubar = new wxMenuBar;
76     file = new wxMenu;
77     file->Append(wxID_OPEN, wxT("&Open"));
78     menubar->Append(file, wxT("&File"));
79     SetMenuBar(menubar);
80     Connect(wxID_OPEN, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainWindow::OnOpen));
81
82     // setup vbox
83     wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
84     this->SetSizer(vbox);
85
86     //setup player widget
87     player_widget = new wxWindow(this, wxID_ANY);
88     player_widget->SetBackgroundColour(wxColour(wxT("black")));
89     vbox->Add(player_widget, 1, wxEXPAND | wxALIGN_TOP);
90
91     //setup timeline slider
92     timeline = new wxSlider(this, myID_TIMELINE, 0, 0, TIMELINE_MAX);
93     timeline->Enable(false);
94     vbox->Add(timeline, 0, wxEXPAND);
95     connectTimeline();
96     timeline->Connect(myID_TIMELINE, wxEVT_LEFT_UP, wxMouseEventHandler(MainWindow::OnTimelineClicked));
97
98     //setup control panel
99     wxPanel *controlPanel = new wxPanel(this, wxID_ANY);
100
101     //setup hbox
102     wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
103     controlPanel->SetSizer(hbox);
104     vbox->Add(controlPanel, 0, wxEXPAND);
105
106     //setup controls
107     playpause_button = new wxButton(controlPanel, myID_PLAYPAUSE, wxT("Play"));
108     stop_button = new wxButton(controlPanel, myID_STOP, wxT("Stop"));
109     volume_slider = new wxSlider(controlPanel, myID_VOLUME, VOLUME_MAX, 0, VOLUME_MAX, wxDefaultPosition, wxSize(100, -1));
110     playpause_button->Enable(false);
111     stop_button->Enable(false);
112     hbox->Add(playpause_button);
113     hbox->Add(stop_button);
114     hbox->AddStretchSpacer();
115     hbox->Add(volume_slider);
116     Connect(myID_PLAYPAUSE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainWindow::OnPlayPause));
117     Connect(myID_STOP, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainWindow::OnStop));
118     Connect(myID_VOLUME, wxEVT_COMMAND_SLIDER_UPDATED, wxCommandEventHandler(MainWindow::OnVolumeChanged));
119     volume_slider->Connect(myID_VOLUME, wxEVT_LEFT_UP, wxMouseEventHandler(MainWindow::OnVolumeClicked));
120
121     //setup vlc
122     vlc_inst = libvlc_new(0, NULL);
123     media_player = libvlc_media_player_new(vlc_inst);
124     vlc_evt_man = libvlc_media_player_event_manager(media_player);
125     libvlc_event_attach(vlc_evt_man, libvlc_MediaPlayerEndReached, ::OnEndReached_VLC, NULL);
126     libvlc_event_attach(vlc_evt_man, libvlc_MediaPlayerPositionChanged, ::OnPositionChanged_VLC, NULL);
127     Connect(wxID_ANY, vlcEVT_END, wxCommandEventHandler(MainWindow::OnEndReached_VLC));
128     Connect(wxID_ANY, vlcEVT_POS, wxCommandEventHandler(MainWindow::OnPositionChanged_VLC));
129
130     Show(true);
131     initVLC();
132 }
133
134 MainWindow::~MainWindow() {
135     libvlc_media_player_release(media_player);
136     libvlc_release(vlc_inst);
137 }
138
139 void MainWindow::initVLC() {
140     #ifdef __WXGTK__
141         libvlc_media_player_set_xwindow(media_player, GET_XID(this->player_widget));
142     #else
143         libvlc_media_player_set_hwnd(media_player, this->player_widget->GetHandle());
144     #endif
145 }
146
147 void MainWindow::OnOpen(wxCommandEvent& event) {
148     wxFileDialog openFileDialog(this, wxT("Choose File"));
149
150     if (openFileDialog.ShowModal() == wxID_CANCEL) {
151         return;
152     }
153     else {
154         libvlc_media_t *media;
155         wxFileName filename = wxFileName::FileName(openFileDialog.GetPath());
156         filename.MakeRelativeTo();
157         media = libvlc_media_new_path(vlc_inst, filename.GetFullPath().mb_str());
158         libvlc_media_player_set_media(media_player, media);
159         play();
160         libvlc_media_release(media);
161     }
162 }
163
164 void MainWindow::OnPlayPause(wxCommandEvent& event) {
165     if(libvlc_media_player_is_playing(media_player) == 1) {
166         pause();
167     }
168     else {
169         play();
170     }
171 }
172
173 void MainWindow::OnStop(wxCommandEvent& event) {
174     stop();
175 }
176
177 void MainWindow::OnPositionChanged_USR(wxCommandEvent& event) {
178     libvlc_media_player_set_position(media_player, (float) event.GetInt() / (float) TIMELINE_MAX);
179 }
180
181 void MainWindow::OnPositionChanged_VLC(wxCommandEvent& event) {
182     float factor = libvlc_media_player_get_position(media_player);
183     setTimeline(factor);
184 }
185
186 void MainWindow::OnEndReached_VLC(wxCommandEvent& event) {
187     stop();
188 }
189
190 void MainWindow::OnVolumeChanged(wxCommandEvent& event) {
191     libvlc_audio_set_volume(media_player, volume_slider->GetValue());
192 }
193
194 void MainWindow::OnVolumeClicked(wxMouseEvent& event) {
195     wxSize size = mainWindow->volume_slider->GetSize();
196     float position = (float) event.GetX() / (float) size.GetWidth();
197     mainWindow->volume_slider->SetValue(position*VOLUME_MAX);
198     libvlc_audio_set_volume(mainWindow->media_player, position*VOLUME_MAX);
199     event.Skip();
200 }
201
202 void MainWindow::OnTimelineClicked(wxMouseEvent& event) {
203     wxSize size = mainWindow->timeline->GetSize();
204     float position = (float) event.GetX() / (float) size.GetWidth();
205     libvlc_media_player_set_position(mainWindow->media_player, position);
206     mainWindow->setTimeline(position);
207     event.Skip();
208 }
209
210 void MainWindow::play() {
211     libvlc_media_player_play(media_player);
212     playpause_button->SetLabel(wxT("Pause"));
213     playpause_button->Enable(true);
214     stop_button->Enable(true);
215     timeline->Enable(true);
216 }
217
218 void MainWindow::pause() {
219     libvlc_media_player_pause(media_player);
220     playpause_button->SetLabel(wxT("Play"));
221 }
222
223 void MainWindow::stop() {
224     pause();
225     libvlc_media_player_stop(media_player);
226     stop_button->Enable(false);
227     setTimeline(0.0);
228     timeline->Enable(false);
229 }
230
231 void MainWindow::setTimeline(float value) {
232     if(value < 0.0) value = 0.0;
233     if(value > 1.0) value = 1.0;
234     Disconnect(myID_TIMELINE);
235     timeline->SetValue((int) (value * TIMELINE_MAX));
236     connectTimeline();
237 }
238
239 void MainWindow::connectTimeline() {
240     Connect(myID_TIMELINE, wxEVT_COMMAND_SLIDER_UPDATED, wxCommandEventHandler(MainWindow::OnPositionChanged_USR));
241 }
242
243 class MyApp : public wxApp {
244     public:
245         virtual bool OnInit();
246 };
247
248 void OnPositionChanged_VLC(const libvlc_event_t *event, void *data) {
249     wxCommandEvent evt(vlcEVT_POS, wxID_ANY);
250     mainWindow->AddPendingEvent(evt);
251 }
252
253 void OnEndReached_VLC(const libvlc_event_t *event, void *data) {
254     wxCommandEvent evt(vlcEVT_END, wxID_ANY);
255     mainWindow->AddPendingEvent(evt);
256 }
257
258 bool MyApp::OnInit() {
259     mainWindow = new MainWindow(wxT("wxWidgets libVLC demo"));
260     return true;
261 }
262
263 IMPLEMENT_APP(MyApp)