Re-enable video in the world.
There are a few rough edges which'll eventually get ironed out. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4607 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -44,8 +44,6 @@ import flash.events.TextEvent;
|
|||||||
|
|
||||||
import flash.geom.Point;
|
import flash.geom.Point;
|
||||||
|
|
||||||
import flash.media.Video;
|
|
||||||
|
|
||||||
import flash.text.TextField;
|
import flash.text.TextField;
|
||||||
import flash.text.TextFieldAutoSize;
|
import flash.text.TextFieldAutoSize;
|
||||||
|
|
||||||
@@ -145,26 +143,12 @@ public class MediaContainer extends Sprite
|
|||||||
*/
|
*/
|
||||||
protected function setupVideo (url :String) :void
|
protected function setupVideo (url :String) :void
|
||||||
{
|
{
|
||||||
// TODO: re-implement video without flex
|
var vid :VideoDisplayer = new VideoDisplayer();
|
||||||
var tf :TextField = new TextField();
|
vid.addEventListener(VideoDisplayer.SIZE_KNOWN, handleVideoSizeKnown);
|
||||||
tf.autoSize = TextFieldAutoSize.LEFT;
|
vid.addEventListener(VideoDisplayer.VIDEO_ERROR, handleVideoError);
|
||||||
tf.text = "Video is temporarily disabled";
|
_media = vid;
|
||||||
tf.background = true;
|
addChild(vid);
|
||||||
tf.selectable = false;
|
vid.setup(url);
|
||||||
tf.width = tf.textWidth + 5;
|
|
||||||
setMediaObject(tf);
|
|
||||||
|
|
||||||
// var vid :VideoDisplay = new VideoDisplay();
|
|
||||||
// vid.autoPlay = false;
|
|
||||||
// _media = vid;
|
|
||||||
// addChild(vid);
|
|
||||||
// vid.addEventListener(ProgressEvent.PROGRESS, loadVideoProgress);
|
|
||||||
// vid.addEventListener(VideoEvent.READY, loadVideoReady);
|
|
||||||
// vid.addEventListener(VideoEvent.REWIND, videoDidRewind);
|
|
||||||
//
|
|
||||||
// // start it loading
|
|
||||||
// vid.source = url;
|
|
||||||
// vid.load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -256,25 +240,12 @@ public class MediaContainer extends Sprite
|
|||||||
|
|
||||||
removeChild(loader);
|
removeChild(loader);
|
||||||
|
|
||||||
// } else if (_media is VideoDisplay) {
|
} else if (_media is VideoDisplayer) {
|
||||||
// var vid :VideoDisplay = (_media as VideoDisplay);
|
var vid :VideoDisplayer = (_media as VideoDisplayer);
|
||||||
// // remove any listeners
|
vid.removeEventListener(VideoDisplayer.SIZE_KNOWN, handleVideoSizeKnown);
|
||||||
// vid.removeEventListener(ProgressEvent.PROGRESS,
|
vid.removeEventListener(VideoDisplayer.VIDEO_ERROR, handleVideoError);
|
||||||
// loadVideoProgress);
|
vid.shutdown();
|
||||||
// vid.removeEventListener(VideoEvent.READY, loadVideoReady);
|
removeChild(vid);
|
||||||
// vid.removeEventListener(VideoEvent.REWIND, videoDidRewind);
|
|
||||||
//
|
|
||||||
// // dispose of media
|
|
||||||
// vid.pause();
|
|
||||||
// try {
|
|
||||||
// vid.close();
|
|
||||||
// } catch (ioe :IOError) {
|
|
||||||
// // ignore
|
|
||||||
// }
|
|
||||||
// vid.stop();
|
|
||||||
//
|
|
||||||
// // remove from hierarchy
|
|
||||||
// removeChild(vid);
|
|
||||||
|
|
||||||
} else if (_media != null) {
|
} else if (_media != null) {
|
||||||
removeChild(_media);
|
removeChild(_media);
|
||||||
@@ -421,31 +392,24 @@ public class MediaContainer extends Sprite
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback to receive PROGRESS events on the video.
|
* Handles video size known.
|
||||||
*/
|
*/
|
||||||
protected function loadVideoProgress (event :ProgressEvent) :void
|
protected function handleVideoSizeKnown (event :ValueEvent) :void
|
||||||
{
|
{
|
||||||
// var vid :VideoDisplay = (event.currentTarget as VideoDisplay);
|
var args :Array = (event.value as Array);
|
||||||
// updateContentDimensions(vid.videoWidth, vid.videoHeight);
|
updateContentDimensions(int(args[0]), int(args[1]));
|
||||||
//
|
trace("Video size is now known: " + _w + ", " + _h);
|
||||||
// updateLoadingProgress(vid.bytesLoaded, vid.bytesTotal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback to receive READY events for video.
|
* Handles an error loading a video.
|
||||||
*/
|
*/
|
||||||
// protected function loadVideoReady (event :VideoEvent) :void
|
protected function handleVideoError (event :ValueEvent) :void
|
||||||
// {
|
{
|
||||||
// var vid :VideoDisplay = (event.currentTarget as VideoDisplay);
|
trace("Video load error: " + event.value);
|
||||||
// updateContentDimensions(vid.videoWidth, vid.videoHeight);
|
stoppedLoading();
|
||||||
// updateLoadingProgress(1, 1);
|
setupBrokenImage(-1, -1);
|
||||||
//
|
}
|
||||||
// vid.play();
|
|
||||||
//
|
|
||||||
// // remove the two listeners
|
|
||||||
// vid.removeEventListener(ProgressEvent.PROGRESS, loadVideoProgress);
|
|
||||||
// vid.removeEventListener(VideoEvent.READY, loadVideoReady);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback function to receive COMPLETE events for swfs or images.
|
* Callback function to receive COMPLETE events for swfs or images.
|
||||||
@@ -465,14 +429,6 @@ public class MediaContainer extends Sprite
|
|||||||
stoppedLoading();
|
stoppedLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the video auto-rewinds.
|
|
||||||
*/
|
|
||||||
// protected function videoDidRewind (event :VideoEvent) :void
|
|
||||||
// {
|
|
||||||
// (_media as VideoDisplay).play();
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure the mask for this object.
|
* Configure the mask for this object.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,225 @@
|
|||||||
|
package com.threerings.util { // TODO: Move.
|
||||||
|
|
||||||
|
import flash.display.Sprite;
|
||||||
|
|
||||||
|
import flash.events.AsyncErrorEvent;
|
||||||
|
import flash.events.IOErrorEvent;
|
||||||
|
import flash.events.Event;
|
||||||
|
import flash.events.MouseEvent;
|
||||||
|
import flash.events.NetStatusEvent;
|
||||||
|
import flash.events.SecurityErrorEvent;
|
||||||
|
import flash.events.TimerEvent;
|
||||||
|
|
||||||
|
import flash.media.Video;
|
||||||
|
|
||||||
|
import flash.net.NetConnection;
|
||||||
|
import flash.net.NetStream;
|
||||||
|
|
||||||
|
import flash.utils.Timer;
|
||||||
|
|
||||||
|
public class VideoDisplayer extends Sprite
|
||||||
|
{
|
||||||
|
/** A value event dispatched when the size of the video is known.
|
||||||
|
* Value: [ width, height ]. */
|
||||||
|
public static const SIZE_KNOWN :String = "SIZE_KNOWN";
|
||||||
|
|
||||||
|
/** A value event sent when there's an error loading the video.
|
||||||
|
* Value: original error event. */
|
||||||
|
public static const VIDEO_ERROR :String = "VIDEO_ERROR";
|
||||||
|
|
||||||
|
public function VideoDisplayer ()
|
||||||
|
{
|
||||||
|
_vid = new Video();
|
||||||
|
addChild(_vid);
|
||||||
|
|
||||||
|
addEventListener(MouseEvent.CLICK, handleClick);
|
||||||
|
_videoChecker.addEventListener(TimerEvent.TIMER, handleVideoCheck);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setup (url :String) :void
|
||||||
|
{
|
||||||
|
_netCon = new NetConnection();
|
||||||
|
_netCon.addEventListener(NetStatusEvent.NET_STATUS, handleNetStatus);
|
||||||
|
|
||||||
|
// error handlers
|
||||||
|
_netCon.addEventListener(AsyncErrorEvent.ASYNC_ERROR, handleAsyncError);
|
||||||
|
_netCon.addEventListener(IOErrorEvent.IO_ERROR, handleIOError);
|
||||||
|
_netCon.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handleSecurityError);
|
||||||
|
|
||||||
|
_netCon.connect(null);
|
||||||
|
trace("Not waiting, just using!");
|
||||||
|
_netStream = new NetStream(_netCon);
|
||||||
|
_netStream.client = this;
|
||||||
|
//_netStream.client = new Callbacker(this);
|
||||||
|
_vid.attachNetStream(_netStream);
|
||||||
|
_videoChecker.start();
|
||||||
|
_netStream.play(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function shutdown () :void
|
||||||
|
{
|
||||||
|
_videoChecker.reset();
|
||||||
|
_vid.attachNetStream(null);
|
||||||
|
|
||||||
|
if (_netStream != null) {
|
||||||
|
_netStream.close();
|
||||||
|
_netStream = null;
|
||||||
|
}
|
||||||
|
if (_netCon != null) {
|
||||||
|
_netCon.close();
|
||||||
|
_netCon.removeEventListener(NetStatusEvent.NET_STATUS, handleNetStatus);
|
||||||
|
_netCon.removeEventListener(AsyncErrorEvent.ASYNC_ERROR, handleAsyncError);
|
||||||
|
_netCon.removeEventListener(IOErrorEvent.IO_ERROR, handleIOError);
|
||||||
|
_netCon.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, handleSecurityError);
|
||||||
|
_netCon = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see if we now know the dimensions of the video.
|
||||||
|
*/
|
||||||
|
protected function handleVideoCheck (event :TimerEvent) :void
|
||||||
|
{
|
||||||
|
if (_vid.videoWidth == 0 || _vid.videoHeight == 0) {
|
||||||
|
return; // not known yet!
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop the checker timer
|
||||||
|
_videoChecker.stop();
|
||||||
|
|
||||||
|
// set up the width/height
|
||||||
|
_vid.width = _vid.videoWidth;
|
||||||
|
_vid.height = _vid.videoHeight;
|
||||||
|
|
||||||
|
// tell any interested parties
|
||||||
|
dispatchEvent(new ValueEvent(SIZE_KNOWN, [ _vid.videoWidth, _vid.videoHeight ]));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleClick (event :MouseEvent) :void
|
||||||
|
{
|
||||||
|
trace("Click!");
|
||||||
|
_netStream.togglePause();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleNetStatus (event :NetStatusEvent) :void
|
||||||
|
{
|
||||||
|
var info :Object = event.info;
|
||||||
|
if ("error" == info.level) {
|
||||||
|
trace("NetStatus error: " + info.code);
|
||||||
|
redispatchError(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// else info.level == "status"
|
||||||
|
switch (info.code) {
|
||||||
|
case "NetConnection.Connect.Success":
|
||||||
|
trace("Connected!");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
trace("NetStatus status: " + info.code);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleAsyncError (event :AsyncErrorEvent) :void
|
||||||
|
{
|
||||||
|
trace("AsyncError: " + event);
|
||||||
|
redispatchError(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleIOError (event :IOErrorEvent) :void
|
||||||
|
{
|
||||||
|
trace("IOError: " + event);
|
||||||
|
redispatchError(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleSecurityError (event :SecurityErrorEvent) :void
|
||||||
|
{
|
||||||
|
trace("SecurityError: " + event);
|
||||||
|
redispatchError(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function redispatchError (event :Event) :void
|
||||||
|
{
|
||||||
|
dispatchEvent(new ValueEvent(VIDEO_ERROR, event));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function callbackCalled (name :String, args :Array) :*
|
||||||
|
{
|
||||||
|
trace("Callback: " + name + ", args: " + args);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onMetaData (obj :Object) :void
|
||||||
|
{
|
||||||
|
trace("Got metadata..");
|
||||||
|
for (var n :String in obj) {
|
||||||
|
trace("name " + n + " -> " + obj[n]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected var _vid :Video;
|
||||||
|
|
||||||
|
protected var _netCon :NetConnection;
|
||||||
|
|
||||||
|
protected var _netStream :NetStream;
|
||||||
|
|
||||||
|
/** Checks the video every 100ms to see if the dimensions are now know.
|
||||||
|
* Yes, this is how to do it. We could trigger on ENTER_FRAME, but then
|
||||||
|
* we may not know the dimensions unless we're added on the display list,
|
||||||
|
* and we want this to work in the general case. */
|
||||||
|
protected var _videoChecker :Timer = new Timer(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
import flash.utils.Proxy;
|
||||||
|
|
||||||
|
import flash.utils.flash_proxy;
|
||||||
|
|
||||||
|
import com.threerings.util.VideoDisplayer;
|
||||||
|
|
||||||
|
use namespace flash_proxy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
internal class Callbacker extends Proxy
|
||||||
|
{
|
||||||
|
public function Callbacker (displayer :VideoDisplayer)
|
||||||
|
{
|
||||||
|
_displayer = displayer;
|
||||||
|
|
||||||
|
_props
|
||||||
|
}
|
||||||
|
|
||||||
|
override flash_proxy function hasProperty (name :*) :Boolean
|
||||||
|
{
|
||||||
|
return (_props[name] !== undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
override flash_proxy function getProperty (name :*) :*
|
||||||
|
{
|
||||||
|
trace("Damn thing asked about '" + name + "'.");
|
||||||
|
return _props[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
override flash_proxy function setProperty (name :*, value :*) :void
|
||||||
|
{
|
||||||
|
trace("Damn thing tried to set '" + name + "' to '" + value + "'.");
|
||||||
|
_props[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
override flash_proxy function deleteProperty (name :*) :Boolean
|
||||||
|
{
|
||||||
|
trace("Damn thing tried to delete '" + name + "'.");
|
||||||
|
return (delete _props[name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
override flash_proxy function callProperty (name :*, ... args) :*
|
||||||
|
{
|
||||||
|
return _displayer.callbackCalled(name, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected var _props :Object = {};
|
||||||
|
|
||||||
|
protected var _displayer :VideoDisplayer;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user