为啥 Flash-Player 不能播放 RTMP 直播流

Posted

技术标签:

【中文标题】为啥 Flash-Player 不能播放 RTMP 直播流【英文标题】:Why can Flash-Player not play RTMP live stream为什么 Flash-Player 不能播放 RTMP 直播流 【发布时间】:2014-06-30 15:19:42 【问题描述】:

我有一个 Flash 播放器(只有 SWF 文件,没有源文件),我们在我们的 Intranet 项目中使用它来播放 RTMP 流。 今天我被这个播放器无法播放的新 RTMP URL 卡住了。同时它很容易用 MediaElements.js 内置 SWF 播放器播放。 我想知道,它会是什么?

我只有一个线索:当我使用 rtmpdump 时,流只加载--live 标志。但是调试输出对我来说是有争议的。由于 --live 标志只调用 FCSubscribe,然后服务器回答 Method not found (FCSubscribe) 并且现在流正在开始。


一些rtmpdump 输出。

没有--live 标志我得到这个:

DEBUG: Invoking createStream
DEBUG: RTMP_ClientPacket, received: invoke 29 bytes
DEBUG: (object begin)
DEBUG: Property: NULL
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking <_result>
DEBUG: HandleInvoke, received result for method call <createStream>
DEBUG: SendPlay, seekTime=0, stopTime=1000, sending play: livestream_3
DEBUG: Invoking play
DEBUG: sending ctrl. type: 0x0003
DEBUG: HandleChangeChunkSize, received: chunk size change to 4096
DEBUG: RTMP_ClientPacket, received: invoke 185 bytes
DEBUG: (object begin)
DEBUG: Property: NULL
DEBUG: (object begin)
DEBUG: Property: <Name:              level, STRING: error>
DEBUG: Property: <Name:               code, STRING: NetStream.Play.StreamNotFound>
DEBUG: Property: <Name:        description, STRING: Failed to play livestream_3; stream not found.>
DEBUG: Property: <Name:            details, STRING: livestream_3>
DEBUG: Property: <Name:           clientid, STRING: qAASQnAA>
DEBUG: (object end)
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking <onStatus>
DEBUG: HandleInvoke, onStatus: NetStream.Play.StreamNotFound
ERROR: Closing connection: NetStream.Play.StreamNotFound
DEBUG: Closing connection.

有了它,我明白了:

DEBUG: Invoking createStream
DEBUG: FCSubscribe: livestream_3
DEBUG: Invoking FCSubscribe
DEBUG: RTMP_ClientPacket, received: invoke 29 bytes
DEBUG: (object begin)
DEBUG: Property: NULL
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking <_result>
DEBUG: HandleInvoke, received result for method call <createStream>
DEBUG: SendPlay, seekTime=0, stopTime=1000, sending play: livestream_3
DEBUG: Invoking play
DEBUG: sending ctrl. type: 0x0003
DEBUG: RTMP_ClientPacket, received: invoke 119 bytes
DEBUG: (object begin)
DEBUG: Property: NULL
DEBUG: (object begin)
DEBUG: Property: <Name:              level, STRING: error>
DEBUG: Property: <Name:               code, STRING: NetConnection.Call.Failed>
DEBUG: Property: <Name:        description, STRING: Method not found (FCSubscribe).>
DEBUG: (object end)
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking <_error>
ERROR: rtmp server sent error
DEBUG: HandleChangeChunkSize, received: chunk size change to 4096
DEBUG: HandleCtrl, received ctrl. type: 0, len: 6
DEBUG: HandleCtrl, Stream Begin 1
DEBUG: RTMP_ClientPacket, received: invoke 166 bytes
DEBUG: (object begin)
DEBUG: Property: NULL
DEBUG: (object begin)
DEBUG: Property: <Name:              level, STRING: status>
DEBUG: Property: <Name:               code, STRING: NetStream.Play.Reset>
DEBUG: Property: <Name:        description, STRING: Playing and resetting livestream_3.>
DEBUG: Property: <Name:            details, STRING: livestream_3>
DEBUG: Property: <Name:           clientid, STRING: qAARQnAA>
DEBUG: (object end)
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking <onStatus>
DEBUG: HandleInvoke, onStatus: NetStream.Play.Reset
DEBUG: RTMP_ClientPacket, received: invoke 160 bytes
DEBUG: (object begin)
DEBUG: Property: NULL
DEBUG: (object begin)
DEBUG: Property: <Name:              level, STRING: status>
DEBUG: Property: <Name:               code, STRING: NetStream.Play.Start>
DEBUG: Property: <Name:        description, STRING: Started playing livestream_3.>
DEBUG: Property: <Name:            details, STRING: livestream_3>
DEBUG: Property: <Name:           clientid, STRING: qAARQnAA>
DEBUG: (object end)
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking <onStatus>
DEBUG: HandleInvoke, onStatus: NetStream.Play.Start
Starting Live Stream

附:我不是 AS2/AS3 开发人员,所以我对 Flash 中所有类似 RTMP 的东西都不熟悉。

【问题讨论】:

如何让 swf 播放视频? @LDMediaServices 我在 flashvars 中传递 rtmp URL。它与以前的流一样工作。但是现在不要使用来自不同服务器的不同流(不幸的是,我现在对此服务器一无所知)。 【参考方案1】:

抱歉,简短的回答是,如果没有源代码,您将无法解决此问题。缺少处理某些 CDN 服务器使用的 onFCsubscribe 方法的函数。

并非所有流/服务器都会执行此请求,所以这就是您到目前为止很幸运的原因。但实际上,该编码器应该进行更好的测试,而不是假设所有 RTMP 流都是平等的。

我回答了一个类似的问题 [下面的链接],如果您查看该源代码,您会看到有一个 onFCSubscribe 函数。如果您(或可以提供帮助的人)使用您自己的流链接编译该示例代码,它很可能会起作用。

How can I play a RTMP video through netConnection and netStream

或者您可以联系 SWF 创建者以更新他们的代码并向您发送重新编译的新 SWF。修复是对上述链接答案的简单复制/粘贴。您的问题是缺少源文件...

【讨论】:

谢谢。你知道我可以找到关于什么是 FCsubscribe 的一些描述的任何来源吗?我只发现了这一点,但我并不完全理解有关 CDN-服务器-播放器交互的所有内容。我想尝试与我遇到问题的流的所有者交谈,以从他们这边解决问题。所以我想知道我是否可以要求他们“关闭 FCsubscribe 要求”。 FCsubscribe 是一种提供流的方法。 Video-On-Demand (VOD) 使用它来决定谁可以观看流媒体。简单地解释一下:想想一个体育频道,如果您只为两小时的拳击付费,那么当拳击之后的三小时足球比赛开始时,您的连接将是 FC UN-Subscribed。我不知道关闭它,因为这会影响他们的商业模式并为每个人释放流。在 Flash 中它很傻,因为要修复你只需要一个函数来处理 onFCsubscribe 请求。它甚至可以是空的,但只要它是该请求的处理程序,它就可以正常工作

以上是关于为啥 Flash-Player 不能播放 RTMP 直播流的主要内容,如果未能解决你的问题,请参考以下文章

video.js播放rtmp

videojs集成--播放rtmp流

使用vedio.js 7在html中播放rtmp视频流

问rtmp 如何做link 才能播放

网络电视怎么把sop,rtsp,flv,http,rtmp,m3u8 这些流媒体协议转成mms协议播放?不更换专门对应的协议的播放

用于 RTMP 和支持广告的免费视频播放器