Netstream 和step() 或seek()?

发布于 2025-01-07 04:57:43 字数 739 浏览 4 评论 0原文

我正在做一个 AS3 项目,正在播放视频 (H264)。由于某些特殊原因,我想去某个职位。

a) 我用 NetStream.seek() 尝试一下。在那里它只进入关键帧。在我当前的设置中,这意味着,我可以每 1 秒找到一个位置。 (为了获得更好的分辨率,我必须使用尽可能多的关键帧对电影进行编码,也就是每一帧都是关键帧)

  • 这绝对不是我最喜欢的方式,因为我不想重新编码所有视频。

b) 我尝试使用 NetStream.step()。这应该让我有机会慢慢地从一帧走到另一帧。但在文档中它说:

仅当数据从 Flash Media Server 3.5.3 或更高版本流式传输且 NetStream.inBufferSeek 为 true 时,此方法才可用。

http://help.adobe.com /en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#step()

这是否意味着 Air for Desktop 无法实现?当我尝试时,没有任何作用。

有什么建议,如何解决这个问题?

问候和谢谢你! 尼古拉斯

I'm on an AS3 project, playing a video (H264). I want, for some special reasons, to go to a certain position.

a) I try it with NetStream.seek(). There it only goes to keyframes. In my current setting, this means, i can find a position every 1 second. (for a better resolution, i'd have to encode the movie with as many keyframes as possible, aka every frame a keyframe)

  • this is definetly not my favourite way, because I don't want to reencode all the vids.

b) I try it with NetStream.step(). This should give me the opportunity to step slowly from frame to frame. But in the documentation it says:

This method is available only when data is streaming from Flash Media Server 3.5.3 or higher and when NetStream.inBufferSeek is true.

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#step()

Does this mean, it is not possible with Air for Desktop? When I try it, nothing works.

Any suggestions, how to solve this problem?

Greetings & Thank you!
Nicolas

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

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

发布评论

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

评论(3

淤浪 2025-01-14 04:57:43

Flash 视频只能提前几秒,除非您有 Flash Media Server 托管您的视频。从技术上讲,这意味着您可以让它在 Air 中按预期工作,但是,视频必须是流式传输的(愚蠢的 adobe...)。

您有两个选择:

1) 将素材导入为影片剪辑。 Flash IDE 有一个向导,如果您专门在非 FlashIDE 环境中进行开发,则可以转换并导出为外部资源,例如 SWF 或 SWC。然后,它将嵌入或运行时加载到您的应用程序中,让您可以访问 MovieClip 的每帧可步进方法。然而,这确实带来了一些音频同步问题(iirc)。而且,向后擦洗也不是MC的强项。

2) 编写您自己的视频对象,加载图像序列并按顺序显示每个帧。您必须设置自己的音频同步功能,但这可能是除了 FLVComponent 或 NetStream 之外最直接的解决方案。

Flash video can only be advanced by seconds unless you have Flash Media Server hosting your video. Technically, that means that you can have it working as intended in Air, however, the video would have to be streaming (silly adobe...).

You have two options:

1) Import the footage as a movieclip. The Flash IDE has a wizard for this, and if you're developing exclusively in non-FlashIDE environment, you can convert and export as an external asset such as an SWF or SWC. This would then be embedded or runtime loaded into your app giving you access to the per-frame steppable methods of MovieClip. This, however, does come with some audio syncing issues (iirc). Also, scrubbing backwards is not an MC's forté.

2) Write your own video object that loads an image sequence and displays each frame in order. You'd have to setup your own audio syncing abilities, but it might be the most direct solution apart from FLVComponent or NetStream.

留蓝 2025-01-14 04:57:43

我注意到 Flash Player 9 的擦洗效果很好且平滑,但在 Player 10+ 中我没有遇到擦洗问题。

我的解决办法是将查找函数的调用频率限制为 <= 200 毫秒。这种固定的擦洗,但不如播放器 9 流畅得多。也许是因为“Flash 视频只能前进几秒”的限制?我使用计时器来触发为视频调用eek() 的函数。

    private var scrubInterval:Timer = new Timer(200);

    private function  videoScrubberTouch():void {
        _ns.pause();

        var bounds:Rectangle = new Rectangle(0,0,340,0);

        scrubInterval.addEventListener(TimerEvent.TIMER, scrubTimeline);
        scrubInterval.start();

        videoThumb.startDrag(false, bounds);


    }
    private function  scrubTimeline(e:TimerEvent):void {
        var amt:Number = Math.floor((videoThumb.x / 340) * duration);
        trace("SCRUB duration: "+duration+" videoThumb.x: "+videoThumb.x+" amt "+amt);

        _ns.seek(amt);

    }

I've noticed that flash player 9 scrubs nice and smooth but in players 10+ I get this no scrub problem.

My fix, was to limit frequency the calls to the seek function to <= 200ms. This fixed scrubbing but is much less smooth as player 9. Perhaps because of the "Flash video can only be advanced by seconds" limitation? I used a timer to tigger the function that calls seek() for the video.

    private var scrubInterval:Timer = new Timer(200);

    private function  videoScrubberTouch():void {
        _ns.pause();

        var bounds:Rectangle = new Rectangle(0,0,340,0);

        scrubInterval.addEventListener(TimerEvent.TIMER, scrubTimeline);
        scrubInterval.start();

        videoThumb.startDrag(false, bounds);


    }
    private function  scrubTimeline(e:TimerEvent):void {
        var amt:Number = Math.floor((videoThumb.x / 340) * duration);
        trace("SCRUB duration: "+duration+" videoThumb.x: "+videoThumb.x+" amt "+amt);

        _ns.seek(amt);

    }
可遇━不可求 2025-01-14 04:57:43

请查看此演示链接(或获取SWF 文件,通过桌面 Flash 在浏览器外进行测试玩家)。
注意:演示需要带有 H.264 视频编解码器和 AAC 或 MP3 音频编解码器的 FLV。

其源代码在这里: Github 链接

在上面的演示中有 (基于字节)搜索和逐帧步进。您要研究的函数主要有:

  • Append_SEEK (位置数量) - 这将以字节为单位到达指定位置并搜索最近的可用关键帧。

  • get_frame_TAG - 这将提取包含一帧数据的标签。音频也可以在帧中,但假设您只有视频。该函数是您调整时间戳的机会。当它运行时,它还会附加标签(因此每个“get_frame_TAG”也是一个“帧步骤”)。

例如:您有一个 25fps 的视频,您希望在 4 秒处播放第三帧...

每个时间戳 1000 毫秒/25 fps = 40 个单位。
因此 4000 毫秒 == 4 秒 + 添加40 x 3rd 帧 == 预期时间戳 4120。

所以获取该帧意味着......首先找到一个关键帧。然后逐步检查每个帧,检查代表您想要的帧的时间戳。如果不是,则将其更改为与最近的关键帧时间戳相同(这会强制 Flash 快进帧以保持同步,因为它假定帧 [具有小于预期时间戳的] 应该在那时播放) 。如果您不喜欢快进的外观,可以在此过程中“隐藏”视频对象。

Please check this Demo link (or get the SWF file to test outside of browser via desktop Flash Player).
Note: Demo requires FLV with H.264 video codec and AAC or MP3 audio codec.

The source code for that is here: Github link

In the above demo there is (bytes-based) seeking and frame by frame stepping. The functions you want to study mainly are:

  • Append_SEEK ( position amount ) - This will got to the specified position in bytes and search for the nearest available keyframe.

  • get_frame_TAG - This will extract a tag holding one frame of data. Audio can be in frames too but lets assume you have video-only. That function is your opportunity to adjust timestamps. When it's run it will also append the tag (so each "get_frame_TAG" is also a "frame step").

For example : You have a 25fps video, you want the third-frame at 4 seconds into playback...

1000 milisecs / 25 fps = 40 units for each timestamp.
So 4000 ms == 4 secs + add the 40 x 3rd frame == an expected timestamp of 4120.

So getting that frame means... First find a keyframe. Then step through each frame checking the timestamps that represent a frame you want. If it isnt then change it to the same as most recent keyframe timestamp (this forces Flash to fast-forward through the frames to keep things in sync as it assumes the frame [with smaller than expected timestamp] should have been played by that time). You can "hide" the video object during this process if you don't like the look of fast-forwarding.

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