如何在使用NetStream.appendBytes时使用BitmapData.draw?

8
我正在使用NetStream.appendBytes()在Adobe AIR中播放本地视频(没有涉及服务器)。我想使用BitmapData.draw()来截取视频输出的图片,但是我遇到了以下错误:
Error #2123: Security sandbox violation: BitmapData.draw: cannot access null. No policy files granted access.
这里是一些示例代码:
package
{
    import flash.display.Sprite;
    import flash.filesystem.File;
    import flash.filesystem.FileMode;
    import flash.filesystem.FileStream;
    import flash.media.Video;
    import flash.net.NetConnection;
    import flash.net.NetStream;
    import flash.net.NetStreamAppendBytesAction;
    import flash.utils.ByteArray;
    import flash.display.BitmapData;

    class ByteArrayPlayer extends Sprite
    {
        private var _ns:NetStream;
        private var _nc:NetConnection;
        private var _video:Video;

        public function playVideo(path:String):void
        {
            _nc = new NetConnection();
            _nc.connect(null);
            _ns = new NetStream(_nc);

            _video = new Video();
            addChild(_video);
            _video.attachNetStream(_ns);

            _ns.play(null);
            _ns.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);

            var file:File = new File(path);
            var fileStream:FileStream = new FileStream();
            fileStream.open(file, FileMode.READ);

            var bytes:ByteArray = new ByteArray();

            fileStream.readBytes(bytes);

            _ns.appendBytes(bytes);
        }


        public function getImage(video:Video):BitmapData
        {
            var bit:BitmapData = new BitmapData(_video.width, _video.height);
            bit.draw(_video);            //This will cause the error
            return bit;
        }
    }
}

这只是一个用于解释的样本代码。在播放视频时调用getImage方法会导致错误。错误提到找不到策略文件。由于文件是本地加载的,因此实际上没有地方放置策略文件。是否需要设置任何策略设置或者当使用appendBytes时BitmapData.draw功能不可用?

我和你当时的情况完全一样,只不过文件是来自远程位置。我使用urlstream对象将数据拉入,并根据需要修改并附加本地标头...所有操作都成功了,但在尝试捕获之前,基本上是自己给自己惹麻烦了。你能克服这些问题吗?或者对如何在远程服务器上完成此操作有什么想法吗?我目前正在下载FMS 4.5,看看是否可以解决这个问题。文档也指向Flash Access的方向... - stat
经过漫长的一个晚上,我终于发现在使用Http动态流媒体(HDS)时,使用appendBytes()方法无法对解码后的视频进行像素级操作。唯一的可能性是将第二个字节流黑客入f4f文件中,但这完全取决于正在执行的检查以及AVM是否会忽略appendBytes流模型中的所有策略标志... - stat
你有没有想到解决这个问题的办法?我也遇到了同样的问题。 - WesleyJohnson
7个回答

1

我认为另一个解决方案是使用_ns.play(path)而不是使用_ns.appendBytes()


这是正确的,但是这样一来你就无法再访问到我这种情况下所需的字节了。 - Aaron
这个也不行,我正在使用这种方法在iOS上播放本地视频。不幸的是,我仍然收到错误信息。 - Drahcir

0

在调用play()函数之前,尝试设置NetStream.checkPolicyFile = true

像这样:

_ns.checkPolicyFile = true;
_ns.play(null);

checkPolicyFile 标志的作用是告诉宿主 SWF 从已加载的 SWF 服务器加载策略文件。如果您在加载时没有指定该标志,则在尝试通过 BitmapData.draw() 从加载的流获取像素数据时,将会收到一个 SecurityError

Adobe 资源链接:http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#checkPolicyFile


这并没有帮助。问题在于没有服务器,因此无处可加载策略文件。该文件正在本地加载(甚至可能是离线状态的机器)。 - Aaron
好的,我的错。你是通过RTMFP流传视频吗?如果是这种情况,我找到了一个你可能会感兴趣的帖子。http://forums.adobe.com/thread/16862 - Tjofras
谢谢提供的链接。然而,NetStream.appendBytes方法只适用于flv格式。我基本上通过FileStream从磁盘读取一个flv文件,稍作修改后再使用appendBytes()将字节发送到NetStream中。 - Aaron

0

我有一个解决方案,可以消除尝试绘制netstream.appendByte()内容时出现的沙盒错误。

SWF检索到沙箱,因为它正在查找由您指定的地址的跨域文件:netstream.play(null)。他正在寻找不存在的东西。

好吧,解决方案是播放一个假视频网址,例如“netstream.play(http://myserv.com/video.flv)”,其中包含真正的跨域文件,之后,您只需使用appendBytes函数加载所需的视频即可。

SWF被愚弄了!

听起来很奇怪,但对我有效 :-)


谢谢,我会试试这个。不过,我需要一个离线可用的解决方案。为了使这种方法正常工作,可能需要一些本地服务器的支持。 - Aaron
1
这样做是不行的:文档明确指出,只有在使用null调用ns.play()时才能调用appendBytes()。否则,会收到错误消息。 - David Hanak

0

我知道这个问题很老了...但它仍然是一个我刚刚面临的问题,我知道其他人也会遇到...所以我想发布另一个Stack问题的链接,在那里我报告了Adobe的错误和解决方法。

在重复的Stack问题上解决错误的方法


0

如果服务器端设置中未将StreamVideoSampleAccess或StreamAudioSampleAccess设置为true或设置为StreamVideoSampleAccess/StramVideoSampleAccess,则无法从rtmp流中拍摄视频或音频快照。我还没有发现在没有访问FMS服务器端的情况下完成此操作的方法。


这是一个关于此的Adobe文档链接:http://help.adobe.com/en_US/FlashMediaServer/3.5_SS_ASD/WS5b3ccc516d4fbf351e63e3d11a11afc95e-7ec3.html#WS5b3ccc516d4fbf351e63e3d11a11afc95e-7fcb - bolnad
1
这不是来自服务器的流式数据。这些数据来自用户机器上的本地文件。 - Aaron

0
尝试将Video对象放置在MovieClip中,并使用bit.draw(_movieclipInstanceName);而不是视频对象。希望它能起作用。

-1

看起来你正在尝试在未加载视频或NetStream对象为空时调用BitmapData.draw()方法。

可能的解决方法:在调用draw()之前等待NetStream.Buffer.Full NetStatus被分派。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接