同步两个 AS3 NetStream
我正在编写一个应用程序,需要在播放背景音轨时录制音频流。我可以正常工作,但播放和记录启动之间存在不一致的间隙。
我不知道我是否可以做任何事情来使同步每次都完美,所以我一直在尝试跟踪每个流的开始时间,以便我可以计算延迟并在服务器端修剪它。这也被证明是一个挑战,因为连接启动时似乎没有发送任何事件(据我所知)。我尝试过使用各种属性,例如流的缓冲区大小等。
我现在想,由于我录制的音频只是单声道,我也许可以在第二个立体声轨道上放置某种“控制信号”可以用来准确确定声音何时开始录制(或者将整个背景音轨粘贴在该通道中,以便我可以以这种方式同步它们)。这给我带来了如何将此声音正确注入 NetStream 的新问题。
如果有人知道这些想法是否行得通、如何执行它们或一些替代方案,那将非常有帮助!已经研究这个问题有一段时间了
I'm writing an app that requires an audio stream to be recording while a backing track is played. I have this working, but there is an inconsistent gap in between playback and record starting.
I don't know if I can do anything to make the sync perfect every time, so I've been trying to track what time each stream starts so I can calculate the delay and trim it server-side. This also has proved to be a challenge as no events seem to be sent when a connection starts (as far as I know). I've tried using various properties like the streams' buffer sizes, etc.
I'm thinking now that as my recorded audio is only mono, I may be able to put some kind of 'control signal' on the second stereo track which I could use to determine exactly when a sound starts recording (or stick the whole backing track in that channel so I can sync them that way). This leaves me with the new problem of properly injecting this sound into the NetStream.
If anyone has any idea whether or not any of these ideas will work, how to execute them, or some alternatives, that would be extremely helpful! Been working on this issue for awhile
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
唯一想到的是尝试使用元数据,flash 媒体流支持元数据和 onMetaData 回调。我假设您正在使用闪存媒体服务器来输入音频并记录输出的音频。如果您使用发送方法,当您将音频流式传输回服务器时,您可以将收听音轨的播放头时间戳放入其中,因此当您将 2 个流送回服务器时,您可以将它们正确地混合在一起。您还可以尝试使用元数据对流式传输到客户端的音频进行编码,并尝试使用 onMetaData 来同步它们。我不知道如何做到这一点,但第二种方法是尝试在音频返回时将 2 个流组合在一起,这样您就不需要稍后混合它们,或者将其附加到带有 2 个空白视频流音轨...
The only thing that comes to mind is to try and use metadata, flash media streams support metadata and the onMetaData callback. I assume you're using flash media server for the audio coming in and to record the audio going out. If you use the send method while your streaming the audio back to the server, you can put the listening audio track's playhead timestamp in it, so when you get the 2 streams back to the server you can mux them together properly. You can also try encoding the audio that is streamed to the client with metadata and try and use onMetaData to sync them up. I'm not sure how to do this, but a second approach is to try and combine the 2 streams together as the audio goes back so that you don't need to mux them later, or attach it to a blank video stream with 2 audio tracks...
如果你要向NetStream注入一些东西...像声音一样复杂...我想这里最好使用Socket。您将直接读取字节。 NetStream 上可能存在压缩,因此发送的数据不是原始声音数据 - 需要一些用于解压缩编解码器的类。当您最终获得原始声音数据时,使用 Socket.readUnsignedByte() 或 Socket.readFloat() 向其中添加输入,并使用 写回修改后的数据em>Socket.writeByte(),或Socket.writeFloat()。
这是将背面注入音频的替代方案。
对于同步来说,其实很简单。尽管数据可能不会立即发送,但有一件事仍然保持不变——时间。因此,当用户的音频完成后,只需将其混合到后轨,无需任何其他内容 - 时间应保持不变。
如果用户的互联网下载速度很慢,因此他的回溯有不必要的中断 - 检查 SWF 中的数据是否有足够的缓冲来添加下一个声音缓冲区(如果我没记错的话,通常为 4096 字节)。如果是,则继续传输用户的音频。
如果没有,请不要进行流式传输,并在数据恢复后立即开始。
If you're to inject something into the NetStream... As complex as SOUND... I guess here it would be better to go with Socket instead. You'll be directly reading bytes. It's possible there's a compression on the NetStream, so the data sent is not raw sound data - some class for decompressing the codec there would be needed. When you finally get the raw sound data, add the input in there, using Socket.readUnsignedByte() or Socket.readFloat(), and write back the modified data using Socket.writeByte(), or Socket.writeFloat().
This is the alternative with injecting the back into the audio.
For syncing, it is actually quite simple. Even though the data might not be sent instantly, one thing still stays the same - time. So, when user's audio is finished, just mix it without anything else to the back track - the time should stay the same.
IF the user has slow internet DOWNLOAD, so that his backtrack has unwanted breaks - check in the SWF if the data is buffered enough to add the next sound buffer (usually 4096 bytes if I remember correctly). If yes, continue streaming user's audio.
If not, do NOT stream, and start as soon as the data catches back on.
根据我的经验,NetStream 是 Flash 最不准确和最肮脏的功能之一(NetStream:play2?!!),顺便说一句,看到 Flash 的主要用途可能是视频播放,这非常讽刺。
尝试以可靠的方式将其与其他任何内容同步非常困难...事件和状态不是很直接,并且有多个问题可能会破坏您的同步。
然而幸运的是,netStream.time 会非常准确地告诉您当前播放头位置,因此您最终可以使用它来确定开始时间、延迟、丢帧等...请注意,确定实际开始时间有点棘手。当您开始加载 netStream 时,时间值为零,但是当它显示第一帧并等待缓冲区填充(尚未播放)时,时间值类似于 0.027(取决于视频),因此您需要非常仔细地监视该值以准确确定事件。
使用 NetStream 的替代方法是将视频嵌入 SWF 文件中,这将使同步变得更加容易(特别是在编码时使用频繁的关键帧时)。但你会失去质量/文件大小比(如果我没记错的话,你只能使用 FLV,而不是 h264)。
In my experience NetStream is one of the most inaccurate and dirty features of Flash (NetStream:play2 ?!!), which btw is quite ironic seeing how Flash's primary use is probably video playback.
Trying to sync it with anything else in a reliable way is very hard... events and statuses are not very straight forward, and there are multiple issues that can spoil your syncing.
Luckily however, netStream.time will tell you quite accurately the current playhead position, so you can eventually use that to determine starting time, delays, dropped frames, etc... Notice that determining the actual starting time is a bit tricky though. When you start loading a netStream, the time value is zero, but when it shows the first frame and is waiting for the buffer to fill (not playing yet) the time value is something like 0.027 (depends on the video), so you need to very carefully monitor this value to accurately determine events.
An alternative to using NetStream is embedding the video in a SWF file, which should make synchronization much easier (specially if you use frequent keyframes on encoding). But you will lose quality/filesize ratio (If I remember correctly you can only use FLV, not h264).
确实有。. NetStatusEvent.NET_STATUS 由于 NetConnections 和 Netstreams 的多种原因而触发,您只需添加一个侦听器并处理 NET_STATUS.info 的内容
as3 参考文档 此处,您正在寻找 NET_STATUS。信息
sure there does.. NetStatusEvent.NET_STATUS fires for a multitude of reasons for NetConnections and Netstreams, you just have to add a listener and process the contents of NET_STATUS.info
the as3 reference docs here and you're looking for NET_STATUS.info