Sto creando una piccola applicazione per un progetto, un player mp3 che preso in imput un file mp3 visualizzi l'id3 tag, lo riproduca e che renda possibile metterlo in pausa o riprenderne l'esecuzione e che una volta terminato il file esca dal programma... Pensavo fosse più facile purtroppo mi trovo invece di fronte a vari problemi che sembrano insormontabili, ma spero che con il vostro aiuto si riesca a risolverli e a migliorare dove possibile Grazie. Dopo questa sviolinata ecco il codice:
codice:
#include <gst/gst.h>

GstElement *player;			// bin
char carattere;				// variabile controllo riproduzione

static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
	GMainLoop *loop = (GMainLoop *) data;
	
	// esegue una diversa azione a seconda del messaggio su bus 
	switch (GST_MESSAGE_TYPE (msg))
	{
		// termina l'applicazione all'End Of Stream
		case GST_MESSAGE_EOS:
			g_print ("Fine del file\n");
			g_main_loop_quit (loop);
		break;
		
		// termina l'applicazione ad un qualsiasi errore
		case GST_MESSAGE_ERROR:
			g_print ("Errorore\n");
			g_main_loop_quit (loop);
		break;
		
		// controllo sulla riproduzione (CONTROLLARE [PUNTO 1])
		default:			
    			scanf(" %c", &carattere);
    			
    			// mette la bin in riproduzione se è inserito il carattere 
    			// corretto e la bin era in pausa
    			if(carattere == 'p'&& GST_STATE (player) == GST_STATE_PAUSED)
			{
				gst_element_set_state(player, GST_STATE_PLAYING);
				g_print ("Riprendo l'esecuzione\n");
			}	
			
			// mette la bin in pausa se è inserito il carattere
			// corretto e la bin era in riproduzione
			if(carattere == 'p' && GST_STATE (player) == GST_STATE_PLAYING)
			{
				gst_element_set_state(player, GST_STATE_PAUSED);
				g_print ("Esecuzione interrotta\n");
			}
			
			// esce dall'applicazione inserendo il carattere corretto
			if(carattere == 'q')
			{
				g_print ("Chiusura programma\n");
				g_main_loop_quit (loop);
			}
		break;
	}			
	return TRUE;
}
 
int main ()
{
	const gchar *nano_str;				// variabili per la versione di gstreamer utilizzata
	guint major, minor, micro, nano;		// variabili per la versione di gstreamer utilizzata
	GstElement *sorgente, *decoder, *sink;		// elementi
	GMainLoop *loop;                    		// loop
	GstBus *bus;					// bus
	
	// inizializzazione
	gst_init (NULL, NULL);
	loop = g_main_loop_new (NULL, FALSE);
       
	// visualizza versione delle librerie
	gst_version (&major, &minor, &micro, &nano);
	if (nano == 1)
		nano_str = "(CVS)";
	else if (nano == 2)
		nano_str = "(Prerelease)";
	else
		nano_str = "";
	g_print ("Questo programma utilizza le librerie gstreamer %d.%d.%d %s\n", major, minor, micro, nano_str);
 
	// messaggi vari
	g_print ("Comandi: \n p - PAUSA/RIPRENDI\n q - ESCI\n");
	
 
 	// creazione elementi
	player = gst_pipeline_new("mp3_player");			// creazione bin
	sorgente = gst_element_factory_make("filesrc", "sorgente");	// creazione sorgente
	decoder = gst_element_factory_make("mad", "filtro");		// creazione decoder
	sink = gst_element_factory_make("alsasink", "destinazione");	// creazione destinazione
  
	// controllo sulla corretta creazione degli elementi
	if (!player || !sorgente || !decoder || !sink) 
	{
		g_print ("Un elemento non può essere creato\n");
		return -1;
	}
	
 	// selezionare la locazione della sorgente
	g_object_set(G_OBJECT(sorgente), "location", "pinopino.mp3", NULL);
  	
  	// inserisci un message handler
        bus = gst_pipeline_get_bus (GST_PIPELINE (player));
        gst_bus_add_watch (bus, bus_call, loop);
        gst_object_unref (bus);
       
 	// incapsuliamo gli elementi nella bin
	gst_bin_add_many(GST_BIN(player), sorgente, decoder, sink, NULL);
	
 	// linkiamo gli elementi
	gst_element_link_many(sorgente, decoder, sink, NULL);
 	
 	// modifichiamo lo stato della bin in play
 	gst_element_set_state(player, GST_STATE_PLAYING);    
	g_main_loop_run (loop);
	
	// dealloca gli elementi
	gst_element_set_state (player, GST_STATE_NULL);
	gst_object_unref (GST_OBJECT(player));
	g_main_loop_unref (loop);
 
	return 0;
}
Cominciamo ad indicare i punti dove c'è errore:
[PUNTO 1] questo piccolo ciclo dovrebbe restare in attesa durante la riproduzione ed aspettare l'inserimento del carattere p per andare in pausa/riproduzione o uscire dal programma:
  • la riproduzione va in pausa, ma al rientro dalla pausa mi esegue di seguito gst_element_set_state(player, GST_STATE_PLAYING) e gst_element_set_state(player, GST_STATE_PAUSED), mantenendo di fatto la bin in pausa, consigli? Eventualmente (ancora meglio) sarebbe possibile associare i vari stati alla pressione di un tasto?

  • al termine del file mp3 ovviamente ho lo scanf che aspetta un input e quindi non mi chiude l'applicazione... c'è un modo per forzarne l'uscita?

  • (parecchio utopica come cosa) sarebbe possibile aggiungere a seguito dei comandi una barra di progressione che avanzi all'avanzare della riproduzione (come la barra del chdsk su linux)?

Ovviamente il file fisso in riproduzione è voluto ed è stato fatto per semplificare le operazioni durante le prove dell'app... Per ora non ho inserito la stampa del tag mp3, la metterò in seguito.