Out with the old.
git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@695 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -1,310 +0,0 @@
|
|||||||
//
|
|
||||||
// $Id$
|
|
||||||
//
|
|
||||||
// Nenya library - tools for developing networked games
|
|
||||||
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
|
|
||||||
// http://www.threerings.net/code/nenya/
|
|
||||||
//
|
|
||||||
// This library is free software; you can redistribute it and/or modify it
|
|
||||||
// under the terms of the GNU Lesser General Public License as published
|
|
||||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
|
||||||
// License along with this library; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
package com.threerings.flash {
|
|
||||||
|
|
||||||
import flash.display.Shape;
|
|
||||||
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;
|
|
||||||
|
|
||||||
import com.threerings.util.ValueEvent;
|
|
||||||
|
|
||||||
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 = "videoDisplayerSizeKnown";
|
|
||||||
|
|
||||||
/** A value event sent when there's an error loading the video.
|
|
||||||
* Value: original error event. */
|
|
||||||
public static const VIDEO_ERROR :String = "videoDisplayerError";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a video displayer.
|
|
||||||
*/
|
|
||||||
public function VideoDisplayer ()
|
|
||||||
{
|
|
||||||
_vid = new Video();
|
|
||||||
addChild(_vid);
|
|
||||||
|
|
||||||
_mask = new Shape();
|
|
||||||
this.mask = _mask;
|
|
||||||
addChild(_mask);
|
|
||||||
|
|
||||||
addEventListener(MouseEvent.ROLL_OVER, handleRollOver);
|
|
||||||
addEventListener(MouseEvent.ROLL_OUT, handleRollOut);
|
|
||||||
|
|
||||||
_videoChecker.addEventListener(TimerEvent.TIMER, handleVideoCheck);
|
|
||||||
|
|
||||||
_pauser = new Sprite();
|
|
||||||
_pauser.addEventListener(MouseEvent.CLICK, handleClick);
|
|
||||||
redrawPauser();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start playing a video!
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
_netStream = new NetStream(_netCon);
|
|
||||||
// pass in refs to some of our protected methods
|
|
||||||
_netStream.client = {
|
|
||||||
onMetaData: metaDataReceived
|
|
||||||
};
|
|
||||||
_netStream.addEventListener(NetStatusEvent.NET_STATUS, handleStreamNetStatus);
|
|
||||||
|
|
||||||
_vid.attachNetStream(_netStream);
|
|
||||||
_videoChecker.start();
|
|
||||||
_netStream.play(url);
|
|
||||||
_paused = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop playing our video.
|
|
||||||
*/
|
|
||||||
public function shutdown () :void
|
|
||||||
{
|
|
||||||
_videoChecker.reset();
|
|
||||||
_vid.attachNetStream(null);
|
|
||||||
|
|
||||||
if (_netStream != null) {
|
|
||||||
_netStream.close();
|
|
||||||
_netStream.removeEventListener(NetStatusEvent.NET_STATUS, handleStreamNetStatus);
|
|
||||||
_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;
|
|
||||||
|
|
||||||
// set up our mask to be the size of the video so that we're
|
|
||||||
// guaranteed to get the mouse clicks
|
|
||||||
with (_mask.graphics) {
|
|
||||||
clear();
|
|
||||||
beginFill(0xFFFFFF);
|
|
||||||
drawRect(0, 0, _vid.videoWidth, _vid.videoHeight);
|
|
||||||
endFill();
|
|
||||||
}
|
|
||||||
|
|
||||||
redrawPauser();
|
|
||||||
|
|
||||||
// tell any interested parties
|
|
||||||
dispatchEvent(new ValueEvent(SIZE_KNOWN, [ _vid.videoWidth, _vid.videoHeight ]));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function handleRollOver (event :MouseEvent) :void
|
|
||||||
{
|
|
||||||
addChild(_pauser);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function handleRollOut (event :MouseEvent) :void
|
|
||||||
{
|
|
||||||
if (_pauser.parent) {
|
|
||||||
removeChild(_pauser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function handleClick (event :MouseEvent) :void
|
|
||||||
{
|
|
||||||
// the buck stops here!
|
|
||||||
event.stopImmediatePropagation();
|
|
||||||
|
|
||||||
if (_paused) {
|
|
||||||
_netStream.resume();
|
|
||||||
_paused = false;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
_netStream.pause();
|
|
||||||
_paused = true;
|
|
||||||
}
|
|
||||||
redrawPauser();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draw the pauser sprite, update it's location.
|
|
||||||
* This will become something artistic, etc.
|
|
||||||
*/
|
|
||||||
protected function redrawPauser () :void
|
|
||||||
{
|
|
||||||
with (_pauser.graphics) {
|
|
||||||
clear();
|
|
||||||
// draw a nice circle
|
|
||||||
beginFill(0x333333);
|
|
||||||
drawCircle(0, 0, 20);
|
|
||||||
endFill();
|
|
||||||
lineStyle(2, 0);
|
|
||||||
drawCircle(0, 0, 20);
|
|
||||||
|
|
||||||
if (_paused) {
|
|
||||||
lineStyle(0, 0, 0);
|
|
||||||
beginFill(0x00FF00);
|
|
||||||
moveTo(-4, -10);
|
|
||||||
lineTo(4, 0);
|
|
||||||
lineTo(-4, 10);
|
|
||||||
lineTo(-4, -10);
|
|
||||||
endFill();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
lineStyle(2, 0x00FF00);
|
|
||||||
moveTo(-4, -10);
|
|
||||||
lineTo(-4, 10);
|
|
||||||
moveTo(4, -10);
|
|
||||||
lineTo(4, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// and update the location
|
|
||||||
_pauser.x = _vid.width/2;
|
|
||||||
_pauser.y = _vid.height/2;
|
|
||||||
}
|
|
||||||
|
|
||||||
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":
|
|
||||||
case "NetConnection.Connect.Closed":
|
|
||||||
// these status events we ignore
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
trace("NetStatus status: " + info.code);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function handleStreamNetStatus (event :NetStatusEvent) :void
|
|
||||||
{
|
|
||||||
if (event.info.code == "NetStream.Play.Stop") {
|
|
||||||
_netStream.seek(0);
|
|
||||||
_netStream.pause();
|
|
||||||
_paused = true;
|
|
||||||
redrawPauser();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redispatch some error we received to our listeners.
|
|
||||||
*/
|
|
||||||
protected function redispatchError (event :Event) :void
|
|
||||||
{
|
|
||||||
dispatchEvent(new ValueEvent(VIDEO_ERROR, event));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when metadata (if any) is found in the video stream.
|
|
||||||
*/
|
|
||||||
protected function metaDataReceived (obj :Object) :void
|
|
||||||
{
|
|
||||||
trace("Got video metadata:");
|
|
||||||
for (var n :String in obj) {
|
|
||||||
trace(" " + n + ": " + obj[n]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected var _vid :Video;
|
|
||||||
|
|
||||||
/** Our mask, also defines our boundaries for clicking. */
|
|
||||||
protected var _mask :Shape;
|
|
||||||
|
|
||||||
protected var _paused :Boolean = false;
|
|
||||||
|
|
||||||
protected var _netCon :NetConnection;
|
|
||||||
|
|
||||||
protected var _netStream :NetStream;
|
|
||||||
|
|
||||||
protected var _pauser :Sprite;
|
|
||||||
|
|
||||||
/** 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user