AS3、NetConnection/NetStream:是否有一种智能方法来拆分源 url?

发布于 2024-12-17 19:21:17 字数 2913 浏览 0 评论 0原文

问题

我必须用自定义组件替换现有 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 =
    • NetStreamStr = “/data/myflvfile”
  2. 给定 rtmp://streamcloud.myserver.com/cfx/st/somedirectory/myflvfile .flv 然后:
    • NetConnectionStr = “rtmp://streamcloud.myserver.com/cfx/st”
    • NetStreamStr = “某个目录/myflvfile”
  3. 给定 rtmp:// streamcloud.myserver.com/cfx/st/somedirectory/subdirectory/myflvfile.flv 然后:
    • NetConnectionStr = “rtmp://streamcloud.myserver.com/cfx/st”
    • NetStreamStr = “某个目录/子目录/myflvfile”

构建两个字符串非常简单对于“本地文件”情况来说很明显,但在其他情况下却变得棘手。问题是我没有聪明的方法来猜测输入的哪一部分是服务器 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/)
  • 连接.connect(rtmp://streamcloud.myserver.com/cfx/st/somedirectory/)
  • ...
  • connection.connect(rtmp://streamcloud.myserver.com/cfx/st/somedirectory/subdirectory/myflvfile.flv)

然后我希望以某种方式检索服务器的“真实”url (< strong>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(subdirectory/myflvfile) 失败
  • 尝试 3: >stream.play(somedirectory/subdirectory/myflvfile) 成功

但这是一种非常丑陋的继续方式,我正在寻找更好的解决方案。

更好的解决方案?

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

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

The problem

I have to replace the mx:VideoDisplay component in an existing Flex project with a custom made component.

To achieve this, I have to conform to its current Interface, so my component receives the video urls (via source parameter) in the form of either:

  1. /data/myflvfile.flv (if the file is played locally)
  2. rtmp://streamcloud.myserver.com/cfx/st/somedirectory/myflvfile.flv (if the file is streamed from Cloudfront)

My new component is based on NetConnection and NetStream. With any of the entries above I have to split the input in two strings: one for the NetConnection.connect(NetConnectionStr) method and the other for the NetStream.play(NetStreamStr) method. For instance:

  1. Given /data/myflvfile.flv then:
    • NetConnectionStr = null
    • NetStreamStr = "/data/myflvfile"
  2. Given rtmp://streamcloud.myserver.com/cfx/st/somedirectory/myflvfile.flv then:
    • NetConnectionStr = "rtmp://streamcloud.myserver.com/cfx/st"
    • NetStreamStr = "somedirectory/myflvfile"
  3. Given rtmp://streamcloud.myserver.com/cfx/st/somedirectory/subdirectory/myflvfile.flv then:
    • NetConnectionStr = "rtmp://streamcloud.myserver.com/cfx/st"
    • NetStreamStr = "somedirectory/subdirectory/myflvfile"

Building the two strings is very obvious for the "local files" case, but it gets tricky in the others. The problem is that I have no smart way to guess what part of the input is the server URL and what part is the stream name + directory structure.

In some examples found on the Internet, people are simply guessing that the last part of the source (what is after the last "/" found) is the NetStream name. In my case, this is not always true because the streams may be in subdirectories on the server. It is even worse because server names may contain "/" characters!

Strategies to solve it

Connecting to server, retrieving its real URL, finding stream name

As NetConnection seems to be "smart" enough, my first attempt was to invoke connect method with the full source url. For instance, given
rtmp://streamcloud.myserver.com/cfx/st/somedirectory/subdirectory/myflvfile.flv

NetConnection is a success with:

  • 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)

Then I was hoping to retrieve somehow the "real" url of the server (rtmp://streamcloud.myserver.com/cfx/st) so I would be able to guess the stream part (somedirectory/subdirectory/myflvfile).

Unfortunately, I found no way to get the real server adress out of a NetConnection object (connection.uri returns back the exact input). So this seems to be a dead end.

Connecting to server, iteratively retrieving streams

Another strategy could be to connect to the server and then try iteratively (starting from the very end) to play streams until it works:

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

  • Try 1: stream.play(myflvfile) FAIL
  • Try 2: stream.play(subdirectory/myflvfile) FAIL
  • Try 3: stream.play(somedirectory/subdirectory/myflvfile) SUCCESS

But this is a very ugly way to proceed, and I am looking for a better solution.

A better solution?

Is there any good method to solve this issue? Does anyone knows how they are doing it in the original VideoDisplay component (if it is based on NetConnection/NetStream objects?)?

Thanks in advance for any help and/or comments on this issue :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烟雨扶苏 2024-12-24 19:21:17
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

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], ''));

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

和影子一齐双人舞 2024-12-24 19:21:17

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

  • 正常创建 NetConnection

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

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

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

这似乎是一个令人烦恼的问题!

Without having tested a solution against a running rtmp service, it's hard to verify this absolutely but consider the following refinement of your second, less desirable strategy:

  • create a NetConnection as normal

  • the first time connect() is successful, iterate through possible combinations of service and asset ("rtmp://streamcloud.myserver.com/cfx/" & "/st/somedirectory/subdirectory/myflvfile.flv", etc), and create concurrent NetStreams for each one -- that way you don't have to wait for sequential discovery

  • if one of the NetStreams dispatches a success event, attach it to the display and drop all the other ones on the floor (they will probably fail out anyway)

  • optionally you could store the successful service / asset pair that worked, to speed things up if the connection is to be reused

It seems like a vexing problem!

倦话 2024-12-24 19:21:17

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

I'm confused by your question. Is there no part of your connection to rtmp that is consistent? Are you swapping streaming providers regularly? If that is consistent then at least half the battle is won. How I go about connecting to rtmp is what goes in the connect is always the same. The latter part is more dynamic which is passed in, in the same way; [folder space]/[video name]. I'll do all my parsing only on what is passed in but then I have a single rtmp provider.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文