我想用webrtcbin将一个摄像头(vp8和opus)从gstreamer传输到janus网关。有一个来自gstreamer的例子,它只播放视频,并且工作正常。
现在我也很难添加音频部分。
这就是我要准备的管道
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但是下面的失败是
Error: Pads have no common grandparentuse 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())
}发布于 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中
let webrtc_bin = gst::parse_bin_from_description_full("webrtcbin name=web", false, None, gst::ParseFlags::NO_SINGLE_ELEMENT_BINS)?;或者简单地使用
let webrtc_bin = gst::ElementFactory::make("webrtcbin", Some("web"))?;在这两种情况下,您都不必再调用pipeline.get_by_name("web"),因为您的webrtc_bin变量中已经有了它。
https://stackoverflow.com/questions/65422313
复制相似问题