使用gstreamer暂停后如何恢复播放? 我为每个gStuple类型编写了C++包装器。它们简单直观,所以我不认为需要在这里发布它们的实现(尽管如果需要,我可以发布它们(可能在github上)

使用gstreamer暂停后如何恢复播放? 我为每个gStuple类型编写了C++包装器。它们简单直观,所以我不认为需要在这里发布它们的实现(尽管如果需要,我可以发布它们(可能在github上),c++,video,media-player,gstreamer,C++,Video,Media Player,Gstreamer,我面临的问题是,我开始播放视频(同时使用gst tee元素将其保存到文件中)…在播放时,我暂停(从不同的线程),这非常有效。但是,当我想恢复时,它不起作用: void pause() { _pipeline.state(GST_STATE_PAUSED) } void resume() { _pipeline.state(GST_STATE_PLAYING); } 这里是play()函数,我在其中创建管道并将其状态设置为GST\u state\u PLAYING int pl

我面临的问题是,我开始播放视频(同时使用gst tee元素将其保存到文件中)…在播放时,我暂停(从不同的线程),这非常有效。但是,当我想恢复时,它不起作用:

void pause()
{
    _pipeline.state(GST_STATE_PAUSED)
}

void resume()
{
    _pipeline.state(GST_STATE_PLAYING);
}
这里是
play()
函数,我在其中创建管道并将其状态设置为GST\u state\u PLAYING

int play(std::string const & source_path, std::string const & save_as_file)
{
    gst::element source(source_path.substr(0,4) == "http" ? "souphttpsrc" : "filesrc", "media-source");
    gst::element demuxer("decodebin", "decoder");
    gst::element vconv("videoconvert",  "vconverter");
    gst::element vsink("autovideosink", "video-output");
    gst::element aconv("audioconvert",  "aconverter");
    gst::element asink("autoaudiosink", "audio-output");
    gst::element filesink("filesink", "file-sink");
    gst::element fq("queue", "file-queqe");
    gst::element tee("tee", "media-tee");
    gst::element aq("queue", "audio-queue");
    gst::element vq("queue", "video-queue");

    source.set("location", source_path.c_str());

    gst::bus bus = _pipeline.bus();
    guint bus_watch_id = _session.add_watch(bus);


    _pipeline.add(source, demuxer, vconv, vsink, aconv, asink, filesink, tee,fq, aq, vq);

    gst::element::link(source, tee); 

    gst::element::link(vq, vconv, vsink);
    gst::element::link(aq, aconv, asink);

    gst::pad tee_src_pad = tee.request_pad("src_%u");
    gst::pad demuxer_sink_pad = demuxer.static_pad("sink");

    gst::pad::link(tee_src_pad, demuxer_sink_pad);

    filesink.set("location",  save_as_file.c_str());

    gst::element::link(fq, filesink);

    gst::pad tee_src_pad2 = tee.request_pad("src_%u");
    gst::pad fq_pad = fq.static_pad ("sink");
    gst::pad::link(tee_src_pad2, fq_pad);

    gst::element::dynamic_link(demuxer, aq);
    gst::element::dynamic_link(demuxer, vq);

    g_print ("Now playing: %s\n", source_path.c_str());
    _pipeline.state(GST_STATE_PLAYING);

    //code
    _session.run()

    //cleanup
}
如果有人能帮我找出这个问题的解决办法,我将不胜感激


我正在使用Qt小部件上的句柄播放视频,并将其传递给gstreamer video overlay。

在T形分叉的每个分支上都有队列元素吗?一个用于文件,一个用于解码?您还可以尝试在filesink上乱搞“sync”属性。也许把它设为真


编辑

因为这个答案首先给了我几个方向,而且几乎接近解决方案的方向,所以它值得我为这个问题设置的奖励。但在此之前,这里是解决方案(解释是在我的答案-纳瓦兹)


希望这对其他人也有帮助。

在T形三通的每个分支上都有队列元素吗?一个用于文件,一个用于解码?您还可以尝试在filesink上乱搞“sync”属性。也许把它设为真


编辑

因为这个答案首先给了我几个方向,而且几乎接近解决方案的方向,所以它值得我为这个问题设置的奖励。但在此之前,这里是解决方案(解释是在我的答案-纳瓦兹)


希望这对其他人也有帮助。

我自己找到了答案。我试图将所有元素的状态打印为:

void print_status_of_all()
{
    auto it  = gst_bin_iterate_elements(GST_BIN(_pipeline.raw()));
    GValue value = G_VALUE_INIT;
    for(GstIteratorResult r = gst_iterator_next(it, &value); r != GST_ITERATOR_DONE; r = gst_iterator_next(it, &value))
    {
         if ( r == GST_ITERATOR_OK )
         {
             GstElement *e = static_cast<GstElement*>(g_value_peek_pointer(&value));
             GstState  current, pending;
             auto ret = gst_element_get_state(e, &current, &pending, 100000);
             g_print("%s(%s), status = %s, pending = %s\n", G_VALUE_TYPE_NAME(&value), gst_element_get_name(e), gst_element_state_get_name(current), gst_element_state_get_name(pending));
         }
    }
}

就这样。现在暂停和恢复效果很好-所有元素的状态变为播放到暂停,暂停到播放,没有任何挂起状态

我自己找到了答案。我试图将所有元素的状态打印为:

void print_status_of_all()
{
    auto it  = gst_bin_iterate_elements(GST_BIN(_pipeline.raw()));
    GValue value = G_VALUE_INIT;
    for(GstIteratorResult r = gst_iterator_next(it, &value); r != GST_ITERATOR_DONE; r = gst_iterator_next(it, &value))
    {
         if ( r == GST_ITERATOR_OK )
         {
             GstElement *e = static_cast<GstElement*>(g_value_peek_pointer(&value));
             GstState  current, pending;
             auto ret = gst_element_get_state(e, &current, &pending, 100000);
             g_print("%s(%s), status = %s, pending = %s\n", G_VALUE_TYPE_NAME(&value), gst_element_get_name(e), gst_element_state_get_name(current), gst_element_state_get_name(pending));
         }
    }
}


就这样。现在暂停和恢复效果很好-所有元素的状态变为播放到暂停,暂停到播放,没有任何挂起状态

管道的实际状态是否会变回播放状态?如果是的话,你可能需要重新公开覆盖。你能在一个简单的管道上测试你的暂停/恢复代码吗,比如一个没有tee的简单的videotestsrc?我对GStreamer的经验是,管道越复杂,像这样的简单命令就越不可能起作用。有太多的方法来解释“暂停”在所有元素中应该做什么。e、 g.mp4 muxer应如何处理暂停流上的时间戳?创建一个长时间运行的冻结帧,还是从用户离开的地方开始?那么,如果mp4 muxer和matroska muxer实现了不同的行为呢?这类事情。@mpr:哇。。。如果我删除了tee元素(以及整个分支),那么pause/resume非常有效。我还注意到,当我使用发球台时,“暂停”确实会暂停比赛,但它不会改变状态(状态保持为*_PLAYING)@BenjaminTrent:不,它不会改变任何状态。即使我暂停,它也不会将状态更改为*\u暂停。州政府一直在打比赛。但是,如果我删除tee元素,暂停/恢复效果会很好(状态也会改变)。你真的认为这可能是一个Qt问题吗?如果没有,请删除Qt标签好吗?让我担心的是,我在你的代码片段中没有看到一个
Q
。管道的实际状态是否会变回播放状态?如果是的话,你可能需要重新公开覆盖。你能在一个简单的管道上测试你的暂停/恢复代码吗,比如一个没有tee的简单的videotestsrc?我对GStreamer的经验是,管道越复杂,像这样的简单命令就越不可能起作用。有太多的方法来解释“暂停”在所有元素中应该做什么。e、 g.mp4 muxer应如何处理暂停流上的时间戳?创建一个长时间运行的冻结帧,还是从用户离开的地方开始?那么,如果mp4 muxer和matroska muxer实现了不同的行为呢?这类事情。@mpr:哇。。。如果我删除了tee元素(以及整个分支),那么pause/resume非常有效。我还注意到,当我使用发球台时,“暂停”确实会暂停比赛,但它不会改变状态(状态保持为*_PLAYING)@BenjaminTrent:不,它不会改变任何状态。即使我暂停,它也不会将状态更改为*\u暂停。州政府一直在打比赛。但是,如果我删除tee元素,暂停/恢复效果会很好(状态也会改变)。你真的认为这可能是一个Qt问题吗?如果没有,请删除Qt标签好吗?让我担心的是,我在你的代码片段中没有看到一个
Q
。分支变成这样:
source->tee
(在tee变成两个分支)。然后
tee->demuxer->audio queue/video queue->audio sink/video sink
。还有另一个分支,
tee->file queue->file sink
。顺便说一句,我在filesink上没有看到
sync
属性:在tee和demuxer之间添加一个队列。好的。让我试试。顺便说一句,你能解释一下为什么你认为这是必要的吗?老实说,我不知道,但医生说要这样设计你的t恤。分支变成这样:
source->tee
(在tee处变成两个分支)。然后
tee->demuxer->audio queue/video queue->audio sink/video sink
。还有另一个分支,
tee->file queue->file sink
。顺便说一句,我在filesink上没有看到
sync
属性:在tee和demuxer之间添加一个队列。好的。让我试试。顺便说一句,你能解释一下为什么你认为这是必要的吗?老实说,我不知道,但医生说要这样设计你的t恤。
gst::element filesink("filesink", "file-sink");
filesink.set("async", gboolean(FALSE));