From 31258aa03cf77f1d6a61e8406c77989041599763 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Kempf Date: Wed, 8 Dec 2010 21:22:37 +0100 Subject: [PATCH] libVLC examples, from GCI work - Gtk+ player - wx player - Qt player - DVD ripper using Gtk --- doc/libvlc/QtPlayer/LICENSE | 13 ++ doc/libvlc/QtPlayer/QtVLC.pro | 9 + doc/libvlc/QtPlayer/main.cpp | 26 +++ doc/libvlc/QtPlayer/player.cpp | 210 ++++++++++++++++++++++ doc/libvlc/QtPlayer/player.h | 52 ++++++ doc/libvlc/gtk_player.c | 141 +++++++++++++++ doc/libvlc/libvlc_DVD_ripper.c | 306 +++++++++++++++++++++++++++++++++ doc/libvlc/wx_player.cpp | 263 ++++++++++++++++++++++++++++ 8 files changed, 1020 insertions(+) create mode 100644 doc/libvlc/QtPlayer/LICENSE create mode 100644 doc/libvlc/QtPlayer/QtVLC.pro create mode 100644 doc/libvlc/QtPlayer/main.cpp create mode 100644 doc/libvlc/QtPlayer/player.cpp create mode 100644 doc/libvlc/QtPlayer/player.h create mode 100644 doc/libvlc/gtk_player.c create mode 100644 doc/libvlc/libvlc_DVD_ripper.c create mode 100644 doc/libvlc/wx_player.cpp diff --git a/doc/libvlc/QtPlayer/LICENSE b/doc/libvlc/QtPlayer/LICENSE new file mode 100644 index 0000000000..39a257d0f4 --- /dev/null +++ b/doc/libvlc/QtPlayer/LICENSE @@ -0,0 +1,13 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/doc/libvlc/QtPlayer/QtVLC.pro b/doc/libvlc/QtPlayer/QtVLC.pro new file mode 100644 index 0000000000..c050c97126 --- /dev/null +++ b/doc/libvlc/QtPlayer/QtVLC.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +TARGET = qtvlc +DEPENDPATH += . +INCLUDEPATH += . +LIBS += -lvlc -lX11 + +# Input +HEADERS += player.h +SOURCES += main.cpp player.cpp diff --git a/doc/libvlc/QtPlayer/main.cpp b/doc/libvlc/QtPlayer/main.cpp new file mode 100644 index 0000000000..4ebf3f943c --- /dev/null +++ b/doc/libvlc/QtPlayer/main.cpp @@ -0,0 +1,26 @@ +/****************************** + * Qt player using libVLC * + * By protonux * + * * + * Under WTFPL * + ******************************/ + +#include +#include "player.h" + +#ifdef Q_WS_X11 + #include +#endif + +int main(int argc, char *argv[]) { +#ifdef Q_WS_X11 + XInitThreads(); +#endif + + QApplication app(argc, argv); + + Mwindow player; + player.show(); + + return app.exec(); +} diff --git a/doc/libvlc/QtPlayer/player.cpp b/doc/libvlc/QtPlayer/player.cpp new file mode 100644 index 0000000000..1aa6c8ba47 --- /dev/null +++ b/doc/libvlc/QtPlayer/player.cpp @@ -0,0 +1,210 @@ +/****************************** + * Qt player using libVLC * + * By protonux * + * * + * Under WTFPL * + ******************************/ +#include "player.h" +#include + +#define qtu( i ) ((i).toUtf8().constData()) + +#include + +Mwindow::Mwindow() { + vlcPlayer = NULL; + + /* Init libVLC */ + if((vlcObject = libvlc_new(0,NULL)) == NULL) { + printf("Could not init libVLC"); + exit(1); + } + + /* Display libVLC version */ + printf("libVLC version: %s\n",libvlc_get_version()); + + /* Interface initialisation */ + initMenus(); + initComponents(); +} + +Mwindow::~Mwindow() { + if(vlcObject) + libvlc_release(vlcObject); +} + +void Mwindow::initMenus() { + + centralWidget = new QWidget; + + videoWidget = new QWidget; + videoWidget->setAutoFillBackground( true ); + QPalette plt = palette(); + plt.setColor( QPalette::Window, Qt::black ); + videoWidget->setPalette( plt ); + + QMenu *fileMenu = menuBar()->addMenu("&File"); + QMenu *editMenu = menuBar()->addMenu("&Edit"); + + QAction *Open = new QAction("&Open", this); + QAction *Quit = new QAction("&Quit", this); + QAction *playAc = new QAction("&Play/Pause", this); + + Open->setShortcut(QKeySequence("Ctrl+O")); + Quit->setShortcut(QKeySequence("Ctrl+Q")); + + fileMenu->addAction(Open); + fileMenu->addAction(Quit); + editMenu->addAction(playAc); + + connect(Open, SIGNAL(triggered()), this, SLOT(openFile())); + connect(playAc, SIGNAL(triggered()), this, SLOT(play())); + connect(Quit, SIGNAL(triggered()), qApp, SLOT(quit())); +} + +void Mwindow::initComponents() { + + playBut = new QPushButton("Play"); + QObject::connect(playBut, SIGNAL(clicked()), this, SLOT(play())); + + stopBut = new QPushButton("Stop"); + QObject::connect(stopBut, SIGNAL(clicked()), this, SLOT(stop())); + + muteBut = new QPushButton("Mute"); + QObject::connect(muteBut, SIGNAL(clicked()), this, SLOT(mute())); + + volumeSlider = new QSlider(Qt::Horizontal); + QObject::connect(volumeSlider, SIGNAL(sliderMoved(int)), this, SLOT(changeVolume(int))); + volumeSlider->setValue(80); + + slider = new QSlider(Qt::Horizontal); + slider->setMaximum(1000); + QObject::connect(slider, SIGNAL(sliderMoved(int)), this, SLOT(changePosition(int))); + + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(updateInterface())); + timer->start(100); + + QHBoxLayout *layout = new QHBoxLayout; + layout->addWidget(playBut); + layout->addWidget(stopBut); + layout->addWidget(muteBut); + layout->addWidget(volumeSlider); + + QVBoxLayout *layout2 = new QVBoxLayout; + layout2->addWidget(videoWidget); + layout2->addWidget(slider); + layout2->addLayout(layout); + + centralWidget->setLayout(layout2); + setCentralWidget(centralWidget); + resize( 600, 400); +} + +void Mwindow::openFile() { + /* Just the basic file-select box */ + QString fileOpen = QFileDialog::getOpenFileName(this,tr("Load a file"), "~"); + + /* Stop if something is playing */ + if( vlcPlayer && libvlc_media_player_is_playing(vlcPlayer) ) + stop(); + + /* New Media */ + libvlc_media_t *vlcMedia = libvlc_media_new_path(vlcObject,qtu(fileOpen)); + if( !vlcMedia ) + return; + + vlcPlayer = libvlc_media_player_new_from_media (vlcMedia); + libvlc_media_release(vlcMedia); + + /* Integrate the video in the interface */ +#if defined(Q_OS_MAC) + libvlc_media_player_set_nsobject(vlcPlayer, videoWidget->winId()); +#elif defined(Q_OS_UNIX) + libvlc_media_player_set_xwindow(vlcPlayer, videoWidget->winId()); +#elif defined(Q_OS_WIN) + libvlc_media_player_set_hwnd(vlcPlayer, videoWidget->winId()); +#endif + + /* And play */ + libvlc_media_player_play (vlcPlayer); + + //Set vars and text correctly + playBut->setText("Pause"); +} + +void Mwindow::play() { + + if(vlcPlayer) + { + if (libvlc_media_player_is_playing(vlcPlayer)) + { + libvlc_media_player_pause(vlcPlayer); + playBut->setText("Play"); + } + else + { + libvlc_media_player_play(vlcPlayer); + playBut->setText("Pause"); + } + } +} + +int Mwindow::changeVolume(int vol) { //Called if you change the volume slider + + if(vlcPlayer) + return libvlc_audio_set_volume (vlcPlayer,vol); + + return 0; +} + +void Mwindow::changePosition(int pos) { //Called if you change the position slider + + if(vlcPlayer) //It segfault if vlcPlayer don't exist + libvlc_media_player_set_position(vlcPlayer,(float)pos/(float)1000); +} + +void Mwindow::updateInterface() { //Update interface and check if song is finished + + if(vlcPlayer) //It segfault if vlcPlayer don't exist + { + /* update the timeline */ + float pos = libvlc_media_player_get_position(vlcPlayer); + int siderPos=(int)(pos*(float)(1000)); + slider->setValue(siderPos); + + /* Stop the media */ + if (libvlc_media_player_get_state(vlcPlayer) == 6) { this->stop(); } + } +} + +void Mwindow::stop() { + if(vlcPlayer) { + libvlc_media_player_stop(vlcPlayer); + libvlc_media_player_release(vlcPlayer); + slider->setValue(0); + playBut->setText("Play"); + } + vlcPlayer = NULL; +} + +void Mwindow::mute() { + if(vlcPlayer) { + if(volumeSlider->value() == 0) { //if already muted... + + this->changeVolume(80); + volumeSlider->setValue(80); + + } else { //else mute volume + + this->changeVolume(0); + volumeSlider->setValue(0); + + } + } +} + +void Mwindow::closeEvent(QCloseEvent *event) { + stop(); + event->accept(); +} diff --git a/doc/libvlc/QtPlayer/player.h b/doc/libvlc/QtPlayer/player.h new file mode 100644 index 0000000000..4cba9fa2f0 --- /dev/null +++ b/doc/libvlc/QtPlayer/player.h @@ -0,0 +1,52 @@ +/****************************** + * Qt player using libVLC * + * By protonux * + * * + * Under WTFPL * + ******************************/ + +#ifndef PLAYER +#define PLAYER + +#include +#include + +class Mwindow : public QMainWindow { + + Q_OBJECT + + public: + Mwindow(); + virtual ~Mwindow(); + + private slots: + void openFile(); + void play(); + void stop(); + void mute(); + + int changeVolume(int); + void changePosition(int); + void updateInterface(); + + protected: + virtual void closeEvent(QCloseEvent*); + + private: + QString current; + QPushButton *playBut; + QPushButton *stopBut; + QPushButton *muteBut; + QSlider *volumeSlider; + QSlider *slider; + QWidget *videoWidget; + QWidget *centralWidget; + libvlc_instance_t *vlcObject; + libvlc_media_player_t *vlcPlayer; + + void initMenus(); + void initComponents(); +}; + + +#endif diff --git a/doc/libvlc/gtk_player.c b/doc/libvlc/gtk_player.c new file mode 100644 index 0000000000..8196476249 --- /dev/null +++ b/doc/libvlc/gtk_player.c @@ -0,0 +1,141 @@ +// gcc -o gtk_player gtk_player.c `pkg-config --libs gtk+-2.0 libvlc` `pkg-config --cflags gtk+-2.0 libvlc` + +/* License WTFPL http://sam.zoy.org/wtfpl/ */ +/* Written by Vincent Schüßler */ + +#include +#include +#include +#include + +#define BORDER_WIDTH 6 + +void destroy(GtkWidget *widget, gpointer data); +void player_widget_on_realize(GtkWidget *widget, gpointer data); +void on_open(GtkWidget *widget, gpointer data); +void open_media(const char* uri); +void play(void); +void pause_player(void); +void on_playpause(GtkWidget *widget, gpointer data); +void on_stop(GtkWidget *widget, gpointer data); + +libvlc_media_player_t *media_player; +libvlc_instance_t *vlc_inst; +GtkWidget *playpause_button; + +void destroy(GtkWidget *widget, gpointer data) { + gtk_main_quit(); +} + +void player_widget_on_realize(GtkWidget *widget, gpointer data) { + libvlc_media_player_set_xwindow(media_player, GDK_WINDOW_XID(gtk_widget_get_window(widget))); +} + +void on_open(GtkWidget *widget, gpointer data) { + GtkWidget *dialog; + dialog = gtk_file_chooser_dialog_new("Choose Media", data, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { + char *uri; + uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog)); + open_media(uri); + g_free(uri); + } + gtk_widget_destroy(dialog); +} + +void open_media(const char* uri) { + libvlc_media_t *media; + media = libvlc_media_new_location(vlc_inst, uri); + libvlc_media_player_set_media(media_player, media); + play(); + libvlc_media_release(media); +} + +void on_playpause(GtkWidget *widget, gpointer data) { + if(libvlc_media_player_is_playing(media_player) == 1) { + pause_player(); + } + else { + play(); + } +} + +void on_stop(GtkWidget *widget, gpointer data) { + pause_player(); + libvlc_media_player_stop(media_player); +} + +void play(void) { + libvlc_media_player_play(media_player); + gtk_button_set_label(GTK_BUTTON(playpause_button), "gtk-media-pause"); +} + +void pause_player(void) { + libvlc_media_player_pause(media_player); + gtk_button_set_label(GTK_BUTTON(playpause_button), "gtk-media-play"); +} + +int main( int argc, char *argv[] ) { + GtkWidget *window, + *vbox, + *menubar, + *filemenu, + *fileitem, + *filemenu_openitem, + *player_widget, + *hbuttonbox, + *stop_button; + + gtk_init (&argc, &argv); + // setup window + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_default_size(GTK_WINDOW(window), 400, 300); + g_signal_connect(window, "destroy", G_CALLBACK(destroy), NULL); + gtk_container_set_border_width (GTK_CONTAINER (window), 0); + gtk_window_set_title(GTK_WINDOW(window), "GTK+ libVLC Demo"); + + //setup vbox + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(window), vbox); + + //setup menu + menubar = gtk_menu_bar_new(); + filemenu = gtk_menu_new(); + fileitem = gtk_menu_item_new_with_label ("File"); + filemenu_openitem = gtk_menu_item_new_with_label("Open"); + gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), filemenu_openitem); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileitem), filemenu); + gtk_menu_bar_append(GTK_MENU_BAR(menubar), fileitem); + gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0); + g_signal_connect(filemenu_openitem, "activate", G_CALLBACK(on_open), window); + + //setup player widget + player_widget = gtk_drawing_area_new(); + gtk_box_pack_start(GTK_BOX(vbox), player_widget, TRUE, TRUE, 0); + + //setup controls + //playpause_button = gtk_button_new_from_stock(GTK_STOCK_MEDIA_PLAY); + playpause_button = gtk_button_new_with_label("gtk-media-play"); + gtk_button_set_use_stock(GTK_BUTTON(playpause_button), TRUE); + stop_button = gtk_button_new_from_stock(GTK_STOCK_MEDIA_STOP); + g_signal_connect(playpause_button, "clicked", G_CALLBACK(on_playpause), NULL); + g_signal_connect(stop_button, "clicked", G_CALLBACK(on_stop), NULL); + hbuttonbox = gtk_hbutton_box_new(); + gtk_container_set_border_width(GTK_CONTAINER(hbuttonbox), BORDER_WIDTH); + gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_START); + gtk_box_pack_start(GTK_BOX(hbuttonbox), playpause_button, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbuttonbox), stop_button, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbuttonbox, FALSE, FALSE, 0); + + //setup vlc + vlc_inst = libvlc_new(0, NULL); + media_player = libvlc_media_player_new(vlc_inst); + g_signal_connect(G_OBJECT(player_widget), "realize", G_CALLBACK(player_widget_on_realize), NULL); + + gtk_widget_show_all(window); + gtk_main (); + + libvlc_media_player_release(media_player); + libvlc_release(vlc_inst); + return 0; +} diff --git a/doc/libvlc/libvlc_DVD_ripper.c b/doc/libvlc/libvlc_DVD_ripper.c new file mode 100644 index 0000000000..57fc896d72 --- /dev/null +++ b/doc/libvlc/libvlc_DVD_ripper.c @@ -0,0 +1,306 @@ +// gcc -o main main.c `pkg-config --cflags --libs gtk+-2.0 libvlc` + +/* Written by Vincent Schüßler */ +/* License WTFPL http://sam.zoy.org/wtfpl/ */ + +#include +#include +#include +#include +#include + +#define PRESET_H264_AAC_MP4_HIGH "MP4 high (h.264 + AAC)" +#define PRESET_H264_AAC_MP4_LOW "MP4 low (h.264 + AAC)" +#define PRESET_THEORA_VORBIS_OGG_HIGH "OGG high (Theora + Vorbis)" +#define PRESET_THEORA_VORBIS_OGG_LOW "OGG low (Theora + Vorbis)" +#define PRESET_VP8_VORBIS_WEBM_HIGH "WebM high (VP8 + Vorbis)" +#define PRESET_VP8_VORBIS_WEBM_LOW "WebM low (VP8 + Vorbis)" +#define BORDER_WIDTH 6 + +GtkWidget *window; +GtkWidget *source_entry, *dest_entry; +GtkWidget *progressbar; +libvlc_instance_t *vlcinst; +libvlc_media_list_t *medialist; +GtkWidget *run_button, *format_chooser, *spinner; +char stopped; + +gchar* get_filepath(GtkWidget* widget, GtkFileChooserAction action) { + GtkWidget *dialog; + gchar *path; + dialog = gtk_file_chooser_dialog_new("Choose location", GTK_WINDOW(gtk_widget_get_toplevel(widget)), action, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { + path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + } + else { + path = NULL; + } + gtk_widget_destroy(dialog); + return path; +} + +void on_select_source_path(GtkWidget *widget, gpointer data) { + char *path; + char scheme[] = "file://"; + char *uri; + + if(data==NULL) { + path = (char*) get_filepath(widget, GTK_FILE_CHOOSER_ACTION_OPEN); + } + else { + path = (char*) get_filepath(widget, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); + } + if(path != NULL) { + uri = malloc((strlen(scheme)+strlen(path)+1) * sizeof(char)); + if(uri == NULL) return; + uri[0] = '\0'; + strncat(uri, scheme, strlen(scheme)); + strncat(uri, path, strlen(path)); + g_free(path); + + gtk_entry_set_text(GTK_ENTRY(source_entry), uri); + free(uri); + } +} + +void on_select_dest_path(GtkWidget *widget, gpointer data) { + gchar *path; + path = get_filepath(widget, GTK_FILE_CHOOSER_ACTION_SAVE); + if(path != NULL) { + gtk_entry_set_text(GTK_ENTRY(dest_entry), path); + g_free(path); + } +} + +char* get_pos_string(float pos) { + int len; + const char format[] = "%.3f %%"; + char *pos_string; + pos *= 100; + len = snprintf(NULL, 0, format, pos); + pos_string = malloc(len); + if(pos_string==NULL) return NULL; + sprintf(pos_string, format, pos); + return pos_string; +} + +gboolean update_progressbar(char *handle) { + float pos = libvlc_vlm_get_media_instance_position(vlcinst, handle, 0); + char *pos_string; + if(pos < 1.0 && 0.0 <= pos) { + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar), pos); + pos_string = get_pos_string(pos); + if(pos_string != NULL) { + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progressbar), pos_string); + free(pos_string); + } + return TRUE; + } + if(stopped = 1) { + free(handle); + return FALSE; + } +} + +const char* get_transcode_string(char *preset) { + static const char mp4_high[] = "#transcode{vcodec=h264,venc=x264{cfr=16},scale=1,acodec=mp4a,ab=160,channels=2,samplerate=44100}"; + static const char mp4_low[] = "#transcode{vcodec=h264,venc=x264{cfr=40},scale=1,acodec=mp4a,ab=96,channels=2,samplerate=44100}"; + static const char ogg_high[] = "#transcode{vcodec=theo,venc=theora{quality=9},scale=1,acodec=vorb,ab=160,channels=2,samplerate=44100}"; + static const char ogg_low[] = "#transcode{vcodec=theo,venc=theora{quality=4},scale=1,acodec=vorb,ab=96,channels=2,samplerate=44100}"; + static const char webm_high[] = "#transcode{vcodec=VP80,vb=2000,scale=1,acodec=vorb,ab=160,channels=2,samplerate=44100}"; + static const char webm_low[] = "#transcode{vcodec=VP80,vb=1000,scale=1,acodec=vorb,ab=96,channels=2,samplerate=44100}"; + static const char nothing[] = ""; + if(0 == strcmp(preset, PRESET_H264_AAC_MP4_HIGH)) { + return mp4_high; + } + else if(0 == strcmp(preset, PRESET_H264_AAC_MP4_LOW)) { + return mp4_low; + } + else if(0 == strcmp(preset, PRESET_THEORA_VORBIS_OGG_HIGH)) { + return ogg_high; + } + else if(0 == strcmp(preset, PRESET_THEORA_VORBIS_OGG_LOW)) { + return ogg_low; + } + else if(0 == strcmp(preset, PRESET_VP8_VORBIS_WEBM_HIGH)) { + return webm_high; + } + else if(0 == strcmp(preset, PRESET_VP8_VORBIS_WEBM_LOW)) { + return webm_low; + } + else { + return nothing; + } +} + +void on_run(GtkWidget *widget, gpointer data) { + char *handle; + const char *transcode; + char *source = (char*) gtk_entry_get_text(GTK_ENTRY(source_entry)); + char *dest = (char*) gtk_entry_get_text(GTK_ENTRY(dest_entry)); + char *preset= (char*) gtk_combo_box_get_active_text(GTK_COMBO_BOX(format_chooser)); + int i; + char file_begin[] = ":file{dst="; + char file_end[] = "}"; + char *sout; + if(preset == NULL) return; + gtk_widget_set_sensitive(widget, FALSE); + handle = malloc((strlen(source)+4+1) * sizeof(char)); + if(handle == NULL) return; + strncpy(handle, source, strlen(source)); + for(i=0;i<=3;++i) { + handle[strlen(source)+i] = (char) (((unsigned int) rand()) & 63) + '0'; + } + handle[strlen(source)+4] = '\0'; + transcode = get_transcode_string(preset); + free(preset); + sout = malloc((strlen(transcode)+strlen(file_begin)+strlen(dest)+strlen(file_end)+1) * sizeof(char)); + if(sout == NULL) return; + strncpy(sout, transcode, strlen(transcode)+1); + strncat(sout, file_begin, strlen(file_begin)); + strncat(sout, dest, strlen(dest)); + strncat(sout, file_end, strlen(file_end)); + libvlc_vlm_add_broadcast(vlcinst, handle, source, sout, 0, NULL, 1, 0); + free(sout); + libvlc_vlm_play_media(vlcinst, handle); + gtk_widget_show(spinner); + gtk_spinner_start(GTK_SPINNER(spinner)); + stopped = 0; + g_timeout_add(50, (GSourceFunc) update_progressbar, handle); +} + +void stop(void) { + stopped = 1; + gtk_spinner_stop(GTK_SPINNER(spinner)); + gtk_widget_hide(spinner); + gtk_widget_set_sensitive(run_button, TRUE); + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar), 0.0); + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progressbar), ""); +} + +gboolean on_end(void) { + GtkWidget *dialog; + stop(); + dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Rip done"); + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + return FALSE; +} + +void on_end_vlc(const libvlc_event_t *event, void *data) { + g_idle_add((GSourceFunc) on_end, NULL); +} + +gboolean on_error(void) { + GtkWidget *dialog; + stop(); + dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error");gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + return FALSE; +} + +void on_error_vlc(const libvlc_event_t *event, void *data) { + g_idle_add((GSourceFunc) on_error, NULL); +} + +int main (int argc, char *argv[]) { + GtkWidget *media_list, *scrolled; + GtkWidget *choose_frame, *output_frame, *run_frame; + GtkWidget *vbox, *choose_table, *output_table, *run_table; + GtkWidget *source_label, *source_button, *source_folder_button; + GtkWidget *dest_label, *dest_button; + + libvlc_event_manager_t *evtman; + + gtk_init(&argc, &argv); + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_container_set_border_width(GTK_CONTAINER(window), BORDER_WIDTH); + gtk_window_set_title(GTK_WINDOW(window), "libVLC DVD ripper"); + + //setup vbox + vbox = gtk_vbox_new(FALSE, BORDER_WIDTH); + gtk_container_add(GTK_CONTAINER(window), vbox); + + // setup media list with scrolled window + media_list = gtk_tree_view_new(); + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(media_list), FALSE); + scrolled = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_container_add(GTK_CONTAINER(scrolled), media_list); + + // setup "choose"-frame + choose_frame = gtk_frame_new("Choose DVD"); + gtk_box_pack_start(GTK_BOX(vbox), choose_frame, TRUE, TRUE, 0); + choose_table = gtk_table_new(1, 4, FALSE); + gtk_table_set_row_spacings(GTK_TABLE(choose_table), BORDER_WIDTH/2); + gtk_table_set_col_spacings(GTK_TABLE(choose_table), BORDER_WIDTH/2); + gtk_container_set_border_width(GTK_CONTAINER(choose_table), BORDER_WIDTH); + source_label = gtk_label_new("Input file or folder:"); + source_entry = gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(source_entry), "dvd://"); + source_button = gtk_button_new_with_label("Open file"); + source_folder_button = gtk_button_new_with_label("Open folder"); + g_signal_connect(G_OBJECT(source_button), "clicked", G_CALLBACK(on_select_source_path), NULL); + g_signal_connect(G_OBJECT(source_folder_button), "clicked", G_CALLBACK(on_select_source_path), (gpointer) 1); + gtk_table_attach(GTK_TABLE(choose_table), source_label, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0); + gtk_table_attach(GTK_TABLE(choose_table), source_entry, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0); + gtk_table_attach(GTK_TABLE(choose_table), source_button, 2, 3, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0); + gtk_table_attach(GTK_TABLE(choose_table), source_folder_button, 3, 4, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0); + gtk_container_add(GTK_CONTAINER(choose_frame), choose_table); + + // setup "output"-frame + output_frame = gtk_frame_new("Output settings"); + gtk_box_pack_start(GTK_BOX(vbox), output_frame, TRUE, TRUE, 0); + output_table = gtk_table_new(2, 3, FALSE); + gtk_table_set_row_spacings(GTK_TABLE(output_table), BORDER_WIDTH/2); + gtk_table_set_col_spacings(GTK_TABLE(output_table), BORDER_WIDTH/2); + gtk_container_set_border_width(GTK_CONTAINER(output_table), BORDER_WIDTH); + gtk_container_add(GTK_CONTAINER(output_frame), output_table); + dest_label = gtk_label_new("Output file:"); + dest_entry = gtk_entry_new(); + format_chooser = gtk_combo_box_new_text(); + gtk_combo_box_append_text(GTK_COMBO_BOX(format_chooser), PRESET_H264_AAC_MP4_HIGH); + gtk_combo_box_append_text(GTK_COMBO_BOX(format_chooser), PRESET_H264_AAC_MP4_LOW); + gtk_combo_box_append_text(GTK_COMBO_BOX(format_chooser), PRESET_THEORA_VORBIS_OGG_HIGH); + gtk_combo_box_append_text(GTK_COMBO_BOX(format_chooser), PRESET_THEORA_VORBIS_OGG_LOW); + gtk_combo_box_append_text(GTK_COMBO_BOX(format_chooser), PRESET_VP8_VORBIS_WEBM_HIGH); + gtk_combo_box_append_text(GTK_COMBO_BOX(format_chooser), PRESET_VP8_VORBIS_WEBM_LOW); + gtk_combo_box_set_active(GTK_COMBO_BOX(format_chooser), 0); + dest_button = gtk_button_new_from_stock(GTK_STOCK_OPEN); + g_signal_connect(G_OBJECT(dest_button), "clicked", G_CALLBACK(on_select_dest_path), NULL); + gtk_table_attach(GTK_TABLE(output_table), dest_label, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0); + gtk_table_attach(GTK_TABLE(output_table), dest_entry, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0); + gtk_table_attach(GTK_TABLE(output_table), dest_button, 2, 3, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0); + gtk_table_attach(GTK_TABLE(output_table), format_chooser, 0, 4, 1, 2, GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0); + + // setup "run"-frame + run_frame = gtk_frame_new("Run"); + gtk_box_pack_start(GTK_BOX(vbox), run_frame, TRUE, TRUE, 0); + run_table = gtk_table_new(3, 2, FALSE); + gtk_table_set_row_spacings(GTK_TABLE(run_table), BORDER_WIDTH/2); + gtk_table_set_col_spacings(GTK_TABLE(run_table), BORDER_WIDTH/2); + gtk_container_set_border_width(GTK_CONTAINER(run_table), BORDER_WIDTH); + gtk_container_add(GTK_CONTAINER(run_frame), run_table); + progressbar = gtk_progress_bar_new(); + spinner = gtk_spinner_new(); + run_button = gtk_button_new_from_stock(GTK_STOCK_OK); + g_signal_connect(G_OBJECT(run_button), "clicked", G_CALLBACK(on_run), NULL); + gtk_table_attach(GTK_TABLE(run_table), progressbar, 0, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0); + gtk_table_attach(GTK_TABLE(run_table), gtk_label_new(""), 0, 1, 1, 2, GTK_EXPAND, GTK_SHRINK, 0, 0); + gtk_table_attach(GTK_TABLE(run_table), spinner, 1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0); + gtk_table_attach(GTK_TABLE(run_table), run_button, 2, 3, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0); + + // setup vlc + vlcinst = libvlc_new(0, NULL); + evtman = libvlc_vlm_get_event_manager(vlcinst); + libvlc_event_attach(evtman, libvlc_VlmMediaInstanceStatusEnd, on_end_vlc, NULL); + libvlc_event_attach(evtman, libvlc_VlmMediaInstanceStatusError, on_error_vlc, NULL); + + g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); + gtk_widget_show_all(window); + gtk_widget_hide(spinner); + gtk_main (); + libvlc_release(vlcinst); + return 0; +} diff --git a/doc/libvlc/wx_player.cpp b/doc/libvlc/wx_player.cpp new file mode 100644 index 0000000000..fbd4a0fc7a --- /dev/null +++ b/doc/libvlc/wx_player.cpp @@ -0,0 +1,263 @@ +// 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 +#include +#include +#include + +#ifdef __WXGTK__ + #include + #include + #include + #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: + 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; + libvlc_instance_t *vlc_inst; + libvlc_event_manager_t *vlc_evt_man; +}; + +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_inst = libvlc_new(0, NULL); + media_player = libvlc_media_player_new(vlc_inst); + vlc_evt_man = libvlc_media_player_event_manager(media_player); + libvlc_event_attach(vlc_evt_man, libvlc_MediaPlayerEndReached, ::OnEndReached_VLC, NULL); + libvlc_event_attach(vlc_evt_man, libvlc_MediaPlayerPositionChanged, ::OnPositionChanged_VLC, NULL); + Connect(wxID_ANY, vlcEVT_END, wxCommandEventHandler(MainWindow::OnEndReached_VLC)); + 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 + 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(); + 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) { + 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) { + wxCommandEvent evt(vlcEVT_POS, wxID_ANY); + mainWindow->AddPendingEvent(evt); +} + +void OnEndReached_VLC(const libvlc_event_t *event, void *data) { + wxCommandEvent evt(vlcEVT_END, wxID_ANY); + mainWindow->AddPendingEvent(evt); +} + +bool MyApp::OnInit() { + mainWindow = new MainWindow(wxT("wxWidgets libVLC demo")); + return true; +} + +IMPLEMENT_APP(MyApp) -- 2.39.2