我参与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无法实现?当我尝试它时,没有任何作用。
有什么建议,如何解决这个问题?
问候&谢谢! 尼古拉斯
答案 0 :(得分:1)
除非您拥有托管视频的Flash Media Server,否则Flash视频只能提前几秒。从技术上讲,这意味着你可以让它按照Air的预期工作,但是,视频必须是流媒体(愚蠢的adobe ......)。
您有两种选择:
1)将素材导入为动画片段。 Flash IDE有一个向导,如果您只在非FlashIDE环境中进行开发,则可以转换并导出为外部资源,如SWF或SWC。然后将其嵌入或运行时加载到您的应用程序中,使您可以访问MovieClip的每帧可执行方法。然而,这确实伴随着一些音频同步问题(iirc)。此外,向后擦洗不是MC的强项。
2)编写自己的视频对象,加载图像序列并按顺序显示每个帧。您必须设置自己的音频同步功能,但除了FLVComponent或NetStream之外,它可能是最直接的解决方案。
答案 1 :(得分:1)
我注意到flash player 9擦洗得很好而且很流畅但是在10+以上的玩家中我没有擦洗问题。
我的修复是将搜索功能的调用频率限制为< = 200ms。这种固定的擦洗方式却不如播放器9那么顺畅。也许是因为“Flash视频只能提前几秒”限制?我用一个计时器来调用为视频调用seek()的函数。
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);
}
答案 2 :(得分:0)
请检查此Demo link(或通过桌面Flash Player获取the SWF file以在浏览器外进行测试。)
注意: Demo需要FLV和H.264视频编解码器以及AAC或MP3音频编解码器。
源代码在这里:Github link
在上面的演示中,有(基于字节的)搜索和逐帧步进。您想要学习的功能主要是:
Append_SEEK (位置金额) - 这将以字节为单位到达指定位置,并搜索最近的可用关键帧。
get_frame_TAG - 这将提取包含一帧数据的标记。音频也可以在帧中,但我们假设您只有视频。该功能是您调整时间戳的机会。当它运行时,它还会附加标签(因此每个“get_frame_TAG”也是一个“帧步”)。
例如:你有一个25fps的视频,你希望第三帧在4秒内播放...
1000 milisecs / 25 fps =每个时间戳40个单位。
所以4000 ms == 4秒+添加40 x 3帧==预期时间戳4120.
所以获得该框架意味着......首先找到一个关键帧。然后逐步检查每个帧,检查表示所需帧的时间戳。如果不是,则将其更改为与最近的关键帧时间戳相同(这会强制Flash在帧中快进以保持同步,因为它假设帧[具有小于预期的时间戳]应该在该时间播放) 。如果您不喜欢快进的外观,可以在此过程中“隐藏”视频对象。