Autore: Fabio Di Matteo
Ultima revisione: 08/11/2011
Partendo dall'articolo “Creare un semplice lettore multimediale con libvlc” vedremo come realizzare un semplice lettore multimediale basato sulla libreria Libvlc anche per i sistemi windows. Facendo in modo tale, che una volta lanciato su windows il nostro eseguibile, non richieda l'installazione di altre dipendenze. Distribuiremo infatti le librerie assieme alla nostra applicazione, portandoci dietro tutto quello che serve (senza compilare staticamente) .
Avremo come risultato una cartella con una struttura simile alla seguente:
drwx------ 2 fabio fabio 4096 2011-10-21 12:22 bin (qui dentro ci sara' l'eseguibile della nostra applicazione) drwx------ 5 fabio fabio 4096 2011-10-21 11:23 etc drwx------ 13 fabio fabio 4096 2011-10-21 11:23 include drwx------ 6 fabio fabio 4096 2011-10-21 11:23 lib drwx------ 3 fabio fabio 4096 2011-10-21 11:23 man drwx------ 2 fabio fabio 4096 2011-10-21 11:23 manifest drwx------ 10 fabio fabio 4096 2011-10-21 11:23 share (qui dentro una cartella con dentro il file .glade della nostra interfaccia) drwx------ 3 fabio fabio 4096 2011-10-21 11:23 src (qui dentro i sorgenti della nostra applicazione e il makefile)
Non è strettamente necessario, ma io per realizzare lo scheletro dell'applicazione che fa uso di gtk e del suo nativo supporto alle interfacce realizzate con glade ho utilizzato il nostro script che automatizza il processo ( Creazione automatica dello scheletro per applicazioni gtkbuilder ) e ho unito le cartelle con quelle appena ottenute.
Per la compilazione nativa per Linux invece le dipendenze (debian/ubuntu) sono: libvlccore-dev, libvlc-dev, libgtk2.0-dev, gcc .
mytest.c
#include <gtk/gtk.h> // includo le librerie gtk e glade. #include <vlc/vlc.h> // includo le librerie vlc #ifdef _WIN32 #include <gdk/gdkwin32.h> #define WINOPT G_MODULE_EXPORT void // necessario per attivare la callbacks automatiche #endif // acnhe su win32. Ogni callback deve restituire il #ifdef __linux // tipo G_MODULE_EXPORT void su win32 . #include <gdk/gdkx.h> #define WINOPT void #endif GtkBuilder *xml; // questo è il puntatore al file xml che contiene l'interfaccia GtkWidget *widget; // questa variabile serve per recuperare di volta in volta il // widget (ovvero l'oggetto ) che vogliamo usare /*Instanza di libvlc (core)*/ libvlc_instance_t * inst; /*Instanza di libvlc media player*/ libvlc_media_player_t *mp; /*Media (file o url da leggere)*/ libvlc_media_t *m; WINOPT on_MainWindow_delete_event(GtkWidget *widget, gpointer user_data) //altra callback associata alla chiusura della { // finestra gtk_main_quit(); } WINOPT on_btStop_clicked(GtkWidget *widget, gpointer user_data) { /* Stop playing */ libvlc_media_player_stop(mp); } WINOPT on_btPause_clicked(GtkWidget *widget, gpointer user_data) { /*Se il lettore sta leggendo qualcosa lo mette in pausa, * altrimenti lo mette in play*/ if (libvlc_media_player_is_playing(mp)==1) { libvlc_media_player_set_pause(mp,1); }else{ libvlc_media_player_play (mp); } } WINOPT on_btLoad_clicked (GtkWidget *widget, gpointer user_data) { /*Dialog gtk per caricare il file*/ GtkWidget *dialog, *MainWindow; GtkFileFilter* filter; gchar *filename; MainWindow= GTK_WIDGET (gtk_builder_get_object(xml, "MainWindow")); dialog = gtk_file_chooser_dialog_new ("Seleziona un file", GTK_WINDOW(MainWindow), 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) { filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); /*Path for plugin (bin/plugins)*/ const char * const vlc_args[] = { "--plugin-path=.\\plugins" }; /* Load the VLC engine */ inst = libvlc_new (1, vlc_args); /* Create a new item */ m = libvlc_media_new_path (inst, (char* )filename); /* Create a media player playing environement */ mp = libvlc_media_player_new_from_media (m); /* No need to keep the media now */ libvlc_media_release (m); /*Include il mediaplayer dentro un widget gtk (drawing area) */ #ifdef __linux widget= GTK_WIDGET (gtk_builder_get_object(xml, "MediaPlayer")); uint32_t xwin = GDK_WINDOW_XWINDOW (GTK_WIDGET (widget)->window); libvlc_media_player_set_xwindow(mp,xwin); #endif #ifdef _WIN32 widget= GTK_WIDGET (gtk_builder_get_object(xml, "MediaPlayer")); HWND win = GDK_WINDOW_HWND(GTK_WIDGET (widget)->window); //buono ma copre tutta la finestra libvlc_media_player_set_hwnd(mp, (void*) win); #endif /* play the media_player */ libvlc_media_player_play (mp); } gtk_widget_destroy (dialog); g_free (filename); } int main (int argc, char *argv[]) { gtk_init (&argc, &argv); gchar* base; gchar* glade_file; if (g_find_program_in_path ("gtk-vlc")==NULL){ /*Ricava il percorso dell'eseguibile, senza il nome del file*/ base = g_path_get_dirname(argv[0]); /*Concatena il percorso base al nome file gui.glade */ glade_file = g_build_filename (base,"../share/gtk-vlc", "gui.glade", NULL); }else{ base = g_path_get_dirname(g_find_program_in_path ("gtk-vlc")); glade_file = g_build_filename (base,"../share/gtk-vlc", "gui.glade", NULL); } /*Infine carica come disolito il file dell'interfaccia */ GError* error = NULL; xml = gtk_builder_new (); if (!gtk_builder_add_from_file (xml, glade_file, &error)) { g_warning ("Couldn't load builder file: %s", error->message); g_error_free (error); } /* connette tutti gli eventi dei widget alle rispettive funzioni */ gtk_builder_connect_signals (xml, NULL); /* Avvia il ciclo principale delle Gtk */ gtk_main (); return 0; }
Il makefile generera' 2 eseguibili, mytest e mytest.exe rispettivamente per Linux e windows.
makefile
CPPWIN32 = i586-mingw32msvc-gcc OPTSWIN32 = -mwindows -I../include -L../lib -I../include/vlc -mms-bitfields -I../include/gtk-2.0/gdk -I../include/gtk-2.0 -I../lib/gtk-2.0/include -I../include/atk-1.0 -I../include/cairo -I../include/gdk-pixbuf-2.0 -I../include/pango-1.0 -I../include/glib-2.0 -I../lib/glib-2.0/include -I../include -I../include/freetype2 -I../include/libpng14 -L../lib -lgtk-win32-2.0 -lgdk-win32-2.0 -latk-1.0 -lgio-2.0 -lpangowin32-1.0 -lgdi32 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lintl -lvlc CPP= gcc OPTS= `pkg-config --cflags --libs gtk+-2.0 libvlc gdk-x11-2.0` -export-dynamic all: $(CPPWIN32) mytest.c -o ../bin/mytest.exe $(OPTSWIN32) $(CPP) mytest.c -o ../bin/mytest $(OPTS) clean: rm mytest.exe rm mytest
Il nostro wiki installa solamente cookie tecnici necessari al funzionamento della piattaforma "Dokuwiki". Niente analitics, statistiche, tracciamenti o altro.