簡體   English   中英

使用gstreamer暫停后如何恢復播放?

[英]How to resume playing after paused using gstreamer?

我已經為每種Gstreamer類型編寫了C ++包裝器。 它們簡單直觀,因此我認為它們的實現不需要在此處發布(盡管如有需要,我可以將它們發布(也許在github上))。

我面臨的問題是我開始播放視頻(並同時使用gst tee元素將其保存到文件中)....並且在播放時,我暫停了(從其他線程執行),效果很好。 但是,當我想恢復它時,它不起作用:

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

void resume()
{
    _pipeline.state(GST_STATE_PLAYING);
}

這是play()函數,在其中創建管道並將其狀態設置為GST_STATE_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視頻疊加層。

發球台上的每個分支上都有隊列元素嗎? 一個用於文件,另一個用於解碼? 您也可以嘗試在filesink上弄亂“ sync”屬性。 也許將其設置為true。


Nawaz編輯。

由於此答案首先給了我很少的指導,幾乎是解決問題的幾乎指導,因此,我應該為此問題設置賞金。 但是在此之前,這是解決方案(我的回答是解釋-Nawaz)。

gst::element filesink("filesink", "file-sink");
filesink.set("async", gboolean(FALSE));

希望對其他人也有幫助。

我自己找到了答案。 我試圖將所有元素的狀態打印為:

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));
         }
    }
}

然后,它幫助我弄清楚了所有元素的狀態都從PLAYING變為PAUSED以及PAUSED變為PLAYING,沒有任何掛起狀態, 除了 filesink元素的狀態仍為PLAYING和掛起的PAUSED狀態(這是因為它試圖改變它異步) -這最終導致我到async的財產GstBaseSink這是基類的filesink 我只是將其設置為FALSE為:

gst::element filesink("filesink", "file-sink");
filesink.set("async", gboolean(FALSE));

而已。 現在,暫停和恢復效果很好- 所有元素的狀態變為“正在播放”到“暫停”,而“暫停”到“播放”,沒有任何待處理狀態!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM