Closed LuoZijun closed 1 year ago
我理解你的这个场景需要把hls协议的数据转成rtmp协议的数据,然后推送到B站?现在还不支持hls到rtmp的转换。
Auth你指的是鉴权吗?正在开发中
把hls协议的数据转成rtmp协议的数据,然后推送到B站?现在还不支持hls到rtmp的转换。
是的,将 HLS 流的数据,推送到 B站 的 RTMP 服务器。但是这个 HLS 到 RTMP 的转换,我可以自己来做。我自己有一些音视频处理方面的经验。我想,把 视频流
和 音频流
的数据放进 RTMP 的 Message
里面,应该不是一件太困难的事情(对于常见的 Codec
而言 )。
Auth你指的是鉴权吗?
一些直播网站,会开放给你一个 RTMP 的地址(也可能还有其它的协议),同时有一些身份上面的数据。我想,推流到服务器时,该服务器会对这些身份信息做鉴定。比如 B站 的数据是这样的:
服务器地址: rtmp://live-push.bilivideo.com/live-bvc/
身份码:CCTTTT783****
串流密钥:?streamname=live_883*********&key=54********&schedule=rtmp&pflag=1
# `live-bvc` 就是 RTMP 里面的 `app_name`
但是如何把这个身份信息,通过 RTMP 库的 ClientSession
发送给 RTMP Server,我目前不太清楚。
如果有比较高层的 API
,我想应该容易很多,比如像这样:
const RTMP_DEFAULT_PORT: u16 = 1935u16;
struct RtmpClietConfig {
app_name: String,
stream_name: String,
identity: String,
secret: String,
}
impl Client {
pub fn connect<A: IntoScoketAddr>(addr: A, config: RtmpClietConfig) -> Result<Self, std::io::Error> {
let mut stream = std::net::TcpStream::connect(addr)?;
rtmp_handshake(&mut stream, &config)?;
Ok(Self { stream: stream, config: config })
}
pub fn publish(&mut self) -> Publisher;
pub fn playback(&mut self) -> Playback;
}
struct Playback { }
struct Publisher { }
impl Publisher {
// 写入 HLS 的 TS Packet,可能需要转换容器的格式。
pub fn write_video_segment(&mut self, segment: Segment) -> Result<(), std::io::Error>;
pub fn write_audio_segment(&mut self, segment: Segment) -> Result<(), std::io::Error>;
}
impl Playback {
pub fn read_video_segment(&mut self, buf: &mut Segment) -> Result<(), std::io::Error>;
pub fn read_audio_segment(&mut self, buf: &mut Segment) -> Result<(), std::io::Error>;
}
@LuoZijun
我在dev分支写了一个pullrtmppushrtmp的例子,你看下。
你如果实现了HLS2RTMP的逻辑,RTMP library是通过rust channel把音视频数据发送到Transmitter的,用下面的enum封起来:
pub enum ChannelData {
Video { timestamp: u32, data: BytesMut },
Audio { timestamp: u32, data: BytesMut },
MetaData { timestamp: u32, data: BytesMut },
}
我理解你的Auth的意思,就是使用本库的RTMP推流,需要推流地址携带鉴权信息发送到B站,才能推流成功,应该现在就支持,你用我给的demo试下吧
测试出来一个拉第三方流,转推RTMP,拉不下来流的问题,RTMP协议信令发送应该有问题。
bug修复了,完善了推拉流demo:
Usage: pprtmp --pull_rtmp_url <path> --push_rtmp_url <path>
Options:
-i, --pull_rtmp_url <path> Specify the pull rtmp url.
-o, --push_rtmp_url <path> Specify the push rtmp url.
-h, --help Print help
-V, --version Print version
把抽象出API来作为SDK使用的想法很好,但是现在还做不到,但是client_session里面的逻辑我感觉比较清楚,如果推流的话,会订阅channels里面的音视频数据,然后发送出去:
self.state = ClientSessionState::StartPublish;
//subscribe from local session and publish to remote rtmp server
if let (Some(app_name), Some(stream_name)) =
(&self.sub_app_name, &self.sub_stream_name)
{
self.common
.subscribe_from_channels(
app_name.clone(),
stream_name.clone(),
self.session_id,
)
.await?;
} else {
self.common
.subscribe_from_channels(
self.app_name.clone(),
self.stream_name.clone(),
self.session_id,
)
.await?;
}
我觉得有两种做法,一种是把hls提取出来的音视频数据/metadata pushlish到channel里面,然后订阅,另一种是绕过channel,直接抽象出来API来写音视频数据/metadata,我有时间可以弄下,或者你也可以尝试弄一下^_^
你好,我看到文档里面对于推流到RTMP服务器,建议采用通过 OBS 和 FFMPEG 这两种工具来做。但是我的推流过程当中可能有一些工作需要做,所以我是否可以直接通过本库的 RTMP 协议推流到一个远端的 RTMP 服务器呢?
我目前的使用场景是:对一个 HLS 流做一些处理后,然后推流给远端的 RTMP 服务器(B站),但是我对于 RTMP 协议不甚了解,不知作者能在代码 RTMP 推流这块能给一些 Example 吗?谢谢。
另外,我在 RTMP 协议代码里面的 ClientSession 里面,似乎也未曾看到 Auth 这块 -_-