Search code examples
pythoncgstreamercode-translationpython-gstreamer

Gstreamer Editing Services. Playing real video file. GESAsset element (translation from Python to C)


I'm trying to play video file using GES. I found python bindings example cut parts of a video using gstreamer/Python (gnonlin?) and I want to translate it to C language.

This is the excerpt of the python code which I want to translate to C:

asset = GES.UriClipAsset.request_sync(source_uri)
timeline = GES.Timeline.new_audio_video()
layer = timeline.append_layer()

start_on_timeline = 0
start_position_asset = 10 * 60 * Gst.SECOND
duration = 5 * Gst.SECOND
# GES.TrackType.UNKNOWN => add every kind of stream to the timeline
clip = layer.add_asset(asset, start_on_timeline, start_position_asset,
    duration, GES.TrackType.UNKNOWN)

What I have translated to the C code so far:

gint start_on_timeline = 0;
gint start_position_asset = 10 * 60 * GST_SECOND;
gint duration = 5 * GST_SECOND;
GESTimeline *timeline2;
GESLayer *layer2;
gchar *uri = gst_filename_to_uri (argv[1], NULL);
GError **error;
GESUriClipAsset *asset = ges_uri_clip_asset_request_sync(uri,error);
timeline2 = ges_timeline_new_audio_video();
if (!ges_timeline_add_layer (timeline2, layer2))
    return -1;
ges_layer_add_asset(layer2, asset, start_on_timeline, start_position_asset, duration, GES_TRACK_TYPE_UNKNOWN);

The problem is that function ges_layer_add_asset accepts type GESAsset asset , and I have type GESUriClipAsset asset.

In GES documentation page http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-editing-services/html/GESUriClipAsset.html#ges-uri-clip-asset-request-sync there doesn't seem to be any alternatives to the ges_uri_clip_asset_request_sync (const gchar *uri, GError **error) function. Is there any way how can I construct GESAsset from video file uri? Maybe there are other ways how can I play video file using GES?


Solution

  • I needed to cast GESUriClipAsset to GESAsset using GES_ASSET(asset).

    What is more here is the C example of playing file in GES, when the program argument is the address to video file (might leak memory) (most of the code is taken from test1.c):

    #include <ges/ges.h>
    
    int main (int argc, gchar ** argv)
    {
      GESAsset *src_asset;
      GESPipeline *pipeline;
      GESTimeline *timeline;
      GESClip *source;
      GESLayer *layer;
      GMainLoop *mainloop;
      GError **error;
      gchar *uri;
      GESUriClipAsset *asset;
      /* Initialize GStreamer (this will parse environment variables and commandline
       * arguments. */
      gst_init (&argc, &argv);
    
      /* Initialize the GStreamer Editing Services */
      ges_init ();
    
      /* Setup of a A/V timeline */
    
      /* This is our main GESTimeline */
      timeline = ges_timeline_new_audio_video ();
    
      /* We are only going to be doing one layer of clips */
      layer = ges_layer_new ();
    
      /* Add the tracks and the layer to the timeline */
      if (!ges_timeline_add_layer (timeline, layer))
        return -1;
    
      /* We create a simple asset able to extract GESTestClip */
      uri = gst_filename_to_uri (argv[1], NULL);
      asset = ges_uri_clip_asset_request_sync(uri,error);
      src_asset = GES_ASSET(asset);
    
      /* Add sources to our layer */
      ges_layer_add_asset (layer, src_asset, 0, 0, 4*GST_SECOND,
          GES_TRACK_TYPE_UNKNOWN);
    
      /* In order to view our timeline, let's grab a convenience pipeline to put
       * our timeline in. */
      pipeline = ges_pipeline_new ();
    
      /* Add the timeline to that pipeline */
      if (!ges_pipeline_set_timeline (pipeline, timeline))
        return -1;
    
      /* The following is standard usage of a GStreamer pipeline (note how you haven't
       * had to care about GStreamer so far ?).
       *
       * We set the pipeline to playing ... */
      gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
    
      /* .. and we start a GMainLoop. GES **REQUIRES** a GMainLoop to be running in
       * order to function properly ! */
      mainloop = g_main_loop_new (NULL, FALSE);
    
      /* Simple code to have the mainloop shutdown after 4s */
      g_timeout_add_seconds (4, (GSourceFunc) g_main_loop_quit, mainloop);
      g_main_loop_run (mainloop);
    
      return 0;
    }