How can I use BitmapData.draw with NetStream.appendBytes?
Asked Answered
M

7

8

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?

Moralist answered 9/4, 2011 at 18:43 Comment(3)
I'm in the exact same boat as you were although, files are coming from a remote location. I was using the urlstream object to pull the data in, and append as desired wile modifying, locally, the headers...all successful, but before trying to catpure. Essentially shot myself in the foot. Were you able to overcome the issues, or have any thoughts on how to accomplish this with a remote server? I'm currently pulling down FMS 4.5 to see if that solves the issue. Docs also point in the direction of Flash Access...Pronghorn
After a very long night, I have simply discovered that with Http Dynamic Streaming (HDS), the use of the appendBytes() method, that there is no possible way of performing pixel level manipulation on the decoded video. One possibility left is hacking a secondary bytestream into the f4f files, but that really depends on what checks are being performed and if the AVM simply ignores all policy flags in the appendBytes streaming model...Pronghorn
Did you ever come up with a solution for this? I'm running into the same issue.Fervidor
M
1

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

Muldon answered 11/8, 2011 at 2:18 Comment(2)
That is true but then you no longer have access to the bytes which is needed in my case.Moralist
This doesn't work either, I'm playing local video on iOS with this method. Unfortunately I still get the error.Slump
C
0

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

Collide answered 9/4, 2011 at 18:52 Comment(3)
This doesn't help. The problem is that there is no server so there is nowhere to load the policy file from. The file is being loaded locally (the machine may even be offline).Moralist
Ok, my bad. Are you streaming the video through RTMFP? In that case I found thread that you might find interesting. forums.adobe.com/thread/16862Collide
Thanks for the link. However, the NetStream.appendBytes method only works with the flv format. I'm basically reading an flv file from disk with a FileStream, changing it a bit then sending the bytes to the NetStream with appendBytes().Moralist
S
0

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 :-)

Susurrate answered 1/6, 2011 at 14:7 Comment(2)
Thanks I'll play with this. However, I need a solution that will work offline. To get this method to work properly some sort of local server would probably be needed.Moralist
This does not work: the documentation clearly states that appendBytes() can only be called when ns.play() is called with null. If done otherwise, I get an error message.Val
W
0

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.

Welter answered 5/8, 2011 at 18:33 Comment(2)
here is a link to the adobe documentation about it help.adobe.com/en_US/FlashMediaServer/3.5_SS_ASD/…Welter
This is not an ramp stream from a server. This data is coming from a local file on the users machine.Moralist
F
0

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

Flyblown answered 13/3, 2012 at 16:21 Comment(0)
M
0

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

Meditate answered 26/3, 2015 at 16:33 Comment(0)
P
-1

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()

Preexist answered 23/5, 2012 at 21:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.