使用Nestream AppendBytes(AS3)解码视频中的位图?

时间:2014-12-13 22:46:56

标签: actionscript-3 video video-processing netstream

我想知道在 Flash 中处理NetStream.appendBytes的人是否知道如何从解码的视频帧中获取bitmapData?我已经查看了 this question ,但这是从3年前开始的,最近的评论/回答似乎已经消失了。 2014年有人设法将这些字节转换为位图吗?我正在使用Flash Player 11.8,这不是桌面/ AIR应用程序。

在下图中,我可以执行 1) 2)步骤,但第3步 < / p>

enter image description here

问题是简单地使用bitmapdata.draw(video_container);不起作用,但即使我使用byteArray(来自与SWF相同的目录中的本地视频文件),它也会引发策略文件错误。甚至没有涉及互联网,但Flash告诉我"No Policy File granted permission from the server"或这样的废话。我认为这个错误只是一种直言不讳的b saying saying saying saying saying You You You You You You You You You You You You You You You You You You You .. .. .. ..

我尝试过尝试安抚此Crossdomain.xml问题并查看所有已知的安全/域设置。我得出结论,错误不是问题,而是问题的副作用。这里的问题是:Flash Player知道SWF的位置以及它本地的任何文件。将String作为URL等传递时可以,但当Netstream数据不是SWF域的本地数据时,则会成为策略文件问题。问题是我的数据在内存中不在像SWF这样的文件夹中,因此不能全部bitmapData.draw,因为它不能&#34;警察&#34;一个字节数组,任何已知的修复程序? ...(我甚至不能说出我真正想要使用的单词)。

我想要实现的目标:基本上使用Netstream作为H.263或H.264图像解码器的方式Loader是JPEG到位图解码器或LoadCompressed..是MP3到PCM的解码器。您知道,访问原始材质(此处为RGB像素),应用一些效果函数,然后发送到屏幕或保存到磁盘。

3 个答案:

答案 0 :(得分:1)

要从视频流中拍摄快照,我们不需要NetStream.appendBytes将数据注入NetStream对象。

为此我们可以使用BitmapData.draw,它有一些安全限制。这就是为什么我们很多时候会遇到闪存安全错误。关于这一点,Adobe说:

  

... Flash Player 9.0.115.0及更高版本和Adobe AIR中的RTMP支持此方法。您可以在服务器端脚本中控制对Flash Media Server上的流的访问。有关详细信息,请参阅Adobe Flash Media Server的服务器端ActionScript语言参考中的Client.audioSampleAccess和Client.videoSampleAccess属性。如果源对象和(在Sprite或MovieClip对象的情况下)其所有子对象不是来自同一个domain作为调用者,或者不在调用者可以通过调用Security.allowDomain()方法访问的内容中,对draw()的调用会引发SecurityError异常。此限制不适用于应用程序安全沙箱.... “。

对于跨域文件创建和AMS服务器的其他一些安全配置,您可以查看以下帖子:Crossdomain Video Snapshot - Fixing BitmapData.draw() Security Sandbox Violation

在允许我们的脚本从我们的视频流中获取数据后,我们可以传递给代码。

我编写了一个播放视频流(rtmp或http)的代码并拍摄快照以在舞台中显示它或在应用pixel effect后将其另存为文件:

const server:String = null; //'rtmp://localhost/vod'
const stream:String = 'stream'; // 'mp4:big_buck_bunny_480p_h264.mp4';
var nc:NetConnection;
var ns:NetStream;
var video:Video;
const jpg_quality:int = 80;
const px_size:int = 10;

nc = new NetConnection();
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, function(e:AsyncErrorEvent):void{});
nc.addEventListener(NetStatusEvent.NET_STATUS, function(e:NetStatusEvent):void{
    if(e.info.code == 'NetConnection.Connect.Success'){
        ns = new NetStream(nc);
        ns.addEventListener(NetStatusEvent.NET_STATUS, function(e:NetStatusEvent):void{});
        ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, function(e:AsyncErrorEvent):void{});
        video = new Video(320, 180);
        video.x = video.y = 10;
        video.attachNetStream(ns);
        addChild(video);
        ns.play(stream);
    }
})
nc.connect(server);

btn_show.addEventListener(
    MouseEvent.CLICK,
    function(e:MouseEvent): void{
        var bmp:Bitmap = pixelate(video, px_size);
            bmp.x = 10;
            bmp.y = 220;
        addChild(bmp);
    }
)
btn_save.addEventListener(
    MouseEvent.CLICK,
    function(e:MouseEvent): void{

        var bmp:Bitmap = pixelate(video, px_size);

        var jpg_encoder:JPGEncoder = new JPGEncoder(80);
        var jpg_stream:ByteArray = jpg_encoder.encode(bmp.bitmapData);

        var file:FileReference = new FileReference();
            file.save(jpg_stream, 'snapshot_'+int(ns.time)+'.jpg');

    }
)

function pixelate(target:DisplayObject, px_size:uint):Bitmap {

    var i:uint, j:uint = 0;
    var s:uint = px_size;
    var d:DisplayObject = target;

    var w:uint = d.width;
    var h:uint = d.height;

    var bmd_src:BitmapData = new BitmapData(w, h);
        bmd_src.draw(d);

    var bmd_final:BitmapData = new BitmapData(w, h);

    var rec:Rectangle = new Rectangle();
        rec.width = rec.height = s;

    for (i = 0; i < w; i += s){
        for (j = 0; j < h; j += s){
            rec.x = i;
            rec.y = j;                  
            bmd_final.fillRect(rec, bmd_src.getPixel32(i, j));
        }
    }

    bmd_src.dispose();
    bmd_src = null;

    return new Bitmap(bmd_final);
}

当然,这只是一个显示从视频流中获取快照的方式的简单示例,您应该根据自己的需要进行调整和改进......

我希望所有这些都可以帮到你。

答案 1 :(得分:1)

我知道这个问题已经有几个月了,但我想发布正确的答案(因为我也遇到了这个问题,而其他问题也是如此)。

正确答案:

这是一个已经在土坯上开放了差不多2年的错误

Link to the bug on Adobe

解决问题直到错误得到修复(我正在使用它并且效果很好):

Workaround using Sprite and graphics

答案 2 :(得分:1)

我知道这有点晚了,但我想我找到了解决问题的方法。

因此,为避免安全沙箱违规#2123错误,您只需这样做:

// ...

net_stream.play(null);

net_stream.play('');

// ...

希望可以提供帮助。