Differenze tra le versioni di "Gestione dei file video con le funzioni esterne delle API di GStreamer"

Da Gambas-it.org - Wikipedia.
 
(2 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
Le funzioni esterne dell'[http://it.wikipedia.org/wiki/Application_programming_interface API] di ''GStreamer'' consentono due modalità per riprodurre un file video:
+
#REDIRECT [[La_gestione_del_video_e_dei_file_video_con_le_funzioni_esterne_del_API_di_GStreamer]]
* all'interno di una finestra ''distinta'' dal Form principale;
 
* all'interno di un oggetto capace di supportare il video e in generale le immagini, posto sul Form principale.
 
 
 
Facciamo riferimento, per i casi e gli esempi di codice che seguono, alla pagina della WIKI, nelle quali è stata descritta [http://www.gambas-it.org/wiki/index.php?title=La_gestione_mediante_le_funzioni_esterne_delle_API_di_GStreamer la gestione del sonoro in ''GStreamer'']. Lì si potrà avere contezza anche delle funzioni esterne necessarie di ''GStreamer'' dichiarate ed utilizzate.
 
 
 
 
 
==Riproduzione del video all'interno di una finestra distinta da ''Form'' principale==
 
Per ottenere la riproduzione di un file video all'interno di una finestra distinta da ''Form'' principale, e generata automaticamente da ''GStreamer'', sarà sufficiente utilizzare la funzione esterna:
 
''GstElement * gst_element_factory_make(const gchar *factoryname, const gchar *name)''
 
alla quale si passerà il nome dell'<I>Elemento</i>, denominato "''playbin''" ed una denominazione per l'<I>Elemento</i> appena creato. È possibile passare ''NULL'' come argomento ''name'' per ottenere un unico nome predefinito.
 
 
 
 
 
Mostriamo di seguito un semplice esempio per riprodurre un file video all'interno di una finestra generata da ''GStreamer'' distinta dal ''Form'' di Gambas:
 
Private video As Pointer
 
 
 
Library "libgstreamer-1.0"
 
 
Private Enum GST_STATE_VOID_PENDING = 0, GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING
 
Private Const GST_FORMAT_TIME As Integer = 3
 
 
<FONT Color=gray>' ''gst_init (int *argc, char **argv[])''
 
' ''Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.''</font>
 
Private Extern gst_init(argc As Pointer, argv As Pointer)
 
 
<FONT Color=gray>' ''GstElement * gst_element_factory_make(const gchar *factoryname, Const gchar * name)''
 
' ''Create a new element of the type defined by the given element factory.''</font>
 
Private Extern gst_element_factory_make(factoryname As String, name As String) As Pointer
 
 
<FONT Color=gray>' ''gchar * g_filename_to_uri (const gchar *filename, const gchar *hostname, GError **error)''
 
' ''Converts an absolute filename to an escaped ASCII-encoded URI.''</font>
 
Private Extern g_filename_to_uri(filename As String, hostname As String, GError As Pointer) As String
 
 
 
<FONT Color=gray>' ''void g_object_set(gpointer object, const gchar *first_property_name, ...)''
 
' ''Sets properties on an object.''</font>
 
Private Extern g_object_set(gobject As Pointer, key As String, value As String, tertium As String)
 
 
<FONT Color=gray>' ''GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)''
 
' ''Sets the state of the element.''</font>
 
Private Extern gst_element_set_state(gstelement As Pointer, state As Integer) As Integer
 
 
<FONT Color=gray>' ''GstStateChangeReturn gst_element_get_state (GstElement *element, GstState *state, GstState *pending, GstClockTime timeout)''
 
' ''Gets the state of the element.''</font>
 
Private Extern gst_element_get_state(e As Pointer, state As Pointer, pen As Pointer, timeout As Long)
 
 
<FONT Color=gray>' ''gboolean gst_element_query_duration (GstElement *element, GstFormat format, gint64 *duration)''
 
' ''Queries an element for the total stream duration in nanoseconds.''</font>
 
Private Extern gst_element_query_duration(gstelement As Pointer, gstformat As Pointer, duration As Pointer) As Boolean
 
 
<FONT Color=gray>' ''gboolean gst_element_query_position (GstElement *element, GstFormat format, gint64 *cur)''
 
' ''Queries an element for the stream position in nanoseconds.''</font>
 
Private Extern gst_element_query_position(gstelement As Pointer, gstformat As Pointer, cur As Pointer) As Boolean
 
 
 
 
'''Public''' Sub ToggleButton1_Click()
 
 
  Dim fileVideo As String
 
  Dim posizione, durata As Long
 
  Dim status As Integer
 
 
 
  If ToggleButton1.Value Then
 
    gst_element_get_state(video, VarPtr(status), 0, 0)
 
    If status < 2 Then
 
      gst_init(0, 0)
 
      <FONT color=#B22222>video = gst_element_factory_make("playbin", "video")</font>
 
      fileVideo = "<FONT Color=gray>''/percorso/del/file/video''</font>"
 
      g_object_set(video, "uri", g_filename_to_uri(fileVideo, Null, 0), Null)
 
    Endif
 
   
 
<FONT color=gray>' ''Avviamo la riproduzione video:''</font>
 
    gst_element_set_state(video, GST_STATE_PLAYING)
 
 
 
    While (posizione = 0) Or (durata > posizione)
 
      gst_element_query_duration(video, GST_FORMAT_TIME, VarPtr(durata))
 
      gst_element_query_position(video, GST_FORMAT_TIME, VarPtr(posizione))
 
      Write #File.Out, "\rDurata: " & Date(0, 0, 0, 0, 0, 0, durata / 1000000) & "      Pos. " & Date(0, 0, 0, 0, 0, 0, posizione / 1000000)
 
      Wait 0.01
 
    Wend
 
  Else
 
    gst_element_set_state(video, GST_STATE_PAUSED)
 
  Endif
 
     
 
'''End'''
 
 
 
'''Public''' Sub Button1_Click()
 
 
 
  ToggleButton1.Value = False
 
 
 
  gst_element_set_state(video, GST_STATE_NULL)
 
 
 
'''End'''
 
 
 
 
 
===Riproduzione di un file video all'interno di una finestra generata da ''GStreamer'' con applicazione ''a riga di comando''===
 
Di seguito mostriamo un esempio simile al precedente, ma con applicazione ''a riga di comando'':
 
Private video As Pointer
 
 
 
Library "libgstreamer-1.0"
 
 
Private Enum GST_STATE_VOID_PENDING = 0, GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING
 
Private Const GST_FORMAT_TIME As Integer = 3
 
 
<FONT Color=gray>' ''gst_init (int *argc, char **argv[])''
 
' ''Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.''</font>
 
Private Extern gst_init(argc As Pointer, argv As Pointer)
 
 
<FONT Color=gray>' ''GstElement * gst_element_factory_make(const gchar *factoryname, Const gchar * name)''
 
' ''Create a new element of the type defined by the given element factory.''</font>
 
Private Extern gst_element_factory_make(factoryname As String, name As String) As Pointer
 
 
<FONT Color=gray>' ''gchar * g_filename_to_uri (const gchar *filename, const gchar *hostname, GError **error)''
 
' ''Converts an absolute filename to an escaped ASCII-encoded URI.''</font>
 
Private Extern g_filename_to_uri(filename As String, hostname As String, GError As Pointer) As String
 
 
<FONT Color=gray>' ''void g_object_set(gpointer object, const gchar *first_property_name, ...)''
 
' ''Sets properties on an object.''</font>
 
Private Extern g_object_set(gobject As Pointer, key As String, value As String, tertium As String)
 
 
<FONT Color=gray>' ''GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)''
 
' ''Sets the state of the element.''</font>
 
Private Extern gst_element_set_state(gstelement As Pointer, state As Integer) As Integer
 
 
<FONT Color=gray>' ''gboolean gst_element_query_duration (GstElement *element, GstFormat format, gint64 *duration)''
 
' ''Queries an element for the total stream duration in nanoseconds.''</font>
 
Private Extern gst_element_query_duration(gstelement As Pointer, gstformat As Pointer, duration As Pointer) As Boolean
 
 
<FONT Color=gray>' ''gboolean gst_element_query_position (GstElement *element, GstFormat format, gint64 *cur)''
 
' ''Queries an element for the stream position in nanoseconds.''</font>
 
Private Extern gst_element_query_position(gstelement As Pointer, gstformat As Pointer, cur As Pointer) As Boolean
 
 
<FONT Color=gray>' ''void gst_object_unref(gpointer object)''
 
' ''Decrements the reference count on object.''</font>
 
Private Extern gst_object_unref(gobject As Pointer)
 
 
 
'''Public''' Sub Main()
 
 
  Dim fileVideo As String
 
  Dim posizione, durata As Long
 
     
 
  gst_init(0, 0)
 
 
 
  <FONT color=#B22222>video = gst_element_factory_make("playbin", "video")</font>
 
  fileVideo = "<FONT Color=gray>''/percorso/del/file/video''</font>"
 
  g_object_set(video, "uri", g_filename_to_uri(fileVideo, Null, 0), Null)
 
 
 
<FONT color=gray>' ''Avviamo la riproduzione video:''</font>
 
  gst_element_set_state(video, GST_STATE_PLAYING)
 
 
 
  While (posizione = 0) Or (durata > posizione)
 
    gst_element_query_duration(video, GST_FORMAT_TIME, VarPtr(durata))
 
    gst_element_query_position(video, GST_FORMAT_TIME, VarPtr(posizione))
 
    Write #File.Out, "\rDurata: " & Date(0, 0, 0, 0, 0, 0, durata / 1000000) & "      Pos. " & Date(0, 0, 0, 0, 0, 0, posizione / 1000000)
 
    Wait 0.01
 
  Wend
 
 
 
  gst_object_unref(video)
 
 
 
  Print "\nEsecuzione terminata."
 
 
 
  Quit
 
   
 
'''End'''
 
 
 
'''Public''' Sub Application_Read()
 
 
Dim s As String
 
 
  Input #File.In, s
 
 
 
  Select Case s
 
    Case "p"
 
<FONT Color=gray>' ''Pone in pausa la riproduzione del file mediale''</font>
 
      gst_element_set_state(video, GST_STATE_PAUSED)
 
    Case "r"
 
<FONT Color=gray>' ''Riprende la riproduzione del file mediale''</font>
 
      gst_element_set_state(video, GST_STATE_PLAYING)
 
    Case "s"
 
<FONT Color=gray>' ''Arresta la riproduzione del file mediale''</font>
 
      gst_element_set_state(video, GST_STATE_NULL)
 
      Quit
 
  End Select
 
 
'''End'''
 
 
 
 
 
 
 
==Mostrare il video sul Form==
 
Per mostrare il video sul ''Form'' dell'applicazione Gambas principale (e dunque non, come nel caso precedente, in una finestra distinta) si dovrà porre sul ''Form'' un oggetto capace di supportare il video (ad esempio in Gambas una ''DrawingArea'') e la seguente funzione esterna:
 
''void gst_video_overlay_set_window_handle(GstVideoOverlay *overlay, guintptr handle)''
 
la quale, però è attualmente contenuta nella libreria ''libgstvideo-1.0''.
 
Il parametro ''overlay'' è un pointer che rappresenta l'<I>Elemento</i> sonoro, mentre il parametro ''handle'' è in intero che rappresenta il numero identificativo (''Id'') dell'oggetto, posto sul ''Form'', nel quale si intende mostrare il video. In Gambas, come già accennato, l'oggetto potrà essere una ''DrawingArea''.
 
 
 
 
 
Mostriamo un semplice esempio:
 
Private video As Pointer
 
 
 
Library "libgstreamer-1.0"
 
 
Private Enum GST_STATE_VOID_PENDING = 0, GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING
 
Private Const GST_FORMAT_TIME As Integer = 3
 
 
<FONT Color=gray>' ''gst_init (int *argc, char **argv[])''
 
' ''Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.''</font>
 
Private Extern gst_init(argc As Pointer, argv As Pointer)
 
 
<FONT Color=gray>' ''GstElement * gst_element_factory_make(const gchar *factoryname, Const gchar * name)''
 
' ''Create a new element of the type defined by the given element factory.''</font>
 
Private Extern gst_element_factory_make(factoryname As String, name As String) As Pointer
 
 
<FONT Color=gray>' ''gchar * g_filename_to_uri (const gchar *filename, const gchar *hostname, GError **error)''
 
' ''Converts an absolute filename to an escaped ASCII-encoded URI.''</font>
 
Private Extern g_filename_to_uri(filename As String, hostname As String, GError As Pointer) As String
 
 
<FONT Color=gray>' ''void g_object_set(gpointer object, const gchar *first_property_name, ...)''
 
' ''Sets properties on an object.''</font>
 
Private Extern g_object_set(gobject As Pointer, key As String, value As String, tertium As String)
 
 
<FONT Color=gray>' ''GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)''
 
' ''Sets the state of the element.''</font>
 
Private Extern gst_element_set_state(gstelement As Pointer, state As Integer) As Integer
 
 
<FONT Color=gray>' ''GstStateChangeReturn gst_element_get_state (GstElement *element, GstState *state, GstState *pending, GstClockTime timeout)''
 
' ''Gets the state of the element.''</font>
 
Private Extern gst_element_get_state(e As Pointer, state As Pointer, pen As Pointer, timeout As Long)
 
 
<FONT Color=gray>' ''gboolean gst_element_query_duration (GstElement *element, GstFormat format, gint64 *duration)''
 
' ''Queries an element for the total stream duration in nanoseconds.''</font>
 
Private Extern gst_element_query_duration(gstelement As Pointer, gstformat As Pointer, duration As Pointer) As Boolean
 
 
<FONT Color=gray>' ''gboolean gst_element_query_position (GstElement *element, GstFormat format, gint64 *cur)''
 
' ''Queries an element for the stream position in nanoseconds.''</font>
 
Private Extern gst_element_query_position(gstelement As Pointer, gstformat As Pointer, cur As Pointer) As Boolean
 
 
 
Library "libgstvideo-1.0"
 
 
<FONT Color=gray>' ''void gst_video_overlay_set_window_handle (GstVideoOverlay *overlay, guintptr handle)''
 
' ''Calls the video overlay's set_window_handle method.''</font>
 
Private Extern gst_video_overlay_set_window_handle(overlay As Pointer, handle As Long)
 
 
 
 
'''Public''' Sub ToggleButton1_Click()
 
 
  Dim fileVideo As String
 
  Dim posizione, durata As Long
 
  Dim status As Integer
 
 
 
  If ToggleButton1.Value Then
 
    gst_element_get_state(video, VarPtr(status), 0, 0)
 
    If status < 2 Then
 
      gst_init(0, 0)
 
      video = gst_element_factory_make("playbin", "video")
 
      fileVideo = "<FONT Color=gray>''/percorso/del/file/video''</font>"
 
      g_object_set(video, "uri", g_filename_to_uri(fileVideo, Null, 0), Null)
 
    Endif
 
   
 
<FONT color=gray>' ''Impostiamo la "DrawingArea" come superficie per la riproduzione video:''</font>
 
    <FONT color=#B22222>gst_video_overlay_set_window_handle(video, CLong(DrawingArea1.Handle))</font>
 
   
 
<FONT color=gray>' ''Avviamo la riproduzione video:''</font>
 
    gst_element_set_state(video, GST_STATE_PLAYING)
 
 
 
    While (posizione = 0) Or (durata > posizione)
 
      gst_element_query_duration(video, GST_FORMAT_TIME, VarPtr(durata))
 
      gst_element_query_position(video, GST_FORMAT_TIME, VarPtr(posizione))
 
      Write #File.Out, "\rDurata: " & Date(0, 0, 0, 0, 0, 0, durata / 1000000) & "      Pos. " & Date(0, 0, 0, 0, 0, 0, posizione / 1000000)
 
      Wait 0.01
 
    Wend
 
  Else
 
    gst_element_set_state(video, GST_STATE_PAUSED)
 
  Endif
 
     
 
'''End'''
 
 
 
'''Public''' Sub Button1_Click()
 
 
 
  ToggleButton1.Value = False
 
 
 
  gst_element_set_state(video, GST_STATE_NULL)
 
 
 
'''End'''
 
 
 
 
 
 
 
==Eseguire un file video usando una linea di pipeline con la funzione ''gst_parse_launch()''==
 
La funzione esterna ''gst_parse_launch()'' della libreria ''GStreamer'' consente di costruire e gestire in modo semplice una pipeline ''GStreamer''. La riga della pipeline gestita dalla funzione esterna ''gst_parse_launch()'' è un insieme di elementi separati da punti esclamativi (!). Le proprietà possono essere aggiunte agli elementi, sotto forma di: ''proprietà = valore''.
 
 
 
Sarà necessario avere installata nel sistema e richiamare nell'applicazione Gambas la libreria dinamica condivisa: "''libgstreamer-1.0''"
 
 
 
 
 
Mostriamo un esempio pratico:
 
Private video As Pointer
 
 
 
Library "libgstreamer-1.0"
 
 
Private Enum GST_STATE_VOID_PENDING = 0, GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING
 
Private Const GST_FORMAT_TIME As Integer = 3
 
 
<FONT Color=gray>' ''gst_init (int *argc, char **argv[])''
 
' ''Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.''</font>
 
Private Extern gst_init(argc As Pointer, argv As Pointer)
 
 
<FONT Color=gray>' ''GstElement * gst_parse_launch (const gchar *pipeline_description, GError **error)''
 
' ''Create a new pipeline based on command line syntax.''</font>
 
Private Extern gst_parse_launch(description As String, GError As Pointer) As Pointer
 
 
<FONT Color=gray>' ''GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)''
 
' ''Sets the state of the element.''</font>
 
Private Extern gst_element_set_state(gstelement As Pointer, state As Integer) As Integer
 
 
 
<FONT Color=gray>' ''gboolean gst_element_query_position (GstElement *element, GstFormat format, gint64 *cur)''
 
' ''Queries an element for the stream position in nanoseconds.''</font>
 
Private Extern gst_element_query_position(gstelement As Pointer, gstformat As Pointer, cur As Pointer) As Boolean
 
 
<FONT Color=gray>' ''void gst_object_unref(gpointer object)''
 
' ''Decrements the reference count on object.''</font>
 
Private Extern gst_object_unref(gobject As Pointer)
 
 
 
'''Public''' Sub Main()
 
 
 
  Dim tempus As Long
 
     
 
  gst_init(0, 0)
 
 
 
  video = gst_parse_launch("filesrc location=\"<FONT Color=gray>''/percorso/del/file/video''</font>\" ! decodebin name=decoder decoder. ! queue ! audioconvert ! audioresample ! alsasink decoder. ! xvimagesink", 0)  <FONT Color=gray>' ''oppure "pulsesink"''</font>
 
         
 
<FONT Color=gray>' ''Avviamo la riproduzione video:''</font>
 
  gst_element_set_state(video, GST_STATE_PLAYING)
 
 
 
  While True
 
    gst_element_query_position(video, GST_FORMAT_TIME, VarPtr(tempus))
 
    Write #File.Out, "\rTempo: " & Date(0, 0, 0, 0, 0, 0, tempus / 1000000)
 
    Wait 0.01
 
  Wend
 
     
 
'''End'''
 
 
 
'''Public''' Sub Application_Read()
 
 
Dim s As String
 
 
  Input #File.In, s
 
 
 
  Select Case s
 
    Case "p"
 
<FONT Color=gray>' ''Pone in pausa la riproduzione del file mediale''</font>
 
      gst_element_set_state(video, GST_STATE_PAUSED)
 
    Case "r"
 
<FONT Color=gray>' ''Riprende la riproduzione del file mediale''</font>
 
      gst_element_set_state(video, GST_STATE_PLAYING)
 
    Case "s"
 
<FONT Color=gray>' ''Arresta la riproduzione del file mediale''</font>
 
      gst_element_set_state(video, GST_STATE_NULL)
 
      gst_object_unref(video)
 
      Print "\nEsecuzione terminata."
 
      Quit
 
  End Select
 
 
'''End'''
 
 
 
 
 
Va precisato che la riga di comando afferente alla funzione esterna ''gst parse launch()'' può essere impostata più brevemente anche così:
 
audio = gst_parse_launch("playbin uri=file://<FONT Color=gray>''/percorso/del/file/video''</font>", 0)
 
 
 
 
 
 
 
 
 
=Riferimenti=
 
* http://gstreamer.freedesktop.org/
 
* http://gstreamer.com/
 
* http://docs.gstreamer.com/display/GstSDK/gst-launch
 

Versione attuale delle 08:57, 17 giu 2021