Skip to content

Instantly share code, notes, and snippets.

@rozklad
Last active December 16, 2015 11:39
Show Gist options
  • Save rozklad/5428707 to your computer and use it in GitHub Desktop.
Save rozklad/5428707 to your computer and use it in GitHub Desktop.
AS3 media player
package {
import flash.geom.*;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Stage;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.StageDisplayState;
import flash.events.Event;
import flash.events.IOErrorEvent
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.events.ProgressEvent;
import flash.events.AsyncErrorEvent;
import flash.media.Video;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.net.URLRequest;
import flash.net.navigateToURL;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.utils.setInterval;
import flash.utils.clearInterval;
// Respects ActionScript 3.0 Coding Conventions: http://opensource.adobe.com/wiki/display/flexsdk/Coding+Conventions
public class Player extends MovieClip {
// Settings and factory defaults
var settings:Object = {};
var factory:Object = { name: 'Player sample', // Name to show in status bar
link: 'http://www.example.com', // Link to pop up by clicking on name
//audio: 'media/custom.mp3', // Default audiofile path
audio: false,
video: 'media/video.mp4', // Default videofile path
thumb: 'media/poster.jpg', // Default thumbnail path
linkColor: 'CCCCCC', // Color of links
hoverColor: 'FFFFFF', // Hover color of links
buffer: 5, // Buffer time in seconds
expandedBuffer: 20, // Expanded buffer
inactiveToHide: 5, // Inactive time needed to hide controls in seconds
controlsHeight: 40, // Height of controls panel
controlsMargin: 0, // Margin of controls panel (goes for status bar as well)
soundVolume: 0.6, // Startup volume of sound
autoplay: false, // Automatically play on load (true/false)
scrubVolume: true, // True enables volume scrubbing, false sets volume to on/off button
debug: true, // Debug mode (true/false)
startMode: true, // Starting screen mode
startMargin: 0, // Starting screen mode margin
animate: true // Animate hide and show actions
}
// netStream
var nc:NetConnection;
var ns:NetStream;
var meta:Object;
// True = video, False = audio
var media:Boolean;
// Save position for resuming audio
var position:Number;
// Video data
var path:String;
var video:Video;
var audio:Sound;
var channel:SoundChannel;
var sound:SoundTransform;
var duration:Number;
var amountLoaded:Number;
var amountPlayed:Number;
var currentTime:int;
// References to objects
var thumbScreen:MovieClip;
var videoScreen:MovieClip;
var curtain:MovieClip;
var controls:MovieClip;
var status:MovieClip;
// Indicators
var played:Boolean = false;
var started:Boolean = false;
var controlsState:Boolean = true;
var inactive:int = 0;
// Intervals
var interval = intervalInit(0);
var sideInterval;
// Helper variables
var lastMouseX:int;
var lastMouseY:int;
// --------------------------------------------------------------------
//
// Player methods
//
// --------------------------------------------------------------------
/**
* Player
*
* Constructor method assigns object references from flash movie
* to actionscript class.
*
* @access public
* @param thumbScreenRef MovieClip Reference to thumbnail screen
* @param videoScreenRef MovieClip Reference to video screen
* @param curtainRef MovieClip Reference to curtain
* @param controlsRef MovieClip Reference to controls panel
* @param statusRef MovieClip Reference to status bar
* @return void
*/
public function Player(thumbScreenRef:MovieClip, videoScreenRef:MovieClip, curtainRef:MovieClip, controlsRef:MovieClip, statusRef:MovieClip):void {
thumbScreen = thumbScreenRef;
videoScreen = videoScreenRef;
curtain = curtainRef;
controls = controlsRef;
status = statusRef;
addEventListener(Event.ADDED_TO_STAGE, init); // Fire init() when class loaded to stage (addChild() function fires Event.ADDED_TO_STAGE)
}
// --------------------------------------------------------------------
/**
* init
*
* Initialization of essential settings and functions. Uses custom events
* to chain initialization. (When A is loaded => init B, When B is loaded =>
* init C etc.)
*
* @access private
* @param event Event event data by listener
* @return void
*/
private function init(event:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init); // Remove firing init()
settings = settingsFactory(stage.loaderInfo.parameters); // Load settings or use factory defaults
stage.addEventListener('prepared', thumbInit);
stage.addEventListener('thumbLoaded', streamInit);
stage.addEventListener('streamLoaded', controlsInit);
stage.addEventListener('controlsLoaded', statusInit);
stage.addEventListener('statusLoaded', soundInit);
prepare(); // Init first init method to start chain initialization
stage.addEventListener(Event.RESIZE, resize); // Respond to resize
}
// --------------------------------------------------------------------
//
// Resize methods
//
// --------------------------------------------------------------------
private function resize(event:Event):void {
resizeControls();
resizeStatus();
resizeVideo();
resizeThumb();
}
private function resizeWidth(element:MovieClip):void {
element.bg.width = stage.stageWidth - 2*settings.controlsMargin;
}
private function getCenter(element:MovieClip):int {
return element.width/2;
}
private function getMiddle(element:MovieClip):int {
return element.height/2;
}
private function resizeControls():void {
resizeWidth(controls);
controls.bg.height = settings.controlsHeight;
controls.y = stage.stageHeight - controls.bg.height - settings.controlsMargin;
controls.playBtn.x = getCenter(controls.playBtn);
controls.playBtn.y = getMiddle(controls.playBtn);
controls.bg.x = 0;
controls.bg.y = 0;
controls.fullBtn.x = stage.stageWidth - getCenter(controls.fullBtn) - settings.controlsMargin;
controls.soundBtn.x = stage.stageWidth - getCenter(controls.soundBtn) - controls.fullBtn.width - settings.controlsMargin;
controls.volumeScrubber.x = controls.soundBtn.x;
resizeControlsScrubber();
}
private function resizeControlsScrubber():void {
controls.scrubber.container.width = stage.stageWidth - 2*settings.controlsMargin - controls.soundBtn.width - controls.fullBtn.width*1.5 - controls.playBtn.width;
controls.scrubber.x = controls.playBtn.width*1.25;
}
private function resizeStatus():void {
resizeWidth(status);
status.heading.bg.width = stage.stageWidth;
status.y = settings.controlsMargin;
status.buffer.y = stage.stageHeight/2 - status.buffer.height/2;
status.buffer.width = stage.stageWidth;
}
private function resizeVideo():void {
status.heading.content.text = stage.stageWidth + ' ' + stage.stageHeight;
videoScreen.width = stage.stageWidth;
videoScreen.height = stage.stageHeight;
}
private function resizeThumb():void {
thumbScreen.width = stage.stageWidth;
thumbScreen.height = stage.stageHeight;
}
// --------------------------------------------------------------------
//
// Interval
//
// --------------------------------------------------------------------
// Could be achived through Timer Class
// --------------------------------------------------------------------
private function intervalInit(kind:int):Number {
switch (kind) {
case 0:
{
return setInterval(streamInterval, 100);
break;
}
case 1:
{
return setInterval(scrubbingInterval, 10);
break;
}
case 2:
{
return setInterval(scrubberInterval, 10);
break;
}
case 3:
{
return setInterval(bufferInterval, 100);
break;
}
default:
{
return 0;
}
}
}
private function streamInterval() {
updateTrack();
currentTime = Math.ceil(ns.time);
updateTime(currentTime);
controls.timer.x = controls.scrubber.played.width + controls.timer.width - controls.scrubber.scrubber.width;
checkMovement();
}
private function scrubberInterval():void {
updateTrack();
controls.timer.x = mouseX - controls.timer.width/2;
currentTime = pos2Time(controls.timer.x, controls.scrubber.container);
updateTime(currentTime);
}
private function scrubbingInterval():void {
controls.timer.x = controls.scrubber.scrubber.x + controls.timer.width - controls.scrubber.scrubber.width;
currentTime = pos2Time(controls.timer.x, controls.scrubber.container);
updateTime(currentTime);
}
private function bufferInterval():void {
updateTrack();
currentTime = Math.ceil(ns.time);
updateTime(currentTime);
controls.timer.x = controls.scrubber.played.width + controls.timer.width - controls.scrubber.scrubber.width;
var buffered = getBuffered();
if (buffered > 99) {
status.buffer.visible = false;
} else {
status.buffer.visible = true;
status.buffer.text = String(buffered) + '%';
}
}
function getBuffered():int {
return Math.round((ns.bufferLength/ns.bufferTime)*100);
}
private function checkMovement():void {
var posMouseX = stage.mouseX;
var posMouseY = stage.mouseY;
if (played) {
if (lastMouseX == posMouseX && lastMouseY == posMouseY)
inactive++;
else
inactive = 0;
}
if (inactive < settings.inactiveToHide * 10) {
if (!controlsState)
controlsShow();
} else {
if (controlsState)
controlsHide();
}
lastMouseX = posMouseX;
lastMouseY = posMouseY;
}
private function updateTime(currentTime) {
controls.timer.content.text = formatTime(currentTime);
}
private function formatTime(time:int):String {
var secs:String = (time % 60).toString();
secs = (secs.length == 1 ? '0' : '') + secs;
var mins:String = Math.floor(time / 60).toString();
mins = (mins.length == 1 ? '0' : '') + mins;
return mins + ':' + secs;
}
private function mouse2Time():int {
return pos2Time(mouseX - controls.timer.width/2, controls.scrubber.container);
}
private function pos2Time(scrubber:int, track:MovieClip):int {
return Math.ceil(duration * (scrubber/track.width));
}
private function updateTrack():void {
amountPlayed = ns.time / duration;
amountLoaded = ns.bytesLoaded / ns.bytesTotal;
if (amountPlayed < 0.05 && duration < 20)
amountPlayed = 0; // Show less than 5% played as 0% for extremely short videos
controls.scrubber.loaded.width = amountLoaded * controls.scrubber.container.width;
controls.scrubber.played.width = amountPlayed * controls.scrubber.container.width;
controls.scrubber.scrubber.x = controls.scrubber.played.width;
}
// --------------------------------------------------------------------
//
// Volume methods
//
// --------------------------------------------------------------------
private function volumeButton(show:Boolean):void {
if (settings.scrubVolume) {
controls.volumeScrubber.visible = show;
controls.soundBtn.visible = false;
volumeScrubberDefault();
} else {
controls.volumeScrubber.visible = true;
controls.soundBtn.visible = show;
}
}
private function volumeDefault():void {
volumeButton(true);
}
private function volumeScrubberDefault():void {
var buttons:Array /* of MovieClips */ = [controls.volumeScrubber.volume0, controls.volumeScrubber.volume20, controls.volumeScrubber.volume40,
controls.volumeScrubber.volume60, controls.volumeScrubber.volume80, controls.volumeScrubber.volume100,
controls.volumeScrubber.volumeMAX];
for (var i = 0; i<buttons.length; i++) {
buttonize(buttons[i], btnOver, volumeOut, pressVolume);
}
}
private function volumeOut(event:MouseEvent):void {
if (media) {
if (voumeGetPieceVolume(event) > ns.soundTransform.volume)
event.currentTarget.gotoAndPlay('out');
} else {
if (voumeGetPieceVolume(event) > channel.soundTransform.volume)
event.currentTarget.gotoAndPlay('out');
}
}
private function voumeGetPieceVolume(event:MouseEvent):Number {
var pieceName:String = event.currentTarget.name.substr(6,3);
var pieceVolume:Number = 0.0;
if (pieceName == 'MAX') {
pieceVolume = 100;
} else {
pieceVolume = Number(pieceName);
}
return pieceVolume/100;
}
private function volumeReflect(volume:Number, originalVolume:Number):void {
var buttons:Array /* of MovieClips */ = [controls.volumeScrubber.volume20, controls.volumeScrubber.volume40,
controls.volumeScrubber.volume60, controls.volumeScrubber.volume80, controls.volumeScrubber.volume100];
var volumes:Array /* of Numbers */ = [0.2, 0.4, 0.6, 0.8, 1.0];
var loops:int = buttons.length;
for (var i = 0; i<loops; i++) {
if (volume>=volumes[i])
buttons[i].gotoAndPlay('over');
else
buttons[i].gotoAndPlay('out');
}
}
private function pressVolume(event:MouseEvent):void {
switch (event.currentTarget.name)
{
case 'volume0':
{
soundSet(0);
break;
}
case 'volume20':
{
soundSet(0.2);
break;
}
case 'volume40':
{
soundSet(0.4);
break;
}
case 'volume60':
{
soundSet(0.6);
break;
}
case 'volume80':
{
soundSet(0.8);
break;
}
case 'volume100':
{
soundSet(1);
break;
}
case 'volumeMAX':
{
soundSet(1);
break;
}
}
}
// --------------------------------------------------------------------
//
// Controls methods
//
// --------------------------------------------------------------------
private function controlsScrubberDefault():void {
controls.scrubber.loaded.width = 1;
controls.scrubber.played.width = 1;
controlsHideTimer();
}
private function controlsHideTimer():void {
controls.timer.visible = false;
}
private function controlsShowTimer():void {
controls.timer.visible = true;
}
private function controlsHide():void {
debug('controlsHide');
if (settings.animate)
controlsAnimate(false);
else
controls.visible = false;
controlsState = false;
}
private function controlsShow():void {
debug('controlsShow');
if (settings.animate)
controlsAnimate(true);
else
controls.visible = true;
controlsState = true;
}
private function controlsAnimate(show:Boolean):void {
clearInterval(sideInterval);
if (show)
sideInterval = setInterval(controlsAnimateShow, 10);
else
sideInterval = setInterval(controlsAnimateHide, 10);
}
private function controlsAnimateShow():void {
controls.y -= 1;
if (controls.y <= stage.stageHeight - settings.controlsHeight) {
clearInterval(sideInterval);
}
}
private function controlsAnimateHide():void {
controls.y += 1;
if (controls.y >= stage.stageHeight) {
clearInterval(sideInterval);
}
}
private function controlsInit(event:Event):void {
debug('controlsInit');
// Set scale mode to NO_SCALE (does not resize elements) and put stage to top left corner
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
controlsBtns();
controlsChange();
controlsScrubberDefault();
controlsSwitch(false);
stage.dispatchEvent(new Event('controlsLoaded'));
stage.dispatchEvent(new Event(Event.RESIZE)); // Fire resize right away to adjust to default resolution
}
private function controlsSwitch(show:Boolean):void {
if ( ! started) {
controls.playBtn.x = controls.playBtn.x + settings.startMargin;
controls.playBtn.y = controls.playBtn.y - settings.startMargin;
controls.bg.width = controls.playBtn.width + status.heading.content.width;
controls.bg.y = controls.bg.y - settings.startMargin;
controls.bg.x = controls.bg.x + settings.startMargin;
status.heading.x = controls.playBtn.x + getCenter(controls.playBtn);
status.heading.y = stage.stageHeight - settings.controlsHeight - settings.startMargin;
} else {
statusHide();
resizeControls();
status.heading.y = 0;
status.heading.x = settings.controlsMargin;
}
controls.scrubber.visible = show;
controls.fullBtn.visible = show;
controls.soundBtn.visible = show;
volumeButton(show);
}
private function controlsBtns():void {
var buttons:Array /* of MovieClips */ = [controls.fullBtn, controls.playBtn, controls.pauseBtn, controls.soundBtn, controls.scrubber.container];
var functions:Array /* of functions */ = [pressFullScreen, pressResume, pressPause, pressSound, pressScrubber];
var loops:int = buttons.length;
for (var i = 0; i<loops; i++) {
buttonize(buttons[i], btnOver, btnOut, functions[i]);
}
thumbScreen.addEventListener(MouseEvent.CLICK, pressResume);
videoScreen.addEventListener(MouseEvent.CLICK, pressToggle);
scrubberShowTimerOver();
controls.scrubber.scrubber.addEventListener(MouseEvent.MOUSE_DOWN, scrubberDown);
controls.scrubber.scrubber.mouseChildren = false;
controls.scrubber.scrubber.buttonMode = true;
volumeDefault();
}
// --------------------------------------------------------------------
// Turn MovieClip into button
// --------------------------------------------------------------------
private function buttonize(button:MovieClip, functionOver, functionOut, functionPress) {
button.addEventListener(MouseEvent.MOUSE_OVER, functionOver);
button.addEventListener(MouseEvent.MOUSE_OUT, functionOut);
button.mouseChildren = false;
button.buttonMode = true;
button.addEventListener(MouseEvent.CLICK, functionPress);
}
// --------------------------------------------------------------------
// Scrubber methods
// --------------------------------------------------------------------
function scrubberShowTimerOver():void {
controls.scrubber.addEventListener(MouseEvent.MOUSE_OVER, scrubberOver);
controls.scrubber.addEventListener(MouseEvent.MOUSE_OUT, scrubberOut);
}
function scrubberHideTimerOver():void {
controls.scrubber.removeEventListener(MouseEvent.MOUSE_OVER, scrubberOver);
controls.scrubber.removeEventListener(MouseEvent.MOUSE_OUT, scrubberOut);
}
function scrubberDown(event:MouseEvent):void {
scrubberHideTimerOver();
scrubberClick();
clearInterval(interval);
interval = intervalInit(1);
controls.scrubber.scrubber.startDrag(false, new Rectangle(0, controls.scrubber.scrubber.y, controls.scrubber.container.width, 0));
stage.addEventListener(MouseEvent.MOUSE_UP, scrubberUp);
}
function scrubberUp(event:MouseEvent):void {
scrubberShowTimerOver();
stage.removeEventListener(MouseEvent.MOUSE_UP, scrubberUp);
controls.scrubber.scrubber.stopDrag();
scrubIt();
scrubberOut(event);
}
function scrubIt():void {
stage.dispatchEvent(new MediaEvent('seek', seeking((controls.scrubber.scrubber.x/controls.scrubber.container.width)*duration)));
}
function scrubberOver(event:MouseEvent):void {
clearInterval(interval);
interval = intervalInit(2);
controlsShowTimer();
}
function scrubberOut(event:MouseEvent):void {
clearInterval(interval);
interval = intervalInit(0);
controlsHideTimer();
}
function scrubberClick():void {
if (!played)
stage.dispatchEvent(new Event('play'));
}
function btnOver(event:MouseEvent):void {
event.currentTarget.gotoAndPlay('over');
}
function btnOut(event:MouseEvent):void {
event.currentTarget.gotoAndPlay('out');
}
private function controlsChange():void {
if (played) {
controls.playBtn.visible = false;
controls.pauseBtn.visible = true;
} else {
controls.playBtn.visible = true;
controls.pauseBtn.visible = false;
}
}
function pressFullScreen(event:Event):void {
if (stage.displayState == StageDisplayState.NORMAL) {
stage.displayState = StageDisplayState.FULL_SCREEN;
} else {
stage.displayState = StageDisplayState.NORMAL;
}
}
function pressToggle(event:Event):void {
if (played)
pressPause(event);
else
pressResume(event);
}
function pressResume(event:Event):void {
if (settings.autoplay == false) {
stage.dispatchEvent(new Event('play'));
settings.autoplay = true;
} else {
stage.dispatchEvent(new Event('resume'));
}
controlsChange();
}
function pressPause(event:Event):void {
stage.dispatchEvent(new Event('pause'));
controlsChange();
}
function pressSound(event:Event):void {
soundToggle();
}
function pressScrubber(event:Event):void {
stage.dispatchEvent(new MediaEvent('seek', seeking(mouse2Time())));
}
// --------------------------------------------------------------------
//
// Sound methods
//
// --------------------------------------------------------------------
private function soundInit(event:Event):void {
debug('soundInit');
soundSet(settings.soundVolume);
}
private function soundToggle():void {
if (ns.soundTransform.volume > 0)
soundSet(0);
else
soundSet(settings.soundVolume);
}
private function soundSet(volume:Number):void {
if (media) {
volumeReflect(volume, ns.soundTransform.volume);
ns.soundTransform = new SoundTransform(volume);
} else {
volumeReflect(volume, channel.soundTransform.volume);
channel.soundTransform = new SoundTransform(volume);
}
}
// --------------------------------------------------------------------
//
// Buffer methods
//
// --------------------------------------------------------------------
private function showBuffer():void {
status.buffer.visible = true;
clearInterval(interval);
interval = intervalInit(3);
}
private function hideBuffer():void {
status.buffer.visible = false;
clearInterval(interval);
interval = intervalInit(0);
}
// --------------------------------------------------------------------
//
// Status methods
//
// --------------------------------------------------------------------
private function statusHide():void {
status.visible = false;
}
private function statusShow():void {
status.visible = true;
}
private function statusToggle():void {
status.visible = !status.visible;
}
private function statusInit(event:Event):void {
debug('statusInit');
hideBuffer();
status.heading.content.text = settings.name;
status.heading.content.autoSize = TextFieldAutoSize.LEFT;
status.heading.addEventListener(MouseEvent.CLICK, goMedia);
linkify(status.heading);
stage.dispatchEvent(new Event('statusLoaded'));
}
function linkify(object):void {
object.addEventListener(MouseEvent.MOUSE_OVER, textRollOver);
object.addEventListener(MouseEvent.MOUSE_OUT, textRollOut);
object.buttonMode = true;
object.mouseChildren = false;
textBasic(object);
}
function textBasic(object):void {
textChange(object, settings.linkColor);
}
function textHover(object):void {
textChange(object, settings.hoverColor);
}
function textChange(object, color):void {
var original = object.content.text;
object.content.htmlText = '<font color="#' + color + '">' + original + '</font>';
}
function textRollOut(e:MouseEvent):void {
textBasic(e.currentTarget);
}
function textRollOver(e:MouseEvent):void {
textHover(e.currentTarget);
}
function goMedia(event:Event):void {
goLink(settings.link);
}
function goLink(link):void {
var request:URLRequest = new URLRequest(link);
try {
navigateToURL(request, '_blank');
} catch (error:Error) {
debug('URL Request failed on: ' + link);
}
}
// --------------------------------------------------------------------
//
// Stream methods
//
// --------------------------------------------------------------------
private function streamInit(event:Event):void {
debug('streamInit');
if (media) {
video = new Video();
video.x = 0;
video.y = 0;
video.attachNetStream(ns);
videoScreen.addChild(video);
linkStreamMethods();
} else {
audio = new Sound();
channel = new SoundChannel();
audio.load(new URLRequest(path));
linkAudioMethods();
}
if (settings.autoplay)
stage.dispatchEvent(new Event('play'));
stage.dispatchEvent(new Event('streamLoaded'));
}
private function linkAudioMethods():void {
stage.addEventListener('play', audioPlay);
stage.addEventListener('resume', audioResume);
stage.addEventListener('pause', audioPause);
}
private function linkStreamMethods():void {
stage.addEventListener('play', nsPlay);
stage.addEventListener('resume', nsResume);
stage.addEventListener('pause', nsPause);
stage.addEventListener('seek', nsSeek);
}
private function audioPlay(event:Event):void {
channel = audio.play();
soundSet(settings.soundVolume);
nsTogglePlayed();
}
private function audioResume(event:Event):void {
channel = audio.play(position);
nsTogglePlayed();
}
private function audioPause(event:Event):void {
position = channel.position;
nsTogglePlayed();
channel.stop();
}
private function nsPlay(event:Event):void {
thumbHide();
ns.play(path);
nsTogglePlayed();
debug('Video ' + path + ' is playing');
}
private function nsResume(event:Event):void {
nsTogglePlayed();
statusHide();
ns.resume();
}
private function nsPause(event:Event):void {
nsTogglePlayed();
statusShow();
ns.pause();
}
private function nsTogglePlayed():void {
played = !played;
if ( ! started) {
started = true;
controlsSwitch(true);
}
debug('Playing' + String(played));
}
private function nsSeek(event:MediaEvent):void {
ns.seek(event.data.seconds);
}
// --------------------------------------------------------------------
//
// Thumb methods
//
// --------------------------------------------------------------------
private function thumbInit(event:Event):void {
debug('thumbInit');
var thumbLoader:Loader = new Loader();
var thumb:URLRequest = new URLRequest(settings.thumb);
thumbLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, thumbLoaded);
thumbLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, thumbProgress);
thumbLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, thumbError);
thumbLoader.load(thumb);
thumbScreen.addChild(thumbLoader);
}
private function thumbHide():void {
thumbScreen.visible = false;
}
private function thumbProgress(event:ProgressEvent):void {
trace(Math.round((event.bytesLoaded/event.bytesTotal)*100) + '%');
}
/**
* thumbLoaded
*
* ThumbLoaded => dispatch thumbLoaded event
* to proceed.
*/
private function thumbLoaded(event:Event):void {
curtainHide();
stage.dispatchEvent(new Event('thumbLoaded'));
debug('Thumb ' + settings.thumb + ' was loaded');
}
/**
* thumbError
*
* ThumbError => dispatch thumbLoaded event
* and try to proceed without thumb.
*/
private function thumbError(event:IOErrorEvent):void {
curtainHide();
stage.dispatchEvent(new Event('thumbLoaded'));
debug('ioErrorHandler: ' + event.text);
}
// --------------------------------------------------------------------
//
// Curtain methods
//
// --------------------------------------------------------------------
private function curtainResize():void {
curtain.width = stage.stageWidth;
curtain.height = stage.stageHeight;
}
private function curtainHide():void {
curtain.visible = false;
}
private function curtainShow():void {
curtain.visible = true;
}
private function curtainToggle():void {
curtain.visible = !curtain.visible;
}
// --------------------------------------------------------------------
//
// NetStream methods
//
// --------------------------------------------------------------------
private function prepare():void {
debug('prepate');
media = setMediaType();
nc = new NetConnection();
nc.connect(null);
ns = new NetStream(nc);
meta = new Object();
meta.onMetaData = onMetaData;
ns.client = meta;
ns.bufferTime = settings.buffer;
ns.addEventListener(NetStatusEvent.NET_STATUS, netStreamStatus);
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
stage.dispatchEvent(new Event('prepared'));
}
private function setMediaType():Boolean {
if (settings.audio == false) {
path = settings.video;
return true;
} else {
path = settings.audio;
return false;
}
}
private function onMetaData(metaData:Object):void {
video.width = metaData.width;
video.height = metaData.height;
duration = metaData.duration;
}
function asyncErrorHandler(event:AsyncErrorEvent):void {
debug(event.text);
}
private function netStreamStatus(event:NetStatusEvent):void {
switch(event.info.code)
{
case 'NetStream.FileStructureInvalid':
{
debug('NetStream.FileStructureInvalid');
break;
}
case 'NetStream.NoSupportedTrackFound':
{
debug('NetStream.NoSupportedTrackFound');
break;
}
case 'NetStream.Buffer.Full': // buffer is full
{
debug('NetStream.Buffer.Full');
ns.bufferTime = settings.exapndedBuffer;
hideBuffer();
break;
}
case 'NetStream.Buffer.Empty': // buffer is empty
{
debug('NetStream.Buffer.Empty');
ns.bufferTime = settings.buffer;
if (ns.bytesLoaded < ns.bytesTotal) {
showBuffer();
}
break;
}
case 'NetStream.Play.Start': // ns.play() fires start
{
debug('NetStream.Play.Start');
showBuffer();
break;
}
case 'NetStream.Seek.Notify': // ns.seek() fires notify (scrubber / rewind)
{
debug('NetStream.Seek.Notify');
showBuffer();
break;
}
case 'NetStream.Seek.InvalidTime': // Scrubber ahead of loaded
{
debug('NetStream.Seek.InvalidTime');
break;
}
case 'NetStream.Play.Stop': // End of netStream
{
debug('NetStream.Play.Stop');
stage.dispatchEvent(new MediaEvent('seek', seeking(0)));
controls.pauseBtn.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
break;
}
case 'NetStream.Play.Flush': // Flush of netStream
{
debug('NetStream.Play.Flush');
break;
}
}
}
private function seeking(seconds:int):Object {
var seeking = new Object();
seeking.seconds = seconds;
return seeking;
}
// --------------------------------------------------------------------
//
// Settings methods
//
// --------------------------------------------------------------------
private function settingsFactory(settings:Object):Object {
for (var key in factory) {
if (settings[key] == undefined)
settings[key] = factory[key];
}
return settings;
}
// --------------------------------------------------------------------
//
// Support methods
//
// --------------------------------------------------------------------
private function debug(message:String):void {
if (settings.debug == true)
trace(message);
}
// --------------------------------------------------------------------
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment