AS3,NetConnection / NetStream:有没有一种智能的方法来分割源URL?

时间:2011-11-22 14:33:53

标签: flash actionscript-3 flex netstream netconnection

问题

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

要实现这一点,我必须遵守其当前的接口,因此我的组件以以下形式接收视频网址(通过源参数):

  1. /data/myflvfile.flv (如果文件在本地播放)
  2. rtmp://streamcloud.myserver.com/cfx/st/somedirectory/myflvfile.flv (如果文件是从Cloudfront流式传输的)
  3. 我的新组件基于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 = “somedirectory / subdirectory / myflvfile”
    4. 对于“本地文件”情况,构建两个字符串非常明显,但在其他字符串中却变得棘手。问题是我没有聪明的方法来猜测输入的哪一部分是服务器URL,哪个部分是流名称+目录结构。

      在互联网上发现的一些例子中,人们只是猜测源的最后部分(发现的最后一个“/”之后)是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

      然后我希望以某种方式检索服务器的“真实”网址( rtmp://streamcloud.myserver.com/cfx/st ),这样我就能猜出流部分(的 somedirectory /子目录/ 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对象?)?

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

  • 正常创建NetConnection

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

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

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

这似乎是一个棘手的问题!

答案 2 :(得分:0)

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