如何使用librtmp库发布流?我阅读了librtmp手册页,对于发布,使用了RTMP_Write()。
我是这样做的。
//Code
//Init RTMP code
RTMP *r;
char uri[]="rtmp://localhost:1935/live/desktop";
r= RTMP_Alloc();
RTMP_Init(r);
RTMP_SetupURL(r, (char*)uri);
RTMP_EnableWrite(r);
RTMP_Connect(r, NULL);
RTMP_ConnectStream(r,0);
然后,为了响应来自服务器的ping/其他消息,我使用一个线程来响应,如下所示:
//Thread
While (ThreadIsRunning && RTMP_IsConnected(r) && RTMP_ReadPacket(r, &packet))
{
if (RTMPPacket_IsReady(&packet))
{
if (!packet.m_nBodySize)
continue;
RTMP_ClientPacket(r, &packet); //This takes care of handling ping/other messages
RTMPPacket_Free(&packet);
}
}
在此之后,我被困在如何使用RTMP_Write()将文件发布到Wowza媒体服务器?
发布于 2012-12-10 22:41:24
根据我自己的经验,将视频数据流式传输到RTMP服务器在librtmp端实际上非常简单。棘手的部分是正确地打包视频/音频数据,并以正确的速率读取它。
假设您使用的是FLV视频文件,只要您能够正确地隔离文件中的每个标签,并使用一个RTMP_Write
调用发送每个标签,您甚至不需要处理传入的数据包。
棘手的部分是理解FLV文件是如何生成的。官方规范可以在这里获得:http://www.adobe.com/devnet/f4v.html
首先,有一个头,它由9个字节组成。此标头不能发送到服务器,而只能通读,以确保文件确实是FLV。
然后是一系列的标签。每个标签都有一个11字节的头部,其中包含标签类型(视频/音频/元数据)、主体长度和标签的时间戳等。
标签头可以用这个结构来描述:
typedef struct __flv_tag {
uint8 type;
uint24_be body_length; /* in bytes, total tag size minus 11 */
uint24_be timestamp; /* milli-seconds */
uint8 timestamp_extended; /* timestamp extension */
uint24_be stream_id; /* reserved, must be "\0\0\0" */
/* body comes next */
} flv_tag;
正文长度和时间戳被表示为24位大端整数,如果需要,还可以使用一个补充字节将时间戳扩展到32位(大约是4小时标记)。
一旦你阅读了标签头,你就可以阅读主体本身,因为你现在知道它的长度(body_length
)。
之后是一个32位的大端整数值,它包含标签的完整长度(11字节+ body_length
)。
你必须在一个RTMP_Write
调用中写下标签头+正文+先前的标签大小(否则它不会播放)。
此外,请注意以视频的名义帧速率发送数据包,否则将严重影响回放。
我已经写了一个完整的FLV文件解复用器,作为我的GPL项目FLVmeta的一部分,你可以作为参考。
发布于 2011-03-15 22:57:10
实际上,RTMP_Write()似乎要求您已经在buf中形成了RTMP包。
RTMPPacket *pkt = &r->m_write;
...
pkt->m_packetType = *buf++;
因此,您不能只将flv数据推送到那里-您需要首先将其分离为数据包。
有一个很好的函数RTMP_ReadPacket(),但它是从网络套接字读取的。
我和你有同样的问题,希望能尽快得到解决。
编辑:
RTMP_Write()中存在某些错误。我做了一个补丁,现在它可以工作了。我将发表这篇文章。
https://stackoverflow.com/questions/4524587
复制相似问题