前段时间做AS,对这个语言不熟悉,就会给自己找些奇奇怪怪的需求。
做到一个视频分享的时候竟然感觉需要把视频一帧一帧获取下来然后共享==
坑是踩了但也有所收获,即使这种有趣的需求还是可以解决的
用一个继承 Sprite 的类作为我们的主体
public class VidMap extends Sprite
以下操作都是 VidMap 的成员。创建 connection 什么的就省略了,使用一个 NetStream 播放视频,并且给它增加事件回调,在视频开始播放后,给主体增加一个监听。
stream.addEventListener(NetStatusEvent.NET_STATUS, onVideoLoaded);
video.attachNetStream(stream);
stream.play(fileName);
private function onVideoLoaded (nsLoaded:NetStatusEvent):void
{
trace("onVideoLoaded: "+nsLoaded.info.code);
if (nsLoaded.info.code == "NetStream.Play.Start"){
this.addEventListener(Event.ENTER_FRAME, flipMap);
}
}
注意到视频开始播放后,给 VidMap 添加了对 EVENT.ENTER_FRAME 属性监听。对应的事件为 enterFrame ,这便是视频流的播放头移动事件,播放头进入新帧时调度。如果播放头不移动,或者只有一帧,则会继续以帧速率调度此事件。这样一来,每一帧移入,就会调用 flipMap 回调函数。因此用这个函数来截取每一帧。
public var vidBmpHolder:BitmapData; //在其他地方初始化
private function flipMap(e:Event):void
{
this.vidBmpHolder.draw(video);
}
BitmapData 的 draw 函数就可以把当前视频对象的帧按像素存入 BitmapData 对象。此时的 BitmapData 不仅可以显示出来,也可以作为数据进行网络传输
可以用 Bitmap 的形式显示对象
vidBmp = new Bitmap(vidBmpHolder);
this.addChild(this.vidBmp);
如果只是想要进行视频共享的话,可以考虑使用FMS的组播技术,具体可以参考GroupSpecifier
而这样按帧获取视频的作用常是用于改造视频,如实现滤镜或更改颜色等
参考原文:EDGE