2016-10-28 47 views
7

我正在尝试为我正在开发的应用程序构建自己的客户端RTMP库。到目前为止,一切都已经相当成功,因为我能够连接到RTMP服务器协商握手,然后发送所有必要的数据包(FCPublish Publish ETC),然后从服务器获得NetStream.Publish.Start的onStatus消息,这意味着我已经成功地让服务器让我开始发布我的实时视频广播。 Wireshark还确认信息(/ Data packetizing)是正确的,因为它在那里也正确显示。RTMP摄取块流问题

现在,我遇到问题的地方是RTMP Chunking,关闭Adobe RTMP Specification(第17页)& 18显示了消息如何分块的示例。从这个例子中,我可以看到它是基于块大小(128字节)分解的。对于我来说,块的大小在最初的连接和交换中得到协商,总是4096字节。因此,当我交换大于4096字节的视频数据时,我需要将消息分块,然后发送RTMP packetHeader和前4096个字节的数据,然后发送一个小RTMP头0xc4(0xc0 | packetHeaderType(0x04))结合4096个字节的视频数据,直到由报头指定的完整数据包发送完毕。然后出现一个新的框架并重复相同的过程。

通过检查使用不同语言编写的其他RTMP客户端示例,这似乎是他们都在做的。不幸的是,我试图流式传输的摄取服务器没有收集广播视频数据,他们没有关闭我的连接,他们只是从不显示视频或任何标志视频是正确的。 Wireshark显示,在发送视频原子数据包后,大部分发送的数据包都是未知数(0x0),然后他们将切换到视频数据,并在触发器显示未知(0x0)和视频数据之间进行排序。但是,如果我将有效负载最大值限制为20000字节,则Wireshark会将所有内容显示为视频数据。很显然,在这种情况下,摄取服务器不会显示视频,因为我将大块数据移除为只有20k字节。

试图弄清楚发生了什么问题我开始了另一个xcode项目,它允许我欺骗我的Lan上的RTMP服务器,这样我就可以在libRTMP IOS进入服务器时看到数据的外观。另外,对于libRTMP,我可以让它记录它发送的数据包,并且即使我已经发送Change Chunk size消息作为服务器,它们似乎也会注入字节0xc4甚至128个字节。当我尝试在RTMP客户端库中复制此内容时,只需使用128块大小,即使它已被设置为4096字节,服务器也会关闭我的连接。但是,如果将libRTMP更改为尝试转到实时RTMP服务器,它仍会在LibRTMP内打印出它正在发送大小为128的块的数据包。并且服务器似乎在视频显示时接受它。当我查看RTMP服务器上的数据时,我可以看到它们都是他们的。

任何人有任何想法可能会发生什么?

回答

2

虽然我没有专门研究RTMP,但我已经非常广泛地使用了RTSP/RTP/RTCP,所以,基于这种经验和我一路上碰到的挫伤,以下是一些随机的,可能适用的提示可能有助于/寻找可能导致问题的东西:

  1. 您的视频编码与您告诉服务器的内容相符吗?换句话说,如果您的视频编码为H.264,那么您要为服务器指定什么?
  2. 数据是否与服务器期望的容器格式相匹配?例如,如果服务器希望接收MPEG-4电影(.m4v)文件,但只发送编码的MPEG-4(.mp4)流,则需要将MPEG-4视频流封装为MPEG-4电影容器。相反,如果服务器预期只有一个MPEG-4视频流,但是您要发送封装的MPEG-4电影,则需要将MPEG-4流从其容器中解混出来,并仅发送该内容。
  3. 您是否考虑了传输介质的MTU?无论块大小如何,在客户端和服务器之间获得MTU不匹配都很难进行调试(这也可能是为什么您将某些数据包列为“未知”类型,其他数据类型为“视频数据”类型)。只要MTU一致,大部分操作系统的内置分割和重组(SAR)基础架构都将处理这些操作,但是如果您必须执行自己的SAR逻辑,则很容易获得此功能错误。
  4. 您是否尝试过使用libRTMP iOS和您自己的客户端在Wireshark中捕获流量并将数据包并排比较?有时,“参考”数据包跟踪对于发现最初并不重要的一点点(或多点)是非常宝贵的。

祝你好运!

+0

感谢您的回复,我其实今天刚刚解决了这个问题,您的第一个回复涵盖了它。原来我的AVCC原子被填充了3 0x00,需要填充4 0x00才能符合闪存规范!我一直在寻找创造视频帧而不是ATOM的东西。服务器不知道我发送给它的格式化数据,因此无法读取数据。 – Charlie

+0

不错,很高兴你追踪到它! – fullofsquirrels

+0

对不起,我认为它汽车给选定的答案赏金,有一封电子邮件说,它仍然存在。意思是把它给你。 – Charlie