From e5c5f6163944797906413f9a556543f070fd1d5f Mon Sep 17 00:00:00 2001 From: Ben Shi <807629978@qq.com> Date: Sun, 23 Jun 2024 21:13:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81webrtc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 83 +++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 +-- README.md | 8 +++-- examples/server.rs | 24 +++++++++---- rszlm-sys/build.rs | 57 +++++++++++++++++++++++++++++++ src/webrtc.rs | 7 ++-- 6 files changed, 169 insertions(+), 14 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..281afd6 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,83 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in library 'rszlm-sys'", + "cargo": { + "args": [ + "test", + "--no-run", + "--lib", + "--package=rszlm-sys" + ], + "filter": { + "name": "rszlm-sys", + "kind": "lib" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in library 'rszlm'", + "cargo": { + "args": [ + "test", + "--no-run", + "--lib", + "--package=rszlm" + ], + "filter": { + "name": "rszlm", + "kind": "lib" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug example 'server'", + "cargo": { + "args": [ + "build", + "--example=server", + "--package=rszlm" + ], + "filter": { + "name": "server", + "kind": "example" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in example 'server'", + "cargo": { + "args": [ + "test", + "--no-run", + "--example=server", + "--package=rszlm" + ], + "filter": { + "name": "server", + "kind": "example" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 7053801..5497f34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,13 +12,13 @@ license = "MIT" readme = "README.md" [dependencies] -rszlm-sys = { path = "./rszlm-sys", version = "0.1.0" } +rszlm-sys = { path = "./rszlm-sys" } once_cell = "1.8" anyhow = "1" [dev-dependencies] -rszlm = { path = "./", features = ["static"] } +rszlm = { path = "./", features = ["static", "webrtc"] } tokio = { version = "1", features = ["full"] } tokio-util = { version = "0.7", features = ["full"] } video-rs = "0.8" diff --git a/README.md b/README.md index a52388d..2e7072e 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ cargo build ### features -- `dynamic`和`static`编译,目前只在 macos 下测试成功 +- `dynamic`和`static`编译 - `dynamic`(默认): @@ -36,7 +36,11 @@ cargo build rszlm = { version = "*", features = ["static"] } ``` -- `webrtc`, 暂未支持 +- `webrtc` + + ```toml + rszlm = { version = "*", features = ["webrtc"] } + ``` ### examples diff --git a/examples/server.rs b/examples/server.rs index 5d8d453..0cdcfcf 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, path::Path, thread}; +use std::{collections::HashMap, fmt::format, path::Path, thread}; use once_cell::sync::{Lazy, OnceCell}; use rszlm::{ @@ -8,6 +8,7 @@ use rszlm::{ obj::{CodecId, Track}, player::ProxyPlayerBuilder, server::{http_server_start, rtmp_server_start, rtsp_server_start, stop_all_server}, + webrtc::rtc_server_start, }; use tokio::sync::RwLock; use tokio_util::sync::CancellationToken; @@ -53,18 +54,22 @@ async fn start(cancel: CancellationToken) -> anyhow::Result<()> { match msg { ProxyMessageCmd::Start(m) => { let cancel = CancellationToken::new(); - let key = m.source.clone(); + let key = format!("{}/{}", m.app, m.stream); { let mut store = PULL_STORE.write().await; if store.contains_key(&key) { continue; } + + println!("start pull: {}", key); let _ = store.insert(key, ProxyState::new(m.source, m.app, m.stream, cancel)); } } ProxyMessageCmd::Stop(m) => { let mut store = PULL_STORE.write().await; - if let Some(state) = store.remove(&m.source) { + let key = format!("{}/{}", m.app, m.stream); + if let Some(state) = store.remove(&key) { + println!("stop pull: {}", key); state.cancel.cancel(); } } @@ -202,7 +207,8 @@ pub struct StartProxyMessage { } pub struct StopProxyMessage { - pub source: String, + pub app: String, + pub stream: String, } async fn zlm_start(cancel: CancellationToken) -> anyhow::Result<()> { @@ -239,6 +245,7 @@ fn start_zlm_background( http_server_start(8553, false); rtsp_server_start(8554, false); rtmp_server_start(8555, false); + rtc_server_start(8556); { let mut events = EVENTS.write().unwrap(); let tx_clone = tx.clone(); @@ -265,9 +272,14 @@ fn start_zlm_background( let tx_clone = tx.clone(); events.on_media_no_reader(move |msg| { - println!("MediaNoReader: {:?}", msg); + println!( + "MediaNoReader: app: {}, stream: {}", + msg.sender.app(), + msg.sender.stream() + ); let _ = tx_clone.blocking_send(ProxyMessageCmd::Stop(StopProxyMessage { - source: "ssss".to_string(), + app: msg.sender.app(), + stream: msg.sender.stream(), })); }); } diff --git a/rszlm-sys/build.rs b/rszlm-sys/build.rs index 4dc6a99..1cc0008 100644 --- a/rszlm-sys/build.rs +++ b/rszlm-sys/build.rs @@ -218,6 +218,8 @@ fn select_static_libs(zlm_link_path: &PathBuf) -> io::Result> { fn buildgen() { let is_static = is_static(); + find_libsrtp2(); + let (zlm_install_include, zlm_install_lib) = if env::var("ZLM_DIR").is_ok() { let zlm_install = PathBuf::from(env::var("ZLM_DIR").unwrap()); println!( @@ -260,3 +262,58 @@ fn buildgen() { .write_to_file(out_dir().join("bindings.rs")) .expect("Couldn't write bindings!"); } + +#[cfg(not(feature = "webrtc"))] +fn find_libsrtp2() { + // nothing +} + +#[cfg(feature = "webrtc")] +fn find_libsrtp2() { + if let Ok(_lib) = pkg_config::Config::new() + .atleast_version("2.3.0") + .statik(is_static()) + .probe("libsrtp2") + { + println!("find libsrtp2 from pkg_config"); + } else { + if build_srtp().is_err() { + panic!("can't find libsrtp2, please install libsrtp2 or disable feature `webrtc`"); + } + } +} + +fn build_srtp() -> io::Result<()> { + // download from github + if !&out_dir().join("libsrtp").exists() { + Command::new("git") + .arg("clone") + .arg("--depth") + .arg("1") + .arg("-b") + .arg("v2.3.0") + .arg("https://github.com/cisco/libsrtp.git") + .current_dir(&out_dir()) + .status()?; + } + + // build srtp + let mut configure = Command::new("./configure"); + configure.current_dir(&out_dir().join("libsrtp")); + configure.arg("--enable-openssl"); + configure.status()?; + + Command::new("make") + .arg("-j8") + .current_dir(&out_dir().join("libsrtp")) + .status()?; + + println!("cargo:rustc-link-search={}", &out_dir().to_string_lossy()); + + if is_static() { + println!("cargo:rustc-link-lib=static=srtp2"); + } else { + println!("cargo:rustc-link-lib=srtp2"); + } + Ok(()) +} diff --git a/src/webrtc.rs b/src/webrtc.rs index 6c0928e..3ae96f9 100644 --- a/src/webrtc.rs +++ b/src/webrtc.rs @@ -1,7 +1,6 @@ -use crate::{ - box_to_mut_void_ptr, const_ptr_to_string, const_str_to_ptr, mk_rtc_server_start, - mk_webrtc_get_answer_sdp2, obj::on_user_data_free, -}; +use rszlm_sys::*; + +use crate::{box_to_mut_void_ptr, const_ptr_to_string, const_str_to_ptr, obj::on_user_data_free}; pub fn rtc_server_start(port: u16) { unsafe {