Flash: How to add Video texture in Papervision 3D
April 15th, 2007 by LuisI have received loads of requests asking how to diaplay a FLV as a texture in Papervision 3D using AS3.
The concept is very basic, you need to snapshot the video object where the video is running using BitmapData.draw(), and then set the result in the texture, and the rest is done by the 3D engine. ( See demo here)
Notice in the code below a small hack by Chris Chen to be able to draw a media source in AS3 bypassing security errors.
Code Updated for latest Flash player and PV3D GreatWhite:
Actionscript:
- package com.lessrain.projects.luis.pv3dWhite.video3d
- {
- import flash.display.BitmapData;
- import flash.display.Sprite;
- import flash.events.AsyncErrorEvent;
- import flash.events.Event;
- import flash.geom.Point;
- import flash.geom.Rectangle;
- import flash.media.Video;
- import flash.net.NetConnection;
- import flash.net.NetStream;
- import flash.system.Security;
- import org.papervision3d.cameras.Camera3D;
- import org.papervision3d.materials.BitmapMaterial;
- import org.papervision3d.objects.DisplayObject3D;
- import org.papervision3d.objects.primitives.Plane;
- import org.papervision3d.render.BasicRenderEngine;
- import org.papervision3d.scenes.Scene3D;
- import org.papervision3d.view.Viewport3D;
- /**
- * @author Luis Martinez, Less Rain (luis@lessrain.com)
- */
- public class Video3D
- {
- private var _target : Sprite;
- private var _container : Sprite;
- private var _viewport : Viewport3D;
- private var _renderer : BasicRenderEngine;
- private var _scene3D : Scene3D;
- private var _camera : Camera3D;
- private var _rootNode : DisplayObject3D;
- private var _connection : NetConnection;
- private var _stream : NetStream;
- private var _video : Video;
- private var _videoWidth : Number = 320;
- private var _videoHeight : Number = 240;
- private var _videoTexture : BitmapData;
- private var _planeTexture1 : BitmapData;
- private var _planeTexture2 : BitmapData;
- private var _srcRect1 : Rectangle;
- private var _srcRect2 : Rectangle;
- private var _basePoint : Point = new Point(0, 0);
- public function Video3D()
- {
- Security.loadPolicyFile("http://www.yourdomain.com/cross-domain.xml");
- }
- public function initialize() : void
- {
- _srcRect1 = new Rectangle(0, 0, _videoWidth>> 1, _videoHeight);
- _srcRect2 = new Rectangle(_videoWidth>> 1, 0, _videoWidth>> 1, _videoHeight);
- _videoTexture = new BitmapData(_videoWidth, _videoHeight);
- _planeTexture1 = new BitmapData(_videoWidth>> 1, _videoHeight);
- _planeTexture2 = new BitmapData(_videoWidth>> 1, _videoHeight);
- initialize3D();
- loadVideo();
- createPlanes();
- _container.addEventListener(Event.ENTER_FRAME, loop3D);
- }
- private function initialize3D() : void
- {
- _container = new Sprite();
- _target.addChild(_container);
- _viewport = new Viewport3D(990, 600, false, false);
- _container.addChild(_viewport);
- _renderer = new BasicRenderEngine();
- _scene3D = new Scene3D();
- _camera = new Camera3D();
- _camera.zoom = 8;
- _camera.focus = 200;
- _rootNode = new DisplayObject3D();
- _scene3D.addChild(_rootNode);
- }
- private function loadVideo() : void
- {
- var customClient : Object = new Object();
- customClient["onCuePoint"] = cuePointHandler;
- customClient["onMetaData"] = metaDataHandler;
- _connection = new NetConnection();
- _connection.connect(null);
- _stream = new NetStream(_connection);
- _stream.checkPolicyFile = true;
- _stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
- _stream.client = customClient;
- _video = new Video(_videoWidth, _videoHeight);
- _video.attachNetStream(_stream);
- _stream.play('http://www.blog.lessrain.com/wp-content/upload/papervideo/myvideo.flv');
- }
- private function cuePointHandler(infoObject_ : Object) : void
- {
- }
- private function metaDataHandler(infoObject_ : Object) : void
- {
- }
- private function asyncErrorHandler(event : AsyncErrorEvent) : void
- {
- }
- private function createPlanes() : void
- {
- var material1 : BitmapMaterial = new BitmapMaterial(_planeTexture1);
- material1.oneSide = false;
- var plane1 : DisplayObject3D = _rootNode.addChild(new Plane(material1, _videoWidth>> 1, _videoHeight, 4, 4), "plane1");
- plane1.x = -_videoWidth>> 2;
- var material2 : BitmapMaterial = new BitmapMaterial(_planeTexture2);
- material2.oneSide = false;
- var plane2 : DisplayObject3D = _rootNode.addChild(new Plane(material2, _videoWidth>> 1, _videoHeight, 4, 4), "plane2");
- plane2.z = _videoWidth>> 2;
- plane2.rotationY = -90;
- }
- private function loop3D(event_ : Event) : void
- {
- _rootNode.rotationY += ((-_container.mouseX * 0.5) - _rootNode.rotationY) / 10;
- _rootNode.rotationX += ((-_container.mouseY * 0.5) - _rootNode.rotationX) / 10;
- _videoTexture.draw(_video);
- _planeTexture1.copyPixels(_videoTexture, _srcRect1, _basePoint);
- _planeTexture2.copyPixels(_videoTexture, _srcRect2, _basePoint);
- _renderer.renderScene(_scene3D, _camera, _viewport);
- }
- public function get target() : Sprite
- {
- return _target;
- }
- public function set target(target_ : Sprite) : void
- {
- _target = target_;
- }
- }
- }




March 8th, 2007 at 5:12 am
that’s cool indeed,thx for sharing! ;D
March 12th, 2007 at 12:50 pm
Is this possible within the AS2 version of Papervision3d too?
March 13th, 2007 at 11:43 am
Yes it does work in AS2 too:
http://www.blog.lessrain.com/?p=525
March 17th, 2007 at 12:29 am
hows the song called?
March 17th, 2007 at 11:29 am
My friends kill my folks by Herman Düne,
my friends kill my folks in front of me
my friends kill my folks and they’re not even sorry
they say the line is thick between crying and crying
they say the line is thick between dying and dying
i hardly ever listen and i don’t steer
but i do hear and i often peer
at the features of men through my glasses
through my pictures and through their faces
it’s the only thing that keeps me awake
through some nights and all kinds of mornings
when you hate yourself it’s the mirror you break
you won’t find ears that fit your earrings
i once was used to killing and double talking
i wasn’t writing then, not even smoking
so i know how it feels to hate your own guts
and rest your sick ego on ifs and buts
and i don’t see a line and i don’t give a damn
i see a surface and i feel its thickness
and what i see from where i am
is so obvious not seeing it is a sickness
March 20th, 2007 at 4:13 pm
Cool tune! Speed runs well too.
April 8th, 2007 at 6:30 pm
nice example!
to make the sample code work with any kind of movie you have to change the line:
_video = new Video(); to
_video = new Video(videoWidth, _videoHeight);
as the Video object doesn’t resize to the video dimensions but stays with the default values (320×240).
April 30th, 2007 at 1:28 pm
[…] ervision home - OS Flash Update How to add Video texture in Papervision 3D: http://www.blog.lessrain.com/?p=552 Best Regards, CP 2 Comments » RSS […]
April 30th, 2007 at 2:43 pm
[…] els and texturing; - Papervision home - OS Flash Update How to add Video texture in Papervision 3D: http://www.blog.lessrain.com/?p=552 Best Regards, CP This entry was posted on Monday, April 30th, 2007 at 4:43 am […]
May 31st, 2007 at 7:51 pm
hey,
this is really tight.
im just getting into flex and pv3d, thanx a lot for this tutorial.
i made a demo version (http://the.fontvir.us/pv3d/vidCube/)
the code works, but i keep getting an error
from the null connection in the loadVideo() function…
_connection.connect(null);
Error #2044: Unhandled AsyncErrorEvent:. text=Error #2095: flash.net.NetStream was unable to invoke callback onMetaData. error=ReferenceError: Error #1069: Property onMetaData not found on flash.net.NetStream and there is no default value.
at main/::loadVideo()
at main$iinit()
i know is is already a h4x but have any ideas?
July 16th, 2007 at 8:45 pm
I tried compiling and running this through Flash. The plane rendering is working and I can hear the video playing but it’s not showing up on the plane.
July 19th, 2007 at 10:57 pm
Buddy ur code ” no work” fix ur
Error #2044: Unhandled AsyncErrorEvent:. text=Error #2095: flash.net.NetStream was unable to invoke callback onMetaData. error=ReferenceError: Error #1069: Property onMetaData not found on flash.net.NetStream and there is no default value.
at main/::loadVideo()
at main$iinit()
then repost.
Thanks
July 20th, 2007 at 9:27 am
It works for me in Flex builder 2 and FLex Builder 3 with the sample video I have. The error you are getting is probably becuase your flv has cue points or other kind of metadata and the asyncError is dispatched and informs you that the NetStream class was unable to invoke the callback onMetaData and onCuePoint. I’m not taking care of this in my code.
One of the easiest ways to handle the asyncError event dispatched by the NetStream object is to listen for the event using the addEventListener() method. This allows you to either handle or ignore the event. ( I have just added a listener for the asyncError in the loadVideo method in the code above).
stream.addEventListener(AsyncErrorEvent.ASYNCERROR, asyncErrorHandler);
private function asyncErrorHandler(event:AsyncErrorEvent):void {}
Try again…
July 20th, 2007 at 9:36 am
Another option if you don’t want to get the error and you want to read the metadata or the cuepoints is to add something like this:
var customClient:Object = new Object();
customClient.onCuePoint = cuePointHandler;
customClient.onMetaData = metaDataHandler;
…
_stream.client = customClient;
…
private function cuePointHandler(infoObject:Object):void
{
trace(”cuePoint”);
}
private function metaDataHandler(infoObject:Object):void
{
trace(”metaData”);
}
Is up to you…
July 20th, 2007 at 7:39 pm
I just tried building and running your example. I can hear the sound but the video is just a white (bent) box. I’m using the latest Flash Player 9.0.47 and the 1.5 version of PaperVision and I’ve tried it on both Mac and Windows. Any ideas?
July 21st, 2007 at 12:19 am
Hi I have the same prob as B… The video texture is not visible but the sound is working… Anyone an idea???
July 23rd, 2007 at 1:22 pm
Hi,
I had the same problem as Rick and irie. After some struggling (i.e. a lot), I was able to solve this by setting material1 and material2 as global variables, and setting their bitmap property to _planeTexture1 and _planeTexture2 in the loop3D function just before the scene rendering as follows:
//added code
material1.bitmap=planeTexture1;
material2.bitmap=planeTexture2;
//end added code
Let me know if that helps.
July 23rd, 2007 at 6:41 pm
That worked — thanks.
I made some other simplifications — see the ‘loop3D’ function, below.
Here’s my final code:
package
{
import flash.display.;
import flash.events.;
import flash.media.Video;
import flash.net.;
import flash.geom.;
//You need papervision 3D framework
import org.papervision3d.scenes.;
import org.papervision3d.cameras.;
import org.papervision3d.objects.;
import org.papervision3d.materials.;
}
August 14th, 2007 at 6:07 am
I just tried building and running your example. I can hear the sound but the video is just a white (bent) box.
August 23rd, 2007 at 2:35 pm
Thank you rick, that works perfectly for me. impressive!
October 13th, 2007 at 4:24 pm
Working fine but how would you make the planes clickable? Any ideas?
October 22nd, 2007 at 7:27 pm
I like, it is very nice
I can see almost endless possibilities with this tool.
October 22nd, 2007 at 9:23 pm
[…] This is not something which I made from scratch, however during reading this guys stuff I have now made myself familiar with: Loading video into Flex. Strea […]
November 2nd, 2007 at 3:52 pm
“Flash: How to add Video texture in Papervision 3D” - Good work. Cogratulations
November 17th, 2007 at 9:46 am
As of this time, it will not work with the release candidate Flash player (version 64 with hardware acceleration), but it does work with version 47.
January 12th, 2008 at 5:08 pm
[…] 17; and source after the click. heavly inspired by Robots w/Lasers and the lessrain log. the video footage is taken from the excellent documentary “Good Copy Bad Copy”, see […]
January 12th, 2008 at 5:38 pm
just done a small demo ( http://www.rootop.de/?p=128 ) inspired by your bitmap.draw example… your blog saved me hours of unnecessary headaches, thanks a lot…
mentioned you in my blog - if you don’t mind.
kind regards, peter
March 12th, 2008 at 1:22 pm
Hi, nice example !
But like in some other tuts I found around, there’s always a problem with the “renderCamera” function…???
Would you have an idea why ?
Thx
May 28th, 2008 at 7:25 pm
thanx for updating this for 2.0/GW compatability!
August 26th, 2008 at 11:48 am
What about loading a swf as texture for a plane ? Do you know if this is possible ? I searched on google, but google’s not my friend today with this requests…
Thx !
August 26th, 2008 at 10:29 pm
@itch: try searching for MovieMaterial. you’ll have to load the swf first though.
July 15th, 2009 at 6:28 am
great post! anyone able to get the video to stop (including audio?) when i try stop the video the audio keeps going - anyone have an idea there?
cheers!
April 6th, 2010 at 12:22 am
Hello.
I`m noob on flex and still cannot configure a project runing this AS file.
Any help please?.
I try also this example http://www.adobe.com/devnet/flash/articles/flashvideo3d_print.html and with this the problem is the object just with gray, no video texture (audio is running)