====== 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**
==== 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)