====== Utilizzare mplayer come backend ====== Autore: **//Fabio Di Matteo//** \\ Ultima revisione: **//3/12/2010//** \\ \\ In questo articolo vedremo come integrare [[http://www.mplayerhq.hu/|Mplayer]] nei nostri programmi (dotati di gui e non). Prima di cominciare ad integrare mplayer nelle nostre interfaccie grafiche è bene parlare di come si possano inviare comandi ad mplayer da un programma esterno. \\ \\ {{programmazione:c:mplayer-gtk.png|}} [[http://www.mplayerhq.hu/|Mplayer]] , il famoso lettore multimediale da riga di comando puo' essere usato come backend nei nostri programmi attraverso l'utilizzo di pipe (in pratica proprio come avviene per il programma [[http://kdekorte.googlepages.com/gnomemplayer|Gnome-mplayer]]). Ovvero si puo' controllare tramite l'invio di comandi sul stdin. \\ E' sufficente,infatti, lanciare il lettore con l'opzione '' -slave '' per metterlo in "ascolto" sullo stdin per captare eventuali comandi. Per l'elenco dei comandi digitare da console ''mplayer -input cmdlist'' . \\ Di seguito un semplice sorgente C che mostra come controllare mplayer attraverso un nostro programma che fa uso di pipe. /* avviando mplayer con l'opzione -slave rimarra in "ascolto" sullo stdin * per captare eventuali comandi (per un elenco dei comandi e' sufficiente lanciare * 'mplayer -input cmdlist' )*/ #define MPLAYER "/usr/bin/mplayer -slave -quiet -idle prova.3gp" #include #include int main(int argc, char **argv) { FILE *mplayer; /*Apriamo una normale pipe in scrittura*/ if ( ( mplayer = popen ( MPLAYER , "w") ) ) { /*Stampo il codec video usato dal filmato*/ fputs("get_video_codec\n", mplayer); fflush(mplayer); /*Aspetto 3 secondi*/ sleep(3); /*Pausa del filmato*/ fputs("pause\n", mplayer); fflush(mplayer); /*Aspetto 3 secondi*/ sleep(3); /*Play del filmato*/ fputs("pause\n", mplayer); fflush(mplayer); sleep(3); /*Stop del filmato*/ fputs("stop\n", mplayer); fflush(mplayer); /*Chiudo la pipe*/ fputs("quit\n", mplayer); fflush(mplayer); pclose(mplayer); } exit( 0 ); } Compiliamo con: gcc mplayer-backend.c -o mplayer-backend La documentazione sull'uso dell' opzione slave e' consultabile qui: [[http://www.mplayerhq.hu/DOCS/tech/slave.txt|slave.txt]] ===== Integrare mplayer nelle nostre finestre gtk+2 ===== Andremo questa volta ad integrare il nostro lettore multimediale all'interno di un nostro widget (GtkDrawingArea) chiedendo ad mplayer di utilizzare il nostro widget tramite il parametro ''-wid'' . Ovvero quello che faremo è ricavare il window id della nostra GtkDrawingArea e fornirlo ad mplayer (il tutto nella funzione ''on_btCarica_clicked()'' ). Per quanto riguarda il controllo del lettore useremo la tecnica della pipe esposta all'inizio di questo articolo. ==== Il sorgente ==== **main.c ** \\ per la creazione dello scheletro dell'applicazione abbiamo usato il nostro script autogtkbuilder ([[programmazione:gtk:creazione_scheletro_per_applicazioni_gtkbuilder]]). #include //includo le librerie gtk e glade. #include 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 /*Pipe per comandare mplayer*/ FILE* mplayer; void on_brStop_clicked(GtkWidget *widget, gpointer user_data) { fputs("stop\n",mplayer); fflush(mplayer); } void on_btPlayPause_clicked(GtkWidget *widget, gpointer user_data) { fputs("pause\n",mplayer); fflush(mplayer); } void on_btCarica_clicked(GtkWidget *widget, gpointer user_data) { /*Apro un dialogo per la scelta del 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) { /*Prendo il path del file da aprire*/ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); /*Include il mediaplayer dentro un widget gtk (drawing area) */ widget= GTK_WIDGET (gtk_builder_get_object(xml, "drvMplayer")); int xwin = GDK_WINDOW_XWINDOW (GTK_WIDGET (widget)->window); /*Se mplayer e' gia' stato avviato lo stoppo*/ if (mplayer!=NULL) { fputs("stop\n",mplayer); fflush(mplayer); } /*Apro una pipe con mplayer e lancio il comando per caricare il file * per un elenco dei comandi accettabili via pipe da mplayer visitare: * http://www.mplayerhq.hu/DOCS/tech/slave.txt */ char cmdMplayer[50]; sprintf(cmdMplayer,"mplayer -wid %d -slave -quiet -idle",xwin); if ( ( mplayer = popen ( cmdMplayer , "w") ) ) { filename = g_strconcat("loadfile '", filename,"'\n",NULL); fputs(filename,mplayer); fflush(mplayer); } } /*Distruggo alcune variabili ormai inutili*/ gtk_widget_destroy (dialog); g_free (filename); } void on_MainWindow_delete_event(GtkWidget *widget, gpointer user_data) //altra callback associata alla chiusura della { // finestra fputs("quit\n",mplayer); fflush(mplayer); pclose(mplayer); gtk_main_quit(); } int main (int argc, char *argv[]) { gtk_init (&argc, &argv); gchar* base; gchar* glade_file; if (g_find_program_in_path ("mplayer-embedded")==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/mplayer-embedded", "gui.glade", NULL); }else{ base = g_path_get_dirname(g_find_program_in_path ("mplayer-embedded")); glade_file = g_build_filename (base,"../share/mplayer-embedded", "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 gtAvvia il ciclo principale delle gtk*/ gtk_main (); return 0; } ===== Il file della Gui creato con Glade ===== Questo è il file xml con la gui dello screenshot. \\ \\ **gui.glade** True True 9 True <b>Integrare mplayer dentro finestra gtk</b> True 0 640 480 True 1 True 23 Carica True True True 0 Play/Pause True True True 1 Stop True True True 2 2 ==== Il nostro CMakeLists.txt ==== ** CMakeLists.txt ** cmake_minimum_required(VERSION 2.6) PROJECT(mplayer-embedded) SET (AUTHOR "Fabio Di Matteo" INTERNAL "Author") SET (VERSION "0.1.0") INCLUDE (FindPkgConfig) IF (NOT PKG_CONFIG_FOUND) MESSAGE (FATAL_ERROR "pkg-config not found...") ENDIF (NOT PKG_CONFIG_FOUND) pkg_check_modules (GTK REQUIRED gtk+-2.0>=2.6) IF (NOT GTK_FOUND) MESSAGE(FATAL_ERROR "You don't seem to have gtk >= 2.6 development libraries installed...") ENDIF (NOT GTK_FOUND) ADD_DEFINITIONS() INCLUDE_DIRECTORIES (. ${GTK_INCLUDE_DIRS}) LINK_DIRECTORIES (${GTK_LIBRARY_DIRS} ) LINK_LIBRARIES (${GTK_LIBRARIES} ) #Indichiamo dove sara' messo l'eseguibile ADD_EXECUTABLE( bin/mplayer-embedded src/main.c) #Se se si ha bisogno di eventuali dipendenze fornite da noi stessi #ADD_DEPENDENCIES (mplayer-embedded src/main.c) #Variabili per le directory di installazione #ADD_DEFINITIONS (-DVERSION=\"${VERSION}\") #ADD_DEFINITIONS (-DDATADIR=\"${CMAKE_INSTALL_PREFIX}/share\") #Copia file per l'installazione #ADD_SUBDIRECTORY (src) INSTALL (TARGETS bin/mplayer-embedded DESTINATION bin) INSTALL (DIRECTORY share/mplayer-embedded DESTINATION share)