How can I use BitmapData.draw with NetStream.appendBytes?
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 func开发者_Go百科tion 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
?
I think another solution is to use _ns.play(path)
and not to use _ns.appendBytes()
.
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
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 :-)
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.
Try placing the Video object in a MovieClip and use bit.draw(_movieclipInstanceName);
instead of the video object. I hope it works.
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
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()
精彩评论