首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在C/C++中使用librtmp发布流

在C/C++中使用librtmp发布流
EN

Stack Overflow用户
提问于 2010-12-24 14:19:17
回答 2查看 12.4K关注 0票数 8

如何使用librtmp库发布流?我阅读了librtmp手册页,对于发布,使用了RTMP_Write()。

我是这样做的。

代码语言:javascript
运行
复制
//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/其他消息,我使用一个线程来响应,如下所示:

代码语言:javascript
运行
复制
//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媒体服务器?

EN

回答 2

Stack Overflow用户

发布于 2012-12-10 22:41:24

根据我自己的经验,将视频数据流式传输到RTMP服务器在librtmp端实际上非常简单。棘手的部分是正确地打包视频/音频数据,并以正确的速率读取它。

假设您使用的是FLV视频文件,只要您能够正确地隔离文件中的每个标签,并使用一个RTMP_Write调用发送每个标签,您甚至不需要处理传入的数据包。

棘手的部分是理解FLV文件是如何生成的。官方规范可以在这里获得:http://www.adobe.com/devnet/f4v.html

首先,有一个头,它由9个字节组成。此标头不能发送到服务器,而只能通读,以确保文件确实是FLV。

然后是一系列的标签。每个标签都有一个11字节的头部,其中包含标签类型(视频/音频/元数据)、主体长度和标签的时间戳等。

标签头可以用这个结构来描述:

代码语言:javascript
运行
复制
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的一部分,你可以作为参考。

票数 9
EN

Stack Overflow用户

发布于 2011-03-15 22:57:10

实际上,RTMP_Write()似乎要求您已经在buf中形成了RTMP包。

代码语言:javascript
运行
复制
RTMPPacket *pkt = &r->m_write;
...
pkt->m_packetType = *buf++;

因此,您不能只将flv数据推送到那里-您需要首先将其分离为数据包。

有一个很好的函数RTMP_ReadPacket(),但它是从网络套接字读取的。

我和你有同样的问题,希望能尽快得到解决。

编辑:

RTMP_Write()中存在某些错误。我做了一个补丁,现在它可以工作了。我将发表这篇文章。

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

https://stackoverflow.com/questions/4524587

复制
相关文章

相似问题

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