Gstreamer 同时使用textoverlay和timeoverlay

Gstreamer 同时使用textoverlay和timeoverlay,gstreamer,Gstreamer,我有一个使用GStreamer的小C项目。我想加载一个视频,并将其与字幕(textoverlay)和运行时间(timeoverlay)一起显示 我的想法是这样的: - 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 -> t

我有一个使用GStreamer的小C项目。我想加载一个视频,并将其与字幕(textoverlay)和运行时间(timeoverlay)一起显示

我的想法是这样的:

- 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 ();
}
//另存为“test.c”。编译时使用:
//gcc-o test`pkg config--cflags--libs gtk+-2.0 gstreamer-0.10 gstreamer-interfaces-0.10`test.c
#包括
#包括
int main(int argc,字符**argv){
//Init-GTK在这里仅用作GUI挂钩
gtk_init(&argc,&argv);
gst_init(0,空);
//文件路径-突出一个简单的演示文件
char-uri[2048];
sprintf(&uri[0],”file:///tmp/1.mpg");
//Playbin和URI
GstElement*playbin2=gst元素工厂制造(“playbin2”、“playbin2”);
g_对象集(g_对象(playbin2),“uri”,&uri[0],NULL);
//元素-视频接收器、文本覆盖、时间覆盖
GstElement*videosink=gst元素工厂制造(“sdlvideosink”、“videosink”);
GstElement*textoverlay=gst_元素_工厂_品牌(“textoverlay”,“textoverlay”);
GstElement*timeoverlay=gst_元素_工厂_品牌(“timeoverlay”,“timeoverlay”);
//在textoverlay中设置示例文本
g_对象集(g_对象(textoverlay),“文本”,“测试字幕”,空);
//创建垃圾箱,添加元素
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);
//获取textoverlay的水槽垫,并将其作为垃圾箱的重影垫
GstPad*pad_textoverlay_sink=gst_元素_get_pad(textoverlay,“视频_sink”);
gst_元素_添加_焊盘(mybin,gst_ghost_焊盘_new(“水槽”,焊盘文字叠加_水槽));
//链接元素:文本覆盖->时间覆盖->视频接收器
gst_元素_链接_焊盘(textoverlay,“src”,timeoverlay,“sink”);
gst_元素_链接_焊盘(时间叠加,“src”,视频接收器,“接收器”);
//将垃圾箱连接到游戏箱
g_对象集(g_对象(playbin2),“视频接收器”,mybin,NULL);
//播放视频
gst_元素_设置_状态(playbin2,gst_状态_播放);
//GTK主回路
gtk_main();
}
如果我将textoverlay的src pad链接到videosink的sink pad(从而跳过timeoverlay),我会得到一个视频和一个字幕——正如预期的那样

如果我更改代码并使timeoverlay的接收器板成为mybin的鬼影板,然后将timeoverlay的src板链接到videosink(从而跳过textoverlay)-我会得到一个经过时间的视频,正如预期的那样

然而,当我尝试级联textoverlay和timeoverlay时,却没有视频。它不依赖于videosink-与ximagesink和ximagesink相同。没有显示错误。随着gstreamer的发布,它运行良好,所以很明显我在C语言中做了一些错误的事情-我只是不知道是什么


任何帮助都将不胜感激

Textoverlay也希望在接收器上有一个文本流。最好使用GST_DEBUG=“*:2”运行您的应用程序,然后您将看到关于此的警告

顺便说一句。 -char-uri[2048]; -sprintf(&uri[0],”file:///tmp/1.mpg"); +gchar*uri=”file:///tmp/1.mpg";
:)

解决问题的方法是使用管道而不是容器

GstElement *mybin = gst_pipeline_new ("my-pipeline");

然而,我仍然不清楚为什么会这样。GStreamer文档称管道只是一个顶级垃圾桶;我在文档中没有发现关于一个箱子中可以存放多少元素或者它们可以做什么的限制。另一方面,playbin2在内部是一个管道,因此mybin可以是一个常规bin(只要只使用textoverlay或timeoverlay,它就可以作为常规bin正常工作)。

更简单的解决方案是使用gst\u元素\u链接\u多个

gst_element_link_many(textoverlay, timeoverlay, videosink);

更准确地说,textoverlay有一个文本接收器,但向其发送文本不是必需的。根据我的需要(字幕应用程序),设置“text”属性很好。第二个建议也不错,但不能解决问题。