How to add subtitles from SRT file to video and play it using Gstreamer in c program

I want to play video with C program using Gstreamer and adding subtitles from SRT file.

I'm new to gstreamer and I somehow figured out who makes it work on the command line:

gst-launch filesrc location=video.srt ! subparse ! \
    overlay. filesrc location=video.ogv ! oggdemux name=demux \
    demux. ! queue ! vorbisdec ! audioconvert ! autoaudiosink \
    demux. ! queue ! theoradec ! ffmpegcolorspace ! subtitleoverlay name=overlay ! autovideosink;

      

The problem is that I can play videos from a C program, but I didn't figure out how to add subtitles.

int main (int argc, char *argv[]) {
    GMainLoop *loop;

    GstElement *pipeline, *source, *demuxer, *audioDecoder, *videoDecoder, *audioConv, *videoConv, *videosink, 
            *audiosink, *audioQueue, *videoQueue;
    GstBus *bus;

    gst_init (&argc, &argv);

    loop = g_main_loop_new (NULL, FALSE);

    if (argc < 2 && argc > 3) {
        g_printerr ("Usage: %s <Ogg/Vorbis filename> [Srt filename]\n", argv[0]);
        return -1;
    }

    pipeline     = gst_pipeline_new ("audiovideo-player");
    source       = gst_element_factory_make ("filesrc",          "file-source");
    demuxer      = gst_element_factory_make ("oggdemux",         "ogg-demuxer");
    audioQueue   = gst_element_factory_make ("queue",            "audio-queue");
    videoQueue   = gst_element_factory_make ("queue",            "video-queue");
    audioDecoder = gst_element_factory_make ("vorbisdec",        "vorbis-decoder");
    videoDecoder = gst_element_factory_make ("theoradec",        "theora-decoder");
    audioConv    = gst_element_factory_make ("audioconvert",     "audio-converter");
    videoConv    = gst_element_factory_make ("ffmpegcolorspace", "video-converter");
    videosink    = gst_element_factory_make ("autovideosink",    "video-output");
    audiosink    = gst_element_factory_make ("autoaudiosink",    "audio-output");


    if (!pipeline || !source || !demuxer || !audioDecoder || !audioConv || !videoDecoder || !videoConv || !audioQueue 
            || !videoQueue || !audiosink || !videosink) {
        g_printerr ("One element could not be created. Exiting.\n");
        exit(-1);
    }

    g_object_set (G_OBJECT (source), "location", argv[1], NULL);

    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    gst_bus_add_watch (bus, bus_call, loop);
    gst_object_unref (bus);

    gst_bin_add_many (GST_BIN (pipeline),
                        source, demuxer, 
                        audioQueue, videoQueue, audioDecoder, videoDecoder,
                        videoConv, audioConv, videosink, audiosink, NULL);

    gst_element_link (source, demuxer);

    gst_element_link_many (videoQueue, videoDecoder, videoConv, videosink, NULL);
    g_signal_connect (demuxer, "pad-added", G_CALLBACK (on_pad_added), videoQueue);

    gst_element_link_many (audioQueue, audioDecoder, audioConv, audiosink, NULL);
    g_signal_connect (demuxer, "pad-added", G_CALLBACK (on_pad_added), audioQueue);

    g_print ("Lecture de : %s\n", argv[1]);
    gst_element_set_state (pipeline, GST_STATE_PLAYING);

    g_print ("En cours...\n");
    g_main_loop_run (loop);

    g_print ("Arret de la lecture\n");
    gst_element_set_state (pipeline, GST_STATE_NULL);
    g_print ("Suppression du pipeline\n");
    gst_object_unref (GST_OBJECT (pipeline));
    return 0;
} 

      

+3


source to share


2 answers


In the pad adding callback (which you only need to connect to one!) You need to check the caps of the newly added pad.

Anyway, the video from the file would also need to be connected to the subtitleoverlay, and you would have to link the video stream after the subtitleoverlay. And you would also link an additional file for the subtitle subtitle file.



Take a look at the code inside playbin / playink for handling subtitles and especially for dynamically managing these things. Also note that playbin has a sub-uri property that allows you to select the external subtitle file to be superimposed over the video.

+2


source


Many thanks to Sebastian Drega, I can finally play the video with subtitles. Here is the code I made.

gst_element_link_many (videoQueue, videoDecoder, videoConv, subOverlay, videosink, NULL);
g_signal_connect (demuxer, "pad-added", G_CALLBACK (on_pad_added), videoQueue);

gst_element_link_many (audioQueue, audioDecoder, audioConv, audiosink, NULL);
g_signal_connect (demuxer, "pad-added", G_CALLBACK (on_pad_added), audioQueue);


g_object_set (G_OBJECT (subSource), "location", argv[2], NULL);

      



Now I'm going to use GTK to add features like pausing videos, it will probably need to be cleaned up a bit, but that will do now.

0


source







All Articles