How to add subtitles from a SRT file on a video and play it with Gstreamer in a c program

拈花ヽ惹草 提交于 2019-12-21 19:57:46

问题


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

I'm new to gstreamer and I somehow figured out who to make it work in 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 the video from a C program but I didn't understood how to add the 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;
} 

回答1:


In the pad-added callback (which you only need to connect to once!) you have to check the caps of the newly added pad.

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

Take a look at the code inside playbin / playsink for subtitle handling, and especially for handling these things dynamically. Also note that playbin has a sub-uri property which allows you to select an external subtitle file that should be overlayed over the video.




回答2:


Thank you very much Sebastian Drödge, I can finally play the video with the subtitles. Here is the code I've done.

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 thinking to use GTK to add features like pausing the video, it'll probably need to be cleaned a bit but that would do for now.



来源:https://stackoverflow.com/questions/26465983/how-to-add-subtitles-from-a-srt-file-on-a-video-and-play-it-with-gstreamer-in-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!