Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

BitmapData.draw() and Video Capture on RTMP - Security sandbox violation.

Compatible ActionScript 2. Cliquer pour en savoir plus sur les compatibilités.Par ekameleon (Marc Alcaraz)

Un petit article rapide pour vous parler d'un problème que j'ai rencontré ces derniers temps en utilisant la classe BitmapData pour capturer le contenu d'un clip contenant un objet Video qui réceptionne un flux vidéo live via la classe NetStream passant par une connexion Flash Media Server.

En gros j'avais besoin de prendre des photos d'un flux vidéo passant par FMS dans une animation contenue dans un page on-line. J'utilise donc pour réaliser cette “prouesse” tout simplement la méthode draw() de la classe BitmapData. Malheureusement à chaque fois j'obtenais une capture de mon clip avec une image toute blanche alors qu'en testant dans Flash je n'avais aucun problème pour réaliser cette capture.

En cherchant dans Google je suis rapidement tombé sur l'article de Kiroukou traitant de sa classe DistortImage 2.0 qui permet de déformer une image en ActionScript. J'ai ainsi tout de suite pu trouvé la nature de mon problème avec le commentaire éclairé de Riggs qui indique qu'il obtient dans ses tests un message d'erreur de type “violation de la sécurité sandbox”.

Il m'a suffit à ce moment là de lancer une nouvelle recherche dans Google pour trouver ma solution sur le blog de Keun Lee dans un article intitulé : Flex 2 VideoDisplay + Security sandbox violation : BitmapData.draw on RTMP

Voyons donc maintenant la solution à cet épineux problème avec un petit bout de code AS2 :

import flash.display.BitmapData ;
 
// The NetConnection instance.
var nc:NetConnection = new NetConnection() ;
nc.onStatus = function( oInfo:Object )
{
	trace( "-> " + oInfo.code ) ;	
}
 
nc.connect( "rtmp://localhost/test_video" ) ;
 
// The NetStream to publish the Camera
var nsOut:NetStream = new NetStream( nc ) ;
nsOut.attachVideo( Camera.get() ) ;
nsOut.publish("test_live") ;
 
// The NetStream instance to play the external Video live stream.
var nsIn:NetStream = new NetStream( nc ) ;
nsIn.play("test_live", -1) ;
 
// The video object in the movieclip with the name "container"
var video:Video = container.video ;
video.attachVideo( nsIn ) ;
 
// The BitmapData instance.
var bmp:BitmapData = new BitmapData(container._width , container._height) ;
 
Key.addListener(this) ;
 
this.onKeyDown = function()
{
 
	video.attachVideo( null ) ;
 
	bmp.draw(container) ;
 
	video.attachVideo( nsIn ) ;
 
	var capture:MovieClip = createEmptyMovieClip("capture", 10) ;
	capture._x = container._x + container._width + 10 ;
	capture._y = container._y ;
 
	capture.attachBitmap( bmp, 1 ) ;
 
}

Le bout de code le plus important dans tout le script ci-dessus c'est la partie contenue dans la fonction callback onKeyDown :

video.attachVideo( null ) ;
bmp.draw(container) ;
video.attachVideo( nsIn ) ;

Comme vous pouvez le voir, la technique est simplement d'arrêter la diffusion du flux vidéo pendant la capture et ensuite de la relancer après l'appel de la fonction draw(). La solution est donc très simple… il fallait juste y penser.

Tutorial ALCARAZ Marc (eKameleon) 2007 - Vous pouvez consulter ce tutorial et des commentaires sur mon blog.