package { import flash.display.*; import flash.events.*; import flash.media.*; import flash.net.*; import flash.text.*; import flash.system.*; import flash.media.Video; import flash.net.NetConnection; import flash.net.NetStream; import flash.geom.ColorTransform; import flash.filters.DropShadowFilter; import flash.utils.Timer; import flash.external.ExternalInterface; import flash.geom.Rectangle; import htmlelements.IMediaElement; import htmlelements.VideoElement; import htmlelements.AudioElement; import htmlelements.YouTubeElement; public class FlashMediaElement extends MovieClip { private var _mediaUrl:String; private var _autoplay:Boolean; private var _preload:String; private var _debug:Boolean; private var _isVideo:Boolean; private var _video:DisplayObject; private var _timerRate:Number; private var _stageWidth:Number; private var _stageHeight:Number; private var _enableSmoothing:Boolean; private var _allowedPluginDomain:String; private var _isFullScreen:Boolean = false; private var _startVolume:Number; private var _controlStyle:String; private var _autoHide:Boolean = true; private var _streamer:String = ""; private var _enablePseudoStreaming:Boolean; private var _pseudoStreamingStartQueryParam:String; // native video size (from meta data) private var _nativeVideoWidth:Number = 0; private var _nativeVideoHeight:Number = 0; // visual elements private var _output:TextField; private var _fullscreenButton:SimpleButton; // media private var _mediaElement:IMediaElement; // connection to fullscreen private var _connection:LocalConnection; private var _connectionName:String; //private var fullscreen_btn:SimpleButton; // CONTROLS private var _alwaysShowControls:Boolean; private var _controlBar:MovieClip; private var _controlBarBg:MovieClip; private var _scrubBar:MovieClip; private var _scrubTrack:MovieClip; private var _scrubOverlay:MovieClip; private var _scrubLoaded:MovieClip; private var _hoverTime:MovieClip; private var _hoverTimeText:TextField; private var _playButton:SimpleButton; private var _pauseButton:SimpleButton; private var _duration:TextField; private var _currentTime:TextField; private var _fullscreenIcon:SimpleButton; private var _volumeMuted:SimpleButton; private var _volumeUnMuted:SimpleButton; private var _scrubTrackColor:String; private var _scrubBarColor:String; private var _scrubLoadedColor:String; // IDLE Timer for mouse for showing/hiding controls private var _inactiveTime:int; private var _timer:Timer; private var _idleTime:int; private var _isMouseActive:Boolean private var _isOverStage:Boolean = false; // security checkes private var securityIssue:Boolean = false; // When SWF parameters contain illegal characters private var directAccess:Boolean = false; // When SWF visited directly with no parameters (or when security issue detected) public function FlashMediaElement() { // check for security issues (borrowed from jPLayer) checkFlashVars(loaderInfo.parameters); // allows this player to be called from a different domain than the HTML page hosting the player //Security.allowDomain("*"); //Security.allowInsecureDomain('*'); // add debug output _output = new TextField(); _output.textColor = 0xeeeeee; _output.width = stage.stageWidth - 100; _output.height = stage.stageHeight; _output.multiline = true; _output.wordWrap = true; _output.border = false; _output.filters = [new DropShadowFilter(1, 0x000000, 45, 1, 2, 2, 1)]; _output.text = "Initializing...\n"; addChild(_output); _output.visible = securityIssue; if (securityIssue) { _output.text = "WARNING: Security issue detected. Player stopped."; return; } // get parameters // Use only FlashVars, ignore QueryString var params:Object, pos:int, query:Object; params = LoaderInfo(this.root.loaderInfo).parameters; pos = root.loaderInfo.url.indexOf('?'); if (pos !== -1) { query = parseStr(root.loaderInfo.url.substr(pos + 1)); for (var key:String in params) { if (query.hasOwnProperty(trim(key))) { delete params[key]; } } } _mediaUrl = (params['file'] != undefined) ? String(params['file']) : ""; _autoplay = (params['autoplay'] != undefined) ? (String(params['autoplay']) == "true") : false; _debug = (params['debug'] != undefined) ? (String(params['debug']) == "true") : false; _isVideo = (params['isvideo'] != undefined) ? ((String(params['isvideo']) == "false") ? false : true ) : true; _timerRate = (params['timerrate'] != undefined) ? (parseInt(params['timerrate'], 10)) : 250; _alwaysShowControls = (params['controls'] != undefined) ? (String(params['controls']) == "true") : false; _enableSmoothing = (params['smoothing'] != undefined) ? (String(params['smoothing']) == "true") : false; _startVolume = (params['startvolume'] != undefined) ? (parseFloat(params['startvolume'])) : 0.8; _preload = (params['preload'] != undefined) ? params['preload'] : "none"; _controlStyle = (params['controlstyle'] != undefined) ? (String(params['controlstyle'])) : ""; // blank or "floating" _autoHide = (params['autohide'] != undefined) ? (String(params['autohide'])) : true; _scrubTrackColor = (params['scrubtrackcolor'] != undefined) ? (String(params['scrubtrackcolor'])) : "0x333333"; _scrubBarColor = (params['scrubbarcolor'] != undefined) ? (String(params['scrubbarcolor'])) : "0xefefef"; _scrubLoadedColor = (params['scrubloadedcolor'] != undefined) ? (String(params['scrubloadedcolor'])) : "0x3CACC8"; _enablePseudoStreaming = (params['pseudostreaming'] != undefined) ? (String(params['pseudostreaming']) == "true") : false; _pseudoStreamingStartQueryParam = (params['pseudostreamstart'] != undefined) ? (String(params['pseudostreamstart'])) : "start"; _streamer = (params['flashstreamer'] != undefined) ? (String(params['flashstreamer'])) : ""; _output.visible = _debug; if (isNaN(_timerRate)) _timerRate = 250; // setup stage and player sizes/scales stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; _stageWidth = stage.stageWidth; _stageHeight = stage.stageHeight; //_autoplay = true; //_mediaUrl = "http://mediafiles.dts.edu/chapel/mp4/20100609.mp4"; //_alwaysShowControls = true; //_mediaUrl = "../media/Parades-PastLives.mp3"; //_mediaUrl = "../media/echo-hereweare.mp4"; //_mediaUrl = "http://video.ted.com/talks/podcast/AlGore_2006_480.mp4"; //_mediaUrl = "rtmp://stream2.france24.yacast.net/france24_live/en/f24_liveen"; //_mediaUrl = "http://www.youtube.com/watch?feature=player_embedded&v=yyWWXSwtPP0"; // hosea //_mediaUrl = "http://www.youtube.com/watch?feature=player_embedded&v=m5VDDJlsD6I"; // railer with notes //_alwaysShowControls = true; //_debug=true; // position and hide _fullscreenButton = getChildByName("fullscreen_btn") as SimpleButton; //_fullscreenButton.visible = false; _fullscreenButton.alpha = 0; _fullscreenButton.addEventListener(MouseEvent.CLICK, fullscreenClick, false); _fullscreenButton.x = stage.stageWidth - _fullscreenButton.width; _fullscreenButton.y = stage.stageHeight - _fullscreenButton.height; // create media element if (_isVideo) { if (_mediaUrl.indexOf("youtube.com") > -1 || _mediaUrl.indexOf("youtu.be") > -1) { //Security.allowDomain("http://www.youtube.com"); _mediaElement = new YouTubeElement(this, _autoplay, _preload, _timerRate, _startVolume); _video = (_mediaElement as YouTubeElement).player; // these are set and then used once the player is loaded (_mediaElement as YouTubeElement).initWidth = _stageWidth; (_mediaElement as YouTubeElement).initHeight = _stageHeight; } else { _mediaElement = new VideoElement(this, _autoplay, _preload, _timerRate, _startVolume, _streamer); _video = (_mediaElement as VideoElement).video; _video.width = _stageWidth; _video.height = _stageHeight; (_video as Video).smoothing = _enableSmoothing; (_mediaElement as VideoElement).setReference(this); (_mediaElement as VideoElement).setPseudoStreaming(_enablePseudoStreaming); (_mediaElement as VideoElement).setPseudoStreamingStartParam(_pseudoStreamingStartQueryParam); //_video.scaleMode = VideoScaleMode.MAINTAIN_ASPECT_RATIO; addChild(_video); } } else { //var player2:AudioDecoder = new com.automatastudios.audio.audiodecoder.AudioDecoder(); _mediaElement = new AudioElement(this, _autoplay, _preload, _timerRate, _startVolume); } // controls! _controlBar = getChildByName("controls_mc") as MovieClip; _controlBarBg = _controlBar.getChildByName("controls_bg_mc") as MovieClip; _scrubTrack = _controlBar.getChildByName("scrubTrack") as MovieClip; _scrubBar = _controlBar.getChildByName("scrubBar") as MovieClip; _scrubOverlay = _controlBar.getChildByName("scrubOverlay") as MovieClip; _scrubLoaded = _controlBar.getChildByName("scrubLoaded") as MovieClip; _scrubOverlay.buttonMode = true; _scrubOverlay.useHandCursor = true applyColor(_scrubTrack, _scrubTrackColor); applyColor(_scrubBar, _scrubBarColor); applyColor(_scrubLoaded, _scrubLoadedColor); _fullscreenIcon = _controlBar.getChildByName("fullscreenIcon") as SimpleButton; // New fullscreenIcon for new fullscreen floating controls //if(_alwaysShowControls && _controlStyle.toUpperCase()=="FLOATING") { _fullscreenIcon.addEventListener(MouseEvent.CLICK, fullScreenIconClick, false); //} _volumeMuted = _controlBar.getChildByName("muted_mc") as SimpleButton; _volumeUnMuted = _controlBar.getChildByName("unmuted_mc") as SimpleButton; _volumeMuted.addEventListener(MouseEvent.CLICK, toggleVolume, false); _volumeUnMuted.addEventListener(MouseEvent.CLICK, toggleVolume, false); _playButton = _controlBar.getChildByName("play_btn") as SimpleButton; _playButton.addEventListener(MouseEvent.CLICK, function(e:MouseEvent) { _mediaElement.play(); }); _pauseButton = _controlBar.getChildByName("pause_btn") as SimpleButton; _pauseButton.addEventListener(MouseEvent.CLICK, function(e:MouseEvent) { _mediaElement.pause(); }); _pauseButton.visible = false; _duration = _controlBar.getChildByName("duration_txt") as TextField; _currentTime = _controlBar.getChildByName("currentTime_txt") as TextField; _hoverTime = _controlBar.getChildByName("hoverTime") as MovieClip; _hoverTimeText = _hoverTime.getChildByName("hoverTime_txt") as TextField; _hoverTime.visible=false; _hoverTime.y=(_hoverTime.height/2)+1; _hoverTime.x=0; // Add new timeline scrubber events _scrubOverlay.addEventListener(MouseEvent.MOUSE_MOVE, scrubMove); _scrubOverlay.addEventListener(MouseEvent.CLICK, scrubClick); _scrubOverlay.addEventListener(MouseEvent.MOUSE_OVER, scrubOver); _scrubOverlay.addEventListener(MouseEvent.MOUSE_OUT, scrubOut); if (_autoHide) { // && _alwaysShowControls) { // Add mouse activity for show/hide of controls stage.addEventListener(Event.MOUSE_LEAVE, mouseActivityLeave); stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseActivityMove); _inactiveTime = 2500; _timer = new Timer(_inactiveTime) _timer.addEventListener(TimerEvent.TIMER, idleTimer); _timer.start(); // set } if(_startVolume<=0) { trace("INITIAL VOLUME: "+_startVolume+" MUTED"); _volumeMuted.visible=true; _volumeUnMuted.visible=false; } else { trace("INITIAL VOLUME: "+_startVolume+" UNMUTED"); _volumeMuted.visible=false; _volumeUnMuted.visible=true; } _controlBar.visible = _alwaysShowControls; setControlDepth(); _output.appendText("stage: " + stage.stageWidth + "x" + stage.stageHeight + "\n"); _output.appendText("file: " + _mediaUrl + "\n"); _output.appendText("autoplay: " + _autoplay.toString() + "\n"); _output.appendText("preload: " + _preload.toString() + "\n"); _output.appendText("isvideo: " + _isVideo.toString() + "\n"); _output.appendText("smoothing: " + _enableSmoothing.toString() + "\n"); _output.appendText("timerrate: " + _timerRate.toString() + "\n"); _output.appendText("displayState: " +(stage.hasOwnProperty("displayState")).toString() + "\n"); // attach javascript _output.appendText("ExternalInterface.available: " + ExternalInterface.available.toString() + "\n"); _output.appendText("ExternalInterface.objectID: " + ((ExternalInterface.objectID != null)? ExternalInterface.objectID.toString() : "null") + "\n"); if (_mediaUrl != "") { _mediaElement.setSrc(_mediaUrl); } positionControls(); // Fire this once just to set the width on some dynamically sized scrub bar items; _scrubBar.scaleX=0; _scrubLoaded.scaleX=0; if (ExternalInterface.available) { // && !_alwaysShowControls _output.appendText("Adding callbacks...\n"); try { if (ExternalInterface.objectID != null && ExternalInterface.objectID.toString() != "") { // add HTML media methods ExternalInterface.addCallback("playMedia", playMedia); ExternalInterface.addCallback("loadMedia", loadMedia); ExternalInterface.addCallback("pauseMedia", pauseMedia); ExternalInterface.addCallback("stopMedia", stopMedia); ExternalInterface.addCallback("setSrc", setSrc); ExternalInterface.addCallback("setCurrentTime", setCurrentTime); ExternalInterface.addCallback("setVolume", setVolume); ExternalInterface.addCallback("setMuted", setMuted); ExternalInterface.addCallback("setFullscreen", setFullscreen); ExternalInterface.addCallback("setVideoSize", setVideoSize); ExternalInterface.addCallback("positionFullscreenButton", positionFullscreenButton); ExternalInterface.addCallback("hideFullscreenButton", hideFullscreenButton); // fire init method ExternalInterface.call("mejs.MediaPluginBridge.initPlugin", ExternalInterface.objectID); } _output.appendText("Success...\n"); } catch (error:SecurityError) { _output.appendText("A SecurityError occurred: " + error.message + "\n"); } catch (error:Error) { _output.appendText("An Error occurred: " + error.message + "\n"); } } if (_preload != "none") { _mediaElement.load(); if (_autoplay) { _mediaElement.play(); } } else if (_autoplay) { _mediaElement.load(); _mediaElement.play(); } // listen for resize stage.addEventListener(Event.RESIZE, resizeHandler); // send click events up to javascript stage.addEventListener(MouseEvent.CLICK, stageClicked); // resize stage.addEventListener(FullScreenEvent.FULL_SCREEN, stageFullScreenChanged); } public function setControlDepth():void { // put these on top addChild(_output); addChild(_controlBar); addChild(_fullscreenButton); } // borrowed from jPLayer // https://github.com/happyworm/jPlayer/blob/e8ca190f7f972a6a421cb95f09e138720e40ed6d/actionscript/Jplayer.as#L228 private function checkFlashVars(p:Object):void { var i:Number = 0; for (var s:String in p) { if (isIllegalChar(p[s], s === 'file')) { securityIssue = true; // Illegal char found } i++; } if(i === 0 || securityIssue) { directAccess = true; } } private static function parseStr (str:String) : Object { var hash:Object = {}, arr1:Array, arr2:Array; str = unescape(str).replace(/\+/g, " "); arr1 = str.split('&'); if (!arr1.length) { return {}; } for (var i:uint = 0, length:uint = arr1.length; i < length; i++) { arr2 = arr1[i].split('='); if (!arr2.length) { continue; } hash[trim(arr2[0])] = trim(arr2[1]); } return hash; } private static function trim(str:String) : String { if (!str) { return str; } return str.toString().replace(/^\s*/, '').replace(/\s*$/, ''); } private function isIllegalChar(s:String, isUrl:Boolean):Boolean { var illegals:String = "' \" ( ) { } * + \\ < >"; if(isUrl) { illegals = "\" { } \\ < >"; } if(Boolean(s)) { // Otherwise exception if parameter null. for each (var illegal:String in illegals.split(' ')) { if(s.indexOf(illegal) >= 0) { return true; // Illegal char found } } } return false; } // START: Controls and events function mouseActivityMove(event:MouseEvent):void { // if mouse is in the video area if (_autoHide && (mouseX>=0 && mouseX<=stage.stageWidth) && (mouseY>=0 && mouseY<=stage.stageHeight)) { // This could be move to a nice fade at some point... _controlBar.visible = (_alwaysShowControls || _isFullScreen); _isMouseActive = true; _idleTime = 0; _timer.reset(); _timer.start() } } function mouseActivityLeave(event:Event):void { if (_autoHide) { _isOverStage = false; // This could be move to a nice fade at some point... _controlBar.visible = false; _isMouseActive = false; _idleTime = 0; _timer.reset(); _timer.stop(); } } function idleTimer(event:TimerEvent):void { if (_autoHide) { // This could be move to a nice fade at some point... _controlBar.visible = false; _isMouseActive = false; _idleTime += _inactiveTime; _idleTime = 0; _timer.reset(); _timer.stop(); } } function scrubMove(event:MouseEvent):void { //if (_alwaysShowControls) { if (_hoverTime.visible) { var seekBarPosition:Number = ((event.localX / _scrubTrack.width) *_mediaElement.duration())*_scrubTrack.scaleX; var hoverPos:Number = (seekBarPosition / _mediaElement.duration()) *_scrubTrack.scaleX; if (_isFullScreen) { _hoverTime.x=event.target.parent.mouseX; } else { _hoverTime.x=mouseX; } _hoverTime.y = _scrubBar.y - (_hoverTime.height/2); _hoverTimeText.text = secondsToTimeCode(seekBarPosition); } //} //trace(event); } function scrubOver(event:MouseEvent):void { _hoverTime.y = _scrubBar.y-(_hoverTime.height/2)+1; _hoverTime.visible = true; trace(event); } function scrubOut(event:MouseEvent):void { _hoverTime.y = _scrubBar.y+(_hoverTime.height/2)+1; _hoverTime.visible = false; //_hoverTime.x=0; //trace(event); } function scrubClick(event:MouseEvent):void { //trace(event); var seekBarPosition:Number = ((event.localX / _scrubTrack.width) *_mediaElement.duration())*_scrubTrack.scaleX; var tmp:Number = (_mediaElement.currentTime()/_mediaElement.duration())*_scrubTrack.width; var canSeekToPosition:Boolean = _scrubLoaded.scaleX > (seekBarPosition / _mediaElement.duration()) *_scrubTrack.scaleX; //var canSeekToPosition:Boolean = true; /* amountLoaded = ns.bytesLoaded / ns.bytesTotal; loader.loadbar._width = amountLoaded * 208.9; loader.scrub._x = ns.time / duration * 208.9; */ trace("seekBarPosition:"+seekBarPosition, "CanSeekToPosition: "+canSeekToPosition); if (seekBarPosition>0 && seekBarPosition<_mediaElement.duration() && canSeekToPosition) { _mediaElement.setCurrentTime(seekBarPosition); } } function toggleVolume(event:MouseEvent):void { trace(event.currentTarget.name); switch(event.currentTarget.name) { case "muted_mc": setMuted(false); break; case "unmuted_mc": setMuted(true); break; } } function toggleVolumeIcons(volume:Number) { if(volume<=0) { _volumeMuted.visible = true; _volumeUnMuted.visible = false; } else { _volumeMuted.visible = false; _volumeUnMuted.visible = true; } } public function positionControls(forced:Boolean=false) { if ( _controlStyle.toUpperCase() == "FLOATING" && _isFullScreen) { trace("CONTROLS: floating"); _hoverTime.y=(_hoverTime.height/2)+1; _hoverTime.x=0; _controlBarBg.width = 300; _controlBarBg.height = 93; //_controlBarBg.x = (stage.stageWidth/2) - (_controlBarBg.width/2); //_controlBarBg.y = stage.stageHeight - 300; _pauseButton.scaleX = _playButton.scaleX=3.5; _pauseButton.scaleY= _playButton.scaleY=3.5; // center the play button and make it big and at the top _pauseButton.x = _playButton.x = (_controlBarBg.width/2)-(_playButton.width/2)+7; _pauseButton.y = _playButton.y = _controlBarBg.height-_playButton.height-(14) _controlBar.x = (stage.stageWidth/2) -150; _controlBar.y = stage.stageHeight - _controlBar.height-100; // reposition the time and duration items _duration.x = _controlBarBg.width - _duration.width - 10; _duration.y = _controlBarBg.height - _duration.height -7; //_currentTime.x = _controlBarBg.width - _duration.width - 10 - _currentTime.width - 10; _currentTime.x = 5 _currentTime.y= _controlBarBg.height - _currentTime.height-7; _fullscreenIcon.x = _controlBarBg.width - _fullscreenIcon.width - 7; _fullscreenIcon.y = 7; _volumeMuted.x = _volumeUnMuted.x = 7; _volumeMuted.y = _volumeUnMuted.y = 7; _scrubLoaded.x = _scrubBar.x = _scrubOverlay.x = _scrubTrack.x =_currentTime.x+_currentTime.width+7; _scrubLoaded.y = _scrubBar.y = _scrubOverlay.y = _scrubTrack.y=_controlBarBg.height-_scrubTrack.height-10; _scrubBar.width = _scrubOverlay.width = _scrubTrack.width = (_duration.x-_duration.width-14); } else { trace("CONTROLS: normal, original"); /* // Original style bottom display _hoverTime.y=(_hoverTime.height/2)+1; _hoverTime.x=0; _controlBarBg.width = stage.stageWidth; _controlBar.y = stage.stageHeight - _controlBar.height; _duration.x = stage.stageWidth - _duration.width - 10; //_currentTime.x = stage.stageWidth - _duration.width - 10 - _currentTime.width - 10; _currentTime.x = _playButton.x+_playButton.width; _scrubTrack.width = (_duration.x-_duration.width-10)-_duration.width+10; _scrubOverlay.width = _scrubTrack.width; _scrubBar.width = _scrubTrack.width; */ // FLOATING MODE BOTTOM DISPLAY - similar to normal trace("THAT WAY!"); _hoverTime.y=(_hoverTime.height/2)+1; _hoverTime.x=0; _controlBarBg.width = stage.stageWidth; _controlBarBg.height = 30; _controlBarBg.y=0; _controlBarBg.x=0; // _controlBarBg.x = 0; // _controlBarBg.y = stage.stageHeight - _controlBar.height; _pauseButton.scaleX = _playButton.scaleX=1; _pauseButton.scaleY = _playButton.scaleY=1; _pauseButton.x = _playButton.x = 7; _pauseButton.y = _playButton.y = _controlBarBg.height-_playButton.height-2; //_currentTime.x = stage.stageWidth - _duration.width - 10 - _currentTime.width - 10; _currentTime.x = _playButton.x+_playButton.width; _fullscreenIcon.x = _controlBarBg.width - _fullscreenIcon.width - 7; _fullscreenIcon.y = 8; _volumeMuted.x = _volumeUnMuted.x = _fullscreenIcon.x - _volumeMuted.width - 10; _volumeMuted.y = _volumeUnMuted.y = 10; _duration.x = _volumeMuted.x - _volumeMuted.width - _duration.width + 5; _duration.y = _currentTime.y = _controlBarBg.height - _currentTime.height - 7; _scrubLoaded.x = _scrubBar.x = _scrubOverlay.x = _scrubTrack.x = _currentTime.x + _currentTime.width + 10; _scrubLoaded.y = _scrubBar.y = _scrubOverlay.y = _scrubTrack.y = _controlBarBg.height - _scrubTrack.height - 9; _scrubBar.width = _scrubOverlay.width = _scrubTrack.width = (_duration.x-_duration.width-10)-_duration.width+5; _controlBar.x = 0; _controlBar.y = stage.stageHeight - _controlBar.height; } } // END: Controls function stageClicked(e:MouseEvent):void { //_output.appendText("click: " + e.stageX.toString() +","+e.stageY.toString() + "\n"); if (e.target == stage) { sendEvent("click", ""); } } function resizeHandler(e:Event):void { //_video.scaleX = stage.stageWidth / _stageWidth; //_video.scaleY = stage.stageHeight / _stageHeight; //positionControls(); repositionVideo(); } // START: Fullscreen function enterFullscreen() { _output.appendText("enterFullscreen()\n"); var screenRectangle:Rectangle = new Rectangle(0, 0, flash.system.Capabilities.screenResolutionX, flash.system.Capabilities.screenResolutionY); stage.fullScreenSourceRect = screenRectangle; stage.displayState = StageDisplayState.FULL_SCREEN; repositionVideo(); positionControls(); updateControls(HtmlMediaEvent.FULLSCREENCHANGE); _controlBar.visible = true; _isFullScreen = true; } function exitFullscreen() { stage.displayState = StageDisplayState.NORMAL; _controlBar.visible = false; _isFullScreen = false; } function setFullscreen(gofullscreen:Boolean) { _output.appendText("setFullscreen: " + gofullscreen.toString() + "\n"); try { //_fullscreenButton.visible = false; if (gofullscreen) { enterFullscreen(); } else { exitFullscreen(); } } catch (error:Error) { // show the button when the security error doesn't let it work //_fullscreenButton.visible = true; _fullscreenButton.alpha = 1; _isFullScreen = false; _output.appendText("error setting fullscreen: " + error.message.toString() + "\n"); } } // control bar button/icon function fullScreenIconClick(e:MouseEvent) { try { _controlBar.visible = true; setFullscreen(!_isFullScreen); repositionVideo(); } catch (error:Error) { } } // special floating fullscreen icon function fullscreenClick(e:MouseEvent) { //_fullscreenButton.visible = false; _fullscreenButton.alpha = 0 try { _controlBar.visible = true; setFullscreen(true); repositionVideo(); positionControls(); } catch (error:Error) { } } function stageFullScreenChanged(e:FullScreenEvent) { _output.appendText("fullscreen event: " + e.fullScreen.toString() + "\n"); //_fullscreenButton.visible = false; _fullscreenButton.alpha = 0; _isFullScreen = e.fullScreen; sendEvent(HtmlMediaEvent.FULLSCREENCHANGE, "isFullScreen:" + e.fullScreen ); if (!e.fullScreen) { _controlBar.visible = _alwaysShowControls; } } // END: Fullscreen // START: external interface function playMedia() { _output.appendText("play\n"); _mediaElement.play(); } function loadMedia() { _output.appendText("load\n"); _mediaElement.load(); } function pauseMedia() { _output.appendText("pause\n"); _mediaElement.pause(); } function setSrc(url:String) { _output.appendText("setSrc: " + url + "\n"); _mediaElement.setSrc(url); } function stopMedia() { _output.appendText("stop\n"); _mediaElement.stop(); } function setCurrentTime(time:Number) { _output.appendText("seek: " + time.toString() + "\n"); _mediaElement.setCurrentTime(time); } function setVolume(volume:Number) { _output.appendText("volume: " + volume.toString() + "\n"); _mediaElement.setVolume(volume); toggleVolumeIcons(volume); } function setMuted(muted:Boolean) { _output.appendText("muted: " + muted.toString() + "\n"); _mediaElement.setMuted(muted); toggleVolumeIcons(_mediaElement.getVolume()); } function setVideoSize(width:Number, height:Number) { _output.appendText("setVideoSize: " + width.toString() + "," + height.toString() + "\n"); _stageWidth = width; _stageHeight = height; if (_video != null) { repositionVideo(); positionControls(); //_fullscreenButton.x = stage.stageWidth - _fullscreenButton.width - 10; _output.appendText("result: " + _video.width.toString() + "," + _video.height.toString() + "\n"); } } function positionFullscreenButton(x:Number, y:Number, visibleAndAbove:Boolean ) { _output.appendText("position FS: " + x.toString() + "x" + y.toString() + "\n"); // bottom corner /* _fullscreenButton.x = stage.stageWidth - _fullscreenButton.width _fullscreenButton.y = stage.stageHeight - _fullscreenButton.height; */ // position just above if (visibleAndAbove) { _fullscreenButton.x = x+1; _fullscreenButton.y = y - _fullscreenButton.height+1; } else { _fullscreenButton.x = x; _fullscreenButton.y = y; } // check for oversizing if ((_fullscreenButton.x + _fullscreenButton.width) > stage.stageWidth) _fullscreenButton.x = stage.stageWidth - _fullscreenButton.width; // show it! if (visibleAndAbove) { _fullscreenButton.alpha = 1; } } function hideFullscreenButton() { //_fullscreenButton.visible = false; _fullscreenButton.alpha = 0; } // END: external interface function repositionVideo():void { if (stage.displayState == "fullScreen") { fullscreen = true; } else { fullscreen = false; } _output.appendText("positioning video "+stage.displayState+"\n"); if (_mediaElement is VideoElement) { if (isNaN(_nativeVideoWidth) || isNaN(_nativeVideoHeight) || _nativeVideoWidth <= 0 || _nativeVideoHeight <= 0) { _output.appendText("ERR: I dont' have the native dimension\n"); return; } // calculate ratios var stageRatio, nativeRatio; _video.x = 0; _video.y = 0; if(fullscreen == true) { stageRatio = flash.system.Capabilities.screenResolutionX/flash.system.Capabilities.screenResolutionY; nativeRatio = _nativeVideoWidth/_nativeVideoHeight; // adjust size and position if (nativeRatio > stageRatio) { _mediaElement.setSize(flash.system.Capabilities.screenResolutionX, _nativeVideoHeight * flash.system.Capabilities.screenResolutionX / _nativeVideoWidth); _video.y = flash.system.Capabilities.screenResolutionY/2 - _video.height/2; } else if (stageRatio > nativeRatio) { _mediaElement.setSize(_nativeVideoWidth * flash.system.Capabilities.screenResolutionY / _nativeVideoHeight, flash.system.Capabilities.screenResolutionY); _video.x = flash.system.Capabilities.screenResolutionX/2 - _video.width/2; } else if (stageRatio == nativeRatio) { _mediaElement.setSize(flash.system.Capabilities.screenResolutionX, flash.system.Capabilities.screenResolutionY); } } else { stageRatio = _stageWidth/_stageHeight; nativeRatio = _nativeVideoWidth/_nativeVideoHeight; // adjust size and position if (nativeRatio > stageRatio) { _mediaElement.setSize(_stageWidth, _nativeVideoHeight * _stageWidth / _nativeVideoWidth); _video.y = _stageHeight/2 - _video.height/2; } else if (stageRatio > nativeRatio) { _mediaElement.setSize( _nativeVideoWidth * _stageHeight / _nativeVideoHeight, _stageHeight); _video.x = _stageWidth/2 - _video.width/2; } else if (stageRatio == nativeRatio) { _mediaElement.setSize(_stageWidth, _stageHeight); } } } else if (_mediaElement is YouTubeElement) { if(fullscreen == true) { _mediaElement.setSize(flash.system.Capabilities.screenResolutionX, flash.system.Capabilities.screenResolutionY); } else { _mediaElement.setSize(_stageWidth, _stageHeight); } } positionControls(); } // SEND events to JavaScript public function sendEvent(eventName:String, eventValues:String) { // special video event if (eventName == HtmlMediaEvent.LOADEDMETADATA && _isVideo) { _output.appendText("METADATA RECEIVED: "); try { if (_mediaElement is VideoElement) { _nativeVideoWidth = (_mediaElement as VideoElement).videoWidth; _nativeVideoHeight = (_mediaElement as VideoElement).videoHeight; } } catch (e:Error) { _output.appendText(e.toString() + "\n"); } _output.appendText(_nativeVideoWidth.toString() + "x" + _nativeVideoHeight.toString() + "\n"); if(stage.displayState == "fullScreen" ) { setVideoSize(_nativeVideoWidth, _nativeVideoHeight); } repositionVideo(); } updateControls(eventName); //trace((_mediaElement.duration()*1).toString() + " / " + (_mediaElement.currentTime()*1).toString()); //trace("CurrentProgress:"+_mediaElement.currentProgress()); if (ExternalInterface.objectID != null && ExternalInterface.objectID.toString() != "") { //_output.appendText("event:" + eventName + " : " + eventValues); //trace("event", eventName, eventValues); if (eventValues == null) eventValues == ""; if (_isVideo) { eventValues += (eventValues != "" ? "," : "") + "isFullScreen:" + _isFullScreen; } eventValues = "{" + eventValues + "}"; /* OLD DIRECT METHOD ExternalInterface.call( "function(id, name) { mejs.MediaPluginBridge.fireEvent(id,name," + eventValues + "); }", ExternalInterface.objectID, eventName); */ // use set timeout for performance reasons //if (!_alwaysShowControls) { ExternalInterface.call("setTimeout", "mejs.MediaPluginBridge.fireEvent('" + ExternalInterface.objectID + "','" + eventName + "'," + eventValues + ")",0); //} } } function updateControls(eventName:String):void { //trace("updating controls"); try { // update controls switch (eventName) { case "pause": case "paused": case "ended": _playButton.visible = true; _pauseButton.visible = false; break; case "play": case "playing": _playButton.visible = false; _pauseButton.visible = true; break; } if (eventName == HtmlMediaEvent.TIMEUPDATE || eventName == HtmlMediaEvent.PROGRESS || eventName == HtmlMediaEvent.FULLSCREENCHANGE) { //_duration.text = (_mediaElement.duration()*1).toString(); _duration.text = secondsToTimeCode(_mediaElement.duration()); //_currentTime.text = (_mediaElement.currentTime()*1).toString(); _currentTime.text = secondsToTimeCode(_mediaElement.currentTime()); var pct:Number = (_mediaElement.currentTime() / _mediaElement.duration()) *_scrubTrack.scaleX; _scrubBar.scaleX = pct; _scrubLoaded.scaleX = (_mediaElement.currentProgress()*_scrubTrack.scaleX)/100; } } catch (error:Error) { trace("error: " + error.toString()); } } // START: utility function secondsToTimeCode(seconds:Number):String { var timeCode:String = ""; seconds = Math.round(seconds); var minutes:Number = Math.floor(seconds / 60); timeCode = (minutes >= 10) ? minutes.toString() : "0" + minutes.toString(); seconds = Math.floor(seconds % 60); timeCode += ":" + ((seconds >= 10) ? seconds.toString() : "0" + seconds.toString()); return timeCode; //minutes.toString() + ":" + seconds.toString(); } function applyColor(item:Object, color:String):void { var myColor:ColorTransform = item.transform.colorTransform; myColor.color = Number(color); item.transform.colorTransform = myColor; } // END: utility } }