Barra laterale

programmazione:libvlc:crosscompilare_progetto_gtk-vlc_per_windows

Crosscompilare progetto gtk - libvlc per windows su Linux

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) .

Preparare il nostro ambiente di lavoro

  1. Scarichiamo i binari di Vlc per windows con la cartella SDK (contenente i file di sviluppo di libvlc );
  2. Scarichiamo il pacchetto All-in-one bundles contenente il necessario per sviluppare con le GTK+ su windows;
  3. a questo punto dobbiamo individuare i file libvlc.dll e libvlcore.dll e la cartella plugins/ dello Sdk di Vlc e copiarli dentro la cartella bin/ del bundle gtk appena scaricato;
  4. copiamo include/vlc in include/ del nostro bundle Gtk;
  5. posizioniamo i nostri sorgenti in una cartella di nome src/ nella root del progetto;
  6. uniamom la cartella lib dell'sdk vlc con quella del bundle gtk.

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 .

Il sorgente

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

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

Problemi della versione windows

Attualmente ho riscontrato dei problemi nella versione windows. Ovvero quando viene eseguito un video , questo sostituisce per intero il contenuto della finestra oscurando tutti gli altri widget. Cosa che non accade nella versione nativa per Linux. Se qualcuno ha una soluzione a questo inconveniente puo' postarla nei commenti.

programmazione/libvlc/crosscompilare_progetto_gtk-vlc_per_windows.txt · Ultima modifica: 18/04/2018 - 15:48 (modifica esterna)