首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Rust中的Ghostpad连接Gstreamer Bin

使用Rust中的Ghostpad连接Gstreamer Bin
EN

Stack Overflow用户
提问于 2020-12-23 17:57:37
回答 1查看 232关注 0票数 3

我想用webrtcbin将一个摄像头(vp8和opus)从gstreamer传输到janus网关。有一个来自gstreamer的例子,它只播放视频,并且工作正常。

现在我也很难添加音频部分。

这就是我要准备的管道

代码语言:javascript
复制
gst-launch-1.0 webrtcbin name=web videotestsrc is-live=true ! videoconvert ! vp8enc ! rtpvp8pay ! web.sink_%u audiotestsrc is-live=true wave=8 ! audioconvert ! audioresample ! opusenc ! rtpopuspay ! web.sink_%u

但是下面的失败是

代码语言:javascript
复制
Error: Pads have no common grandparent
代码语言:javascript
复制
use gst::gst_element_error;
use gst::prelude::*;

async fn run() -> Result<(), anyhow::Error> {
    gst::init()?;

    let pipeline = gst::Pipeline::new(Some("test"));

    let webrtc_bin = gst::parse_bin_from_description("webrtcbin name=web", false)?;
    pipeline.add(&webrtc_bin)?;

    let video_bin = gst::parse_bin_from_description("autovideosrc ! videoconvert ! vp8enc ! rtpvp8pay", true)?;
    pipeline.add(&video_bin)?;

    let audio_bin = gst::parse_bin_from_description("autoaudiosrc ! audioconvert ! opusenc ! rtpopuspay", true)?;
    pipeline.add(&audio_bin)?;

    let webrtcbin = pipeline.get_by_name("web").expect("can't find webrtcbin");

    let video_src = video_bin.get_static_pad("src").expect("Unable to get video src pad");
    let video_sink = webrtcbin.get_request_pad("sink_%u").expect("Unable to request outgoing webrtcbin pad");

    if let Ok(webrtc_ghost_video_src) = gst::GhostPad::with_target(Some("webrtc_video_src"), &video_src) {
        video_bin.add_pad(&webrtc_ghost_video_src)?;
        webrtc_ghost_video_src.link(&video_sink)?;
    }

    let audio_src = audio_bin.get_static_pad("src").expect("Unable to get audio src pad");
    let audio_sink = webrtcbin.get_request_pad("sink_%u").expect("Unable to request outgoing webrtcbin pad");

    if let Ok(webrtc_ghost_audio_src) = gst::GhostPad::with_target(Some("webrtc_audio_src"), &audio_src) {
        audio_bin.add_pad(&webrtc_ghost_audio_src)?;
        webrtc_ghost_audio_src.link(&audio_sink)?;
    }

    let bus = pipeline.get_bus().unwrap();
    let _ = bus.add_watch_local(move |_bus, msg| {
        println!("{:#?}", msg);
        glib::Continue(true)
    });

    pipeline.call_async(|pipeline| {
        // If this fails, post an error on the bus so we exit
        if pipeline.set_state(gst::State::Playing).is_err() {
            gst_element_error!(
                pipeline,
                gst::LibraryError::Failed,
                ("Failed to set pipeline to Playing")
            );
        }
    });

    Ok(())
}

fn main() -> Result<(), anyhow::Error> {
    let main_context = glib::MainContext::default();
    main_context.block_on(run())
}
EN

回答 1

Stack Overflow用户

发布于 2021-04-15 15:31:30

你的问题是你在webrtcbin上也使用了gst::parse_bin_from_description()。如下所示,它将创建一个webrtcbin并将其放入一个新的bin中。因此,为了将webrtcbin与管道中的任何其他bin链接起来,您还必须在webrtc_bin上添加一个幻影垫,用于代理video_sink

或者,您也可以不将webrtcbin放入它自己的bin中,方法是执行以下操作告诉parse_bin_from_description() to ,而不是将单个元素放入新的bin中

代码语言:javascript
复制
let webrtc_bin = gst::parse_bin_from_description_full("webrtcbin name=web", false, None, gst::ParseFlags::NO_SINGLE_ELEMENT_BINS)?;

或者简单地使用

代码语言:javascript
复制
let webrtc_bin = gst::ElementFactory::make("webrtcbin", Some("web"))?;

在这两种情况下,您都不必再调用pipeline.get_by_name("web"),因为您的webrtc_bin变量中已经有了它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65422313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档