我有一个使用GStreamer的小型C项目。我想加载视频并将其与字幕(textoverlay)和已用时间(时间延迟)一起显示。
我的想法是这样的:
- create a textoverlay and set a sample subtitle
- create a timeoverlay
- create a videosink
- put the three elements in a new bin and link them:
textoverlay -> timeoverlay -> videosink
- use playbin2 for playback and send the video from playbin2 to the new bin
这是我的测试独立应用程序:
// Save as "test.c". Compile with:
// gcc -o test `pkg-config --cflags --libs gtk+-2.0 gstreamer-0.10 gstreamer-interfaces-0.10` test.c
#include <gst/gst.h>
#include <gtk/gtk.h>
int main(int argc, char **argv) {
// Init - GTK is only used here as a GUI hook
gtk_init (&argc, &argv);
gst_init(0, NULL);
// Path to file - juts a simple demo file
char uri[2048];
sprintf(&uri[0], "file:///tmp/1.mpg");
// Playbin and URI
GstElement *playbin2 = gst_element_factory_make ("playbin2", "playbin2");
g_object_set (G_OBJECT (playbin2), "uri", &uri[0], NULL);
// Elements - videosink, textoverlay, timeoverlay
GstElement *videosink = gst_element_factory_make ("sdlvideosink", "videosink");
GstElement *textoverlay = gst_element_factory_make("textoverlay", "textoverlay");
GstElement *timeoverlay = gst_element_factory_make("timeoverlay", "timeoverlay");
// Set sample text in textoverlay
g_object_set(G_OBJECT(textoverlay), "text", "Test Subtitle", NULL);
// Create bin, add elements
GstElement *mybin = gst_bin_new("mybin");
gst_bin_add (GST_BIN (mybin), videosink);
gst_bin_add (GST_BIN (mybin), textoverlay);
gst_bin_add (GST_BIN (mybin), timeoverlay);
// Get sink pad for textoverlay and make it a ghostpad for bin
GstPad *pad_textoverlay_sink = gst_element_get_pad(textoverlay, "video_sink");
gst_element_add_pad(mybin, gst_ghost_pad_new("sink", pad_textoverlay_sink));
// Link elements: textoverlay -> timeoverlay -> videosink
gst_element_link_pads(textoverlay, "src", timeoverlay, "sink");
gst_element_link_pads(timeoverlay, "src", videosink, "sink");
// Conect the bin to the playbin
g_object_set (G_OBJECT (playbin2), "video-sink", mybin, NULL);
// Play video
gst_element_set_state (playbin2, GST_STATE_PLAYING);
// GTK Main loop
gtk_main ();
}
如果我将textoverlay的src pad链接到videosink的sink pad(从而跳过timeoverlay),我会得到一个视频和一个副标题 - 正如预期的那样。
如果我更改代码并使timeoverlay的接收器垫成为mybin的ghostpad,则将timeoverlay的src pad链接到videosink(从而跳过textoverlay) - 我得到了一段经过时间的视频,正如预期的那样。
然而,当我尝试级联textoverlay和timeoverlay时,没有视频。它不依赖于videosink - 与xvimagesink和ximagesink相同。没有显示错误。使用gstreamer-launch它工作正常,所以很明显我在C中做错了 - 我只是无法弄清楚是什么。
任何帮助将不胜感激。
答案 0 :(得分:0)
Textoverlay也希望在接收器上有一串文本。使用GST_DEBUG =“*:2”更好地运行您的应用程序,然后您将看到有关该警告的警告。
顺便说一下。 - char uri [2048]; - sprintf(&amp; uri [0],“file:///tmp/1.mpg”); + gchar * uri =“file:///tmp/1.mpg”; :)
答案 1 :(得分:0)
解决问题的方法是使用管道而不是bin。
GstElement *mybin = gst_pipeline_new ("my-pipeline");
然而,为什么它仍然不清楚。 GStreamer博士说,管道只是一个顶级垃圾箱;我发现文档中没有限制有多少元素可以驻留在bin中或者它们可以做什么。另一方面,playbin2在内部是一个管道,因此mybin可以是一个普通的bin(只要使用textoverlay或timeoverlay,它就可以作为常规bin使用)。
答案 2 :(得分:0)
更简单的解决方案是使用 gst_element_link_many :
gst_element_link_many(textoverlay, timeoverlay, videosink);