Here is my meager attempt to port over the existing Away3D
VideoMaterial to Away3D Lite. I have to admit that I barely know what
I'm doing, but I managed to get it working. I have zero idea how to
improve the performance beyond what I've already done, but If anyone
can make suggestions I'll do my best to implement them and update the
class
---------------------------
package away3dlite.materials
{
import away3dlite.arcane;
import fl.video.VideoEvent;
import flash.display.Sprite;
import flash.events.AsyncErrorEvent;
import flash.events.IOErrorEvent;
import flash.events.NetStatusEvent;
import flash.events.SecurityErrorEvent;
import flash.geom.Rectangle;
import flash.media.SoundTransform;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
use namespace arcane;
public class VideoMaterial extends MovieMaterial
{
private var _file:String;
private var _netStream:NetStream;
private var _video:Video;
private var _loop:Boolean;
private var _framerate:Number;
private var _duration:Number;
private var _fileWidth:Number;
private var _fileHeight:Number;
private function initStream():void
{
try {
// Use null connection for progressive files
nc = new NetConnection();
nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR,
securityErrorHandler, false, 0, true);
nc.connect(null);
// Setup stream. Remember that the FLV must be
in the same
security sandbox as the SWF.
_netStream = new NetStream(nc);
_netStream.addEventListener(NetStatusEvent.NET_STATUS,
netStatusHandler, false, 0, true);
_netStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR,
ayncErrorHandler, false, 0, true);
_netStream.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler,
false, 0, true);
play();
// ignore metadata
var obj:Object = {};
obj["onCuePoint"] = metaDataHandler;
obj["onMetaData"] = metaDataHandler;
_netStream.client = obj;
// Setup video object
if(video == null) {
video = new Video();
}
} catch (e:Error) {
trace("An error has occured with the flv
stream: " + e.message);
}
}
private function playStream():void
{
_netStream = new NetStream(nc);
_netStream.checkPolicyFile = true;
_netStream.addEventListener(NetStatusEvent.NET_STATUS,
netStatusHandler, false, 0, true);
_netStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR,
ayncErrorHandler, false, 0, true);
_netStream.addEventListener(IOErrorEvent.IO_ERROR,
ioErrorHandler,
false, 0, true);
play();
var obj:Object = {};
obj["onMetaData"] = metaDataHandler;
_netStream.client = obj;
// Setup video object
if(video == null) {
video = new Video();
}
}
// Event handling
private function ayncErrorHandler(event:AsyncErrorEvent): void
{
// Must be present to prevent errors, but won't do
anything
}
private function metaDataHandler(meta:Object = null):void
{
//store info about the loaded video
_fileWidth = meta.width;
_fileHeight = meta.height;
_framerate = meta.framerate;
_duration = meta.duration;
//using this method destroys the framerate for some
reason
//possibly because the _video instance thinks it needs
to be
320x240 when the loaded video is only 100x66
//movie = sprite;
//this seems to be better (set the video player's width
and define
the rect automatically)
_video.width = _fileWidth;
_video.height = _fileHeight;
//set the rect to match the video's dimensions
rect = sprite.getBounds(sprite);
dispatchEvent(new
VideoEvent(VideoEvent.BUFFERING_STATE_ENTERED));
//this.dispatchEvent( new VideoEvent
(VideoEvent.METADATA,_netStream,file,oData) );
}
private function ioErrorHandler(e:IOErrorEvent):void
{
trace("An IOerror occured: "+e.text);
}
private function securityErrorHandler(e:SecurityErrorEvent):void
{
trace("A security error occured: "+e.text+" Remember
that the FLV
must be in the same security sandbox as your SWF.");
}
private function netStatusHandler(e:NetStatusEvent):void
{
switch (e.info["code"]) {
case "NetStream.Play.Stop":
dispatchEvent(new VideoEvent
(VideoEvent.STOPPED_STATE_ENTERED));
//this.dispatchEvent( new
VideoEvent(VideoEvent.STOP,_netStream,
file) );
if(loop)
play();
break;
case "NetStream.Play.Play":
dispatchEvent(new VideoEvent
(VideoEvent.PLAYING_STATE_ENTERED));
//this.dispatchEvent( new
VideoEvent(VideoEvent.PLAY,_netStream,
file) );
break;
case "NetStream.Play.StreamNotFound":
trace("The file "+file+" was not
found", e);
break;
case "NetConnection.Connect.Success":
playStream();
break;
}
}
/**
* Plays the NetStream object. The material plays the NetStream
object by default at init. Use this handler only if you pause the
NetStream object;
*/
public function play():void
{
_netStream.play(file);
}
/**
* Pauses the NetStream object
*/
public function pause():void
{
_netStream.pause();
}
/**
* Seeks to a given time in the file, specified in seconds,
with a precision of three decimal places (milliseconds).
* For a progressive download, you can seek only to a keyframe,
so a
seek takes you to the time of the first keyframe after the specified
time. (When streaming, a seek always goes to the precise specified
time even if the source FLV file doesn't have a keyframe there.)
* @param val Number: the playheadtime
*/
public function seek(value:Number):void
{
pause();
_netStream.seek(value);
_netStream.resume();
}
/**
* Returns the actual time of the netStream
*/
public function get time():Number
{
return _netStream.time;
}
/**
* Closes the NetStream object
*/
public function close():void
{
_netStream.close();
}
/**
* The sound pan
* @param value Number: the sound pan, a value
from -1 to 1. Default
is 0;
*/
public function set pan(value:Number):void
{
var transform:SoundTransform = _netStream.soundTransform;
transform.pan = value;
_netStream.soundTransform = transform;
}
/**
* The sound volume
* @param value Number: the sound volume, a
value from 0 to 1.
Default is 0;
*/
public function set volume(value:Number):void
{
var transform:SoundTransform = _netStream.soundTransform;
transform.volume = value;
_netStream.soundTransform = transform;
}
/**
* The FLV url used for rendering the material
*/
public function get file():String
{
return _file;
}
public function set file(file:String):void
{
_file = file;
initStream();
}
/**
* The NetStream object used by the class
*/
public function get netStream():NetStream
{
return _netStream;
}
public function set netStream(ns:NetStream):void
{
_netStream = ns;
}
/**
* Defines if the FLV will loop
*/
public function get loop():Boolean
{
return _loop;
}
public function set loop(b:Boolean):void
{
_loop = b;
}
public function get framerate():Number
{
return _framerate;
}
public function get duration():Number
{
return _duration;
}
public function get fileWidth():Number
{
return _fileWidth;
}
public function get fileHeight():Number
{
return _fileHeight;
}
/**
* The Video Object
*/
public function get video():Video
{
return _video;
}
public function set video(vid:Video):void
{
if(_video != null) {
sprite.removeChild(_video);
}
_video = vid;
_video.smoothing = true;
_video.attachNetStream(_netStream);
sprite.addChild(_video);
movie = sprite;
}
/**
* Defines the NetConnection we'll use
*/
public var nc:NetConnection;
/**
* A Sprite we can return to the MovieMaterial
*/
public var sprite:Sprite;
/**
* Creates a new <code>VideoMaterial</code> object.
* Be aware that FLV files must be located in the same domain as
the
SWF or you will get security errors.
*/
public function VideoMaterial(movie:Sprite = null,
rect:Rectangle = null, autoUpdate:Boolean = true, transparent:Boolean
= true)
{
if(movie == null) {
movie = new Sprite();
}
this.sprite = new Sprite();
super(movie, rect, autoUpdate, transparent);
}
}
}