问题
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