Papervision3Dで背景抜きFLV再生
Papervision3DのVideoStreamMaterialでFLV(AfterEffectsで背景抜きしたFLV)を再生させようと思ったら、
素直に背景が透明な状態で表示してくれなかったのでメモ。(2008/5/15 17:13 現在の最新リビジョン557)
実際の表示結果としては、背景部分がVideoStreamMaterial.fillColorで塗り潰されてしまう。
VideoStreamMaterialでは、生成したVideoオブジェクトを絶えずBitmapDataにdrawする事で、あたかも3D空間内で動画が再生されているように表現している。
ここで、
VideoStreamMaterial.as(一部抜粋)
public override function updateBitmap ():void { try { // copies the scale properties of the video var myMatrix:Matrix = new Matrix(); myMatrix.scale( this.video.scaleX, this.video.scaleY ); // Fills the rectangle with a background color this.bitmap.fillRect ( this.bitmap.rect, this.fillColor ); // Due to security reasons the BitmapData cannot access RTMP content like a NetStream using a FMS server. // The next three lines are a simple but effective workaround to get pass Flash its security sandbox. //this.video.attachNetStream ( null ); this.bitmap.draw( this.video, myMatrix, this.video.transform.colorTransform ); this.video.attachNetStream ( this.stream ); }catch(e:Error) { // trace(e); } }
このdrawしてる部分。
自身のプロパティとしてBitmapDataを保持している。
では、このBitmapDataはいつ生成されているのか。
それは、継承元のMovieMaterialの下記の部分
(createBitmapFromSpriteメソッドでもbitmapをセットしていますが、今回問題になった処理ではないので。)
MovieMaterial.as(一部抜粋)
protected function initBitmap( asset:DisplayObject ):void { // Cleanup previous bitmap if needed if( bitmap ) bitmap.dispose(); // Create new bitmap bitmap = new BitmapData( asset.width, asset.height, this.movieTransparent ); }
ここで、「this.movieTransparent」。
これがtrueに設定されていないと、当たり前のように透明にはなりませんよねー。
じゃぁ、VideoStreamMaterialで、どのタイミングで設定できるのか?
設定するとなると、皆様はきっと下記のようにしますよね。
少なくとも、berianはそうしたくなります。
var videoStreamMaterial:VideoStreamMaterial = new VideoStreamMaterial(video, stream); videoStreamMaterial.movieTransparent = true;
だがしかし!!
だがしかしなのですYO!!
隊長!!
VideoStreamMaterialのインスタンスが生成された時点で、bitmapプロパティは作成済みであります!!
現状のVideoStreamMaterialでは、外から設定出来るタイミングが・・ありません。。。
残念だ・・。。
本当に残念だ・・。。
なので、VideoStreamMaterialのコンストラクタ引数に「transparent」を追加して、
「super」の引数にそれを追加してあげました。
以下、修正したVideoStreamMaterialコンストラクタ。
VideoStreamMaterial.as(一部抜粋)
public function VideoStreamMaterial ( video:Video, stream:NetStream, transparent:Boolean = false ) { // store the values this.stream = stream; this.video = video; animated = true; // init the material with a listener for the NS object initMaterial ( video, stream ); /** * 実は、super(MovieMaterialコンストラクタ)の引数にはtransparentがあります。。 * * public function MovieMaterial( movieAsset:DiplayObject=null, transparent:Boolean=false, animated:Boolean=false ) * { * ・ * ・ * ・ * } */ super ( DisplayObject(video), transparent ); }
これで背景抜きFLVが、めでたく表示されました。
本来はこうあるべきですよね!?
透過させると、何か他の問題が出てくるのかな??(もちろん負荷的な事以外に)
まぁ、もっと良い方法があれば、それに越した事はありませんが、とりあえずこれでw
でも、GreatWhiteでもこの部分は、今のところ(リビジョン557)特に変更ないしなー・・
とりあえず、試しにissueしとこうかな。