8

问题

我必须用定制组件替换现有 Flex 项目中的mx:VideoDisplay组件。

为了实现这一点,我必须符合其当前接口,因此我的组件接收视频网址(通过源参数),格式为:

  1. /data/myflvfile.flv(如果文件在本地播放)
  2. rtmp://streamcloud.myserver.com/cfx/st/somedirectory/myflvfile.flv(如果文件是从 Cloudfront 流式传输的)

我的新组件基于 NetConnection 和 NetStream。对于上面的任何条目,我必须将输入分成两个字符串:一个用于 NetConnection.connect(NetConnectionStr) 方法,另一个用于 NetStream.play(NetStreamStr) 方法。例如:

  1. 给定/data/myflvfile.flv然后:
    • NetConnectionStr = null
    • NetStreamStr = "/data/myflvfile"
  2. 给定rtmp://streamcloud.myserver.com/cfx/st/somedirectory/myflvfile.flv然后:
    • NetConnectionStr = "rtmp://streamcloud.myserver.com/cfx/st"
    • NetStreamStr = "somedirectory/myflvfile"
  3. 给定rtmp://streamcloud.myserver.com/cfx/st/somedirectory/subdirectory/myflvfile.flv然后:
    • NetConnectionStr = "rtmp://streamcloud.myserver.com/cfx/st"
    • NetStreamStr = "一些目录/子目录/myflvfile"

对于“本地文件”情况,构建这两个字符串非常明显,但在其他情况下会变得很棘手。问题是我没有聪明的方法来猜测输入的哪一部分是服务器 URL,哪一部分是流名称 + 目录结构。

在 Internet 上找到的一些示例中,人们只是猜测源的最后一部分(找到的最后一个“/”之后的内容)是 NetStream 名称。就我而言,这并不总是正确的,因为流可能位于服务器的子目录中。更糟糕的是,服务器名称可能包含“/”字符!

解决它的策略

连接到服务器,检索其真实 URL,查找流名称

由于 NetConnection 似乎足够“聪明”,我的第一次尝试是使用完整的源 URL 调用 connect 方法。例如,给定 rtmp://streamcloud.myserver.com/cfx/st/somedirectory/subdirectory/myflvfile.flv

NetConnection 在以下方面取得了成功:

  • connection.connect( rtmp://streamcloud.myserver.com/cfx/st/ )
  • connection.connect( rtmp://streamcloud.myserver.com/cfx/st/somedirectory/ )
  • ...
  • connection.connect(rtmp://streamcloud.myserver.com/cfx/st/somedirectory/subdirectory/myflvfile.flv

然后我希望以某种方式检索服务器的“真实”url(rtmp://streamcloud.myserver.com/cfx/st),这样我就可以猜测流部分(somedirectory/subdirectory/myflvfile)。

不幸的是,我发现无法从 NetConnection 对象中获取真正的服务器地址(connection.uri 返回确切的输入)。所以这似乎是一个死胡同。

连接到服务器,迭代检索流

另一种策略可能是连接到服务器,然后反复尝试(从最后开始)播放流,直到它工作:

给定rtmp://streamcloud.myserver.com/cfx/st/somedirectory/subdirectory/myflvfile.flv

  • 尝试 1: stream.play( myflvfile )失败
  • 尝试2: stream.play(子目录/myflvfile失败
  • 尝试 3: stream.play( somedirectory/subdirectory/myflvfile )成功

但这是一种非常难看的方法,我正在寻找更好的解决方案。

更好的解决方案?

有什么好的方法可以解决这个问题吗?有谁知道他们在原始 VideoDisplay 组件中是如何做到的(如果它基于 NetConnection/NetStream 对象?)?

提前感谢您对此问题的任何帮助和/或评论:)

4

3 回答 3

0

我对你的问题感到困惑。您与 rtmp 的连接中没有一致的部分吗?您是否定期更换流媒体提供商?如果这是一致的,那么至少赢得了一半的战斗。我如何连接到 rtmp 是连接中的内容总是相同的。后半部分更动态,以同样的方式传入;[文件夹空间]/[视频名称]。我将只对传入的内容进行所有解析,但我只有一个 rtmp 提供程序。

于 2013-07-25T18:17:39.613 回答
0

在没有针对正在运行的 rtmp 服务测试解决方案的情况下,很难绝对验证这一点,但请考虑对您的第二个不太理想的策略进行以下改进:

  • 像往常一样创建一个 NetConnection

  • 第一次 connect() 成功时,迭代服务和资产的可能组合(“rtmp://streamcloud.myserver.com/cfx/”和“/st/somedirectory/subdirectory/myflvfile.flv”等),以及为每个创建并发 NetStreams——这样您就不必等待顺序发现

  • 如果其中一个 NetStreams 发送了一个成功事件,则将它附加到显示器上并将所有其他的放在地板上(它们可能无论如何都会失败)

  • 可选地,您可以存储成功的服务/资产对,以便在要重用连接时加快速度

这似乎是一个令人头疼的问题!

于 2011-12-14T04:56:58.333 回答
0
var match:Array = path.match('rtmp://(.*/.*/.*/)');
var server:String = match[0];
var file:String = removeExtension(path.replace(match[1], ''));
var channel:String = removeExtension(path.replace(match[2], ''));

参考: http: //onyx-vj.googlecode.com/svn/trunk/Onyx-VJ%203.0.0/OnyxCore/onyx/core/ProtocolRTMP.as

于 2011-11-28T00:08:19.617 回答