How can I use BitmapData.draw with NetStream.appendBytes?

5.1k views Asked by At

I am using NetStream.appendBytes() to play a local video (no server involved) in Adobe AIR. I would like to use BitmapData.draw() to take a picture of the video output, but I am getting this error:

Error #2123: Security sandbox violation: BitmapData.draw: cannot access null. No policy files granted access.

Here is some sample code:

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;
        }
    }
}

This is only sample code use for an explanation. The error would happen when calling the getImage method while the video is playing. The error mentions a policy file not found. Since the file is loaded locally there isn't really a place to put a policy file. Is there a policy setting somewhere that needs to be set or is the BitmapData.draw feature just not available when using appendBytes?

7

There are 7 answers

0
FlashDictionary On

It looks like you are trying to call the BitmapData.draw() method on a video that isn't loaded, or when the NetStream object is null.

possible fix: wait until the NetStream.Buffer.Full NetStatus is dispatched before calling draw()

3
Tjofras On

Try set NetStream.checkPolicyFile = true before you call the play() function.

Like this:

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

What the checkPolicyFile flag does is that it tells the host swf to load a policy file from the loaded swf's server. If you haven't specified that flag at loading time you will recieve a SecurityError when you try to get pixel data from the loaded stream through BitmapData.draw().

Link to Adobe resource: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#checkPolicyFile

2
bolnad On

You can't take a snapshot of video or audio from an rtmp stream unless the server side settings called StreamVideoSampleAccess or StreamAudioSampleAccess is set to true or set like this StreamVideoSampleAccess/StramVideoSampleAccess. I haven't discovered a way to do this without having access to the FMS server side.

2
yukoba On

I think another solution is to use _ns.play(path) and not to use _ns.appendBytes().

0
Jason Reeves On

I know this question is really old... but it is still a problem that I just faced and I know others will too... So I wanted to post the link to the other Stack question where I posted the bug at Adobe and the workaround to get it to work.

Workaround for bug on a duplicate Stack Question

2
Pixel Expander On

I’ve a solution to get rid of the sandbox error when trying to draw a netstream.appendByte() content.

The SWF retrieves a sandbox because he is looking for a crossdomain file at the address specified by you :netstream.play(null). He’s looking for something that doesnt exist.

Well, the solution is to play a fake video url, like “netstream.play(http://myserv.com/video.flv)” with a genuine crossdomain file on it, and after that, you just have to load the video you want thanks to the appendBytes function.

The SWF is fooled!

As strange as it sounds, it work for me :-)

0
KielSoft On

Try placing the Video object in a MovieClip and use bit.draw(_movieclipInstanceName); instead of the video object. I hope it works.