gyorgy@0: package gyorgy@0: { gyorgy@0: import flash.display.*; gyorgy@0: import flash.events.*; gyorgy@0: import flash.media.*; gyorgy@0: import flash.net.*; gyorgy@0: import flash.text.*; gyorgy@0: import flash.system.*; gyorgy@0: gyorgy@0: import flash.media.Video; gyorgy@0: import flash.net.NetConnection; gyorgy@0: import flash.net.NetStream; gyorgy@0: gyorgy@0: import flash.filters.DropShadowFilter; gyorgy@0: import flash.utils.Timer; gyorgy@0: import flash.external.ExternalInterface; gyorgy@0: import flash.geom.Rectangle; gyorgy@0: gyorgy@0: import htmlelements.IMediaElement; gyorgy@0: import htmlelements.VideoElement; gyorgy@0: import htmlelements.AudioElement; gyorgy@0: gyorgy@0: public class FlashMediaElement extends MovieClip { gyorgy@0: gyorgy@0: private var _mediaUrl:String; gyorgy@0: private var _autoplay:Boolean; gyorgy@0: private var _preload:String; gyorgy@0: private var _debug:Boolean; gyorgy@0: private var _isVideo:Boolean; gyorgy@0: private var _video:Video; gyorgy@0: private var _timerRate:Number; gyorgy@0: private var _stageWidth:Number; gyorgy@0: private var _stageHeight:Number; gyorgy@0: private var _enableSmoothing:Boolean; gyorgy@0: private var _allowedPluginDomain:String; gyorgy@0: private var _isFullScreen:Boolean = false; gyorgy@0: private var _startVolume:Number; gyorgy@0: gyorgy@0: // native video size (from meta data) gyorgy@0: private var _nativeVideoWidth:Number = 0; gyorgy@0: private var _nativeVideoHeight:Number = 0; gyorgy@0: gyorgy@0: // visual elements gyorgy@0: private var _output:TextField; gyorgy@0: private var _fullscreenButton:SimpleButton; gyorgy@0: gyorgy@0: // media gyorgy@0: private var _mediaElement:IMediaElement; gyorgy@0: gyorgy@0: // connection to fullscreen gyorgy@0: private var _connection:LocalConnection; gyorgy@0: private var _connectionName:String; gyorgy@0: gyorgy@0: //private var fullscreen_btn:SimpleButton; gyorgy@0: gyorgy@0: // CONTROLS gyorgy@0: private var _showControls:Boolean; gyorgy@0: private var _controlBar:MovieClip; gyorgy@0: private var _controlBarBg:MovieClip; gyorgy@0: private var _playButton:SimpleButton; gyorgy@0: private var _pauseButton:SimpleButton; gyorgy@0: private var _duration:TextField; gyorgy@0: private var _currentTime:TextField; gyorgy@0: gyorgy@0: gyorgy@0: public function FlashMediaElement() { gyorgy@0: gyorgy@0: // show allow this player to be called from a different domain than the HTML page hosting the player gyorgy@0: Security.allowDomain("*"); gyorgy@0: gyorgy@0: // get parameters gyorgy@0: var params:Object = LoaderInfo(this.root.loaderInfo).parameters; gyorgy@0: _mediaUrl = (params['file'] != undefined) ? String(params['file']) : ""; gyorgy@0: _autoplay = (params['autoplay'] != undefined) ? (String(params['autoplay']) == "true") : false; gyorgy@0: _debug = (params['debug'] != undefined) ? (String(params['debug']) == "true") : false; gyorgy@0: _isVideo = (params['isvideo'] != undefined) ? ((String(params['isvideo']) == "false") ? false : true ) : true; gyorgy@0: _timerRate = (params['timerrate'] != undefined) ? (parseInt(params['timerrate'], 10)) : 250; gyorgy@0: _showControls = (params['controls'] != undefined) ? (String(params['controls']) == "true") : false; gyorgy@0: _enableSmoothing = (params['smoothing'] != undefined) ? (String(params['smoothing']) == "true") : false; gyorgy@0: _startVolume = (params['startvolume'] != undefined) ? (parseFloat(params['startvolume'])) : 0.8; gyorgy@0: _preload = (params['preload'] != undefined) ? params['preload'] : "none"; gyorgy@0: gyorgy@0: if (isNaN(_timerRate)) gyorgy@0: _timerRate = 250; gyorgy@0: gyorgy@0: // setup stage and player sizes/scales gyorgy@0: stage.align = StageAlign.TOP_LEFT; gyorgy@0: stage.scaleMode = StageScaleMode.NO_SCALE; gyorgy@0: _stageWidth = stage.stageWidth; gyorgy@0: _stageHeight = stage.stageHeight; gyorgy@0: gyorgy@0: //_autoplay = true; gyorgy@0: //_mediaUrl = "http://mediafiles.dts.edu/chapel/mp4/20100609.mp4"; gyorgy@0: //_mediaUrl = "../media/Parades-PastLives.mp3"; gyorgy@0: //_mediaUrl = "../media/echo-hereweare.mp4"; gyorgy@0: gyorgy@0: //_mediaUrl = "http://video.ted.com/talks/podcast/AlGore_2006_480.mp4"; gyorgy@0: //_mediaUrl = "rtmp://stream2.france24.yacast.net/france24_live/en/f24_liveen"; gyorgy@0: gyorgy@0: //_debug=true; gyorgy@0: gyorgy@0: // position and hide gyorgy@0: _fullscreenButton = getChildByName("fullscreen_btn") as SimpleButton; gyorgy@0: _fullscreenButton.visible = false; gyorgy@0: _fullscreenButton.addEventListener(MouseEvent.CLICK, fullscreenClick, false); gyorgy@0: _fullscreenButton.x = stage.stageWidth - _fullscreenButton.width - 10; gyorgy@0: _fullscreenButton.y = 10; gyorgy@0: gyorgy@0: // create media element gyorgy@0: if (_isVideo) { gyorgy@0: _mediaElement = new VideoElement(this, _autoplay, _preload, _timerRate, _startVolume); gyorgy@0: _video = (_mediaElement as VideoElement).video; gyorgy@0: _video.width = _stageWidth; gyorgy@0: _video.height = _stageHeight; gyorgy@0: _video.smoothing = _enableSmoothing; gyorgy@0: //_video.scaleMode = VideoScaleMode.MAINTAIN_ASPECT_RATIO; gyorgy@0: addChild(_video); gyorgy@0: } else { gyorgy@0: _mediaElement = new AudioElement(this, _autoplay, _preload, _timerRate, _startVolume); gyorgy@0: } gyorgy@0: gyorgy@0: // debugging gyorgy@0: _output = new TextField(); gyorgy@0: _output.textColor = 0xeeeeee; gyorgy@0: _output.width = stage.stageWidth - 100; gyorgy@0: _output.height = stage.stageHeight; gyorgy@0: _output.multiline = true; gyorgy@0: _output.wordWrap = true; gyorgy@0: _output.border = false; gyorgy@0: _output.filters = [new DropShadowFilter(1, 0x000000, 45, 1, 2, 2, 1)]; gyorgy@0: gyorgy@0: _output.text = "Initializing...\n"; gyorgy@0: addChild(_output); gyorgy@0: _output.visible = _debug; gyorgy@0: gyorgy@0: // controls! gyorgy@0: _controlBar = getChildByName("controls_mc") as MovieClip; gyorgy@0: _controlBarBg = _controlBar.getChildByName("controls_bg_mc") as MovieClip; gyorgy@0: _playButton = _controlBar.getChildByName("play_btn") as SimpleButton; gyorgy@0: _playButton.addEventListener(MouseEvent.CLICK, function(e:MouseEvent) { gyorgy@0: _mediaElement.play(); gyorgy@0: }); gyorgy@0: _pauseButton = _controlBar.getChildByName("pause_btn") as SimpleButton; gyorgy@0: _pauseButton.addEventListener(MouseEvent.CLICK, function(e:MouseEvent) { gyorgy@0: _mediaElement.pause(); gyorgy@0: }); gyorgy@0: _pauseButton.visible = false; gyorgy@0: _duration = _controlBar.getChildByName("duration_txt") as TextField; gyorgy@0: _currentTime = _controlBar.getChildByName("currentTime_txt") as TextField; gyorgy@0: gyorgy@0: _controlBar.visible = _showControls; gyorgy@0: addChild(_controlBar); gyorgy@0: gyorgy@0: // put back on top gyorgy@0: addChild(_fullscreenButton); gyorgy@0: //_fullscreenButton.alpha = 0; gyorgy@0: _fullscreenButton.visible = false; gyorgy@0: gyorgy@0: _output.appendText("stage: " + stage.stageWidth + "x" + stage.stageHeight + "\n"); gyorgy@0: _output.appendText("file: " + _mediaUrl + "\n"); gyorgy@0: _output.appendText("autoplay: " + _autoplay.toString() + "\n"); gyorgy@0: _output.appendText("preload: " + _preload.toString() + "\n"); gyorgy@0: _output.appendText("isvideo: " + _isVideo.toString() + "\n"); gyorgy@0: _output.appendText("smoothing: " + _enableSmoothing.toString() + "\n"); gyorgy@0: _output.appendText("timerrate: " + _timerRate.toString() + "\n"); gyorgy@0: _output.appendText("displayState: " +(stage.hasOwnProperty("displayState")).toString() + "\n"); gyorgy@0: gyorgy@0: // attach javascript gyorgy@0: _output.appendText("ExternalInterface.available: " + ExternalInterface.available.toString() + "\n"); gyorgy@0: _output.appendText("ExternalInterface.objectID: " + ((ExternalInterface.objectID != null)? ExternalInterface.objectID.toString() : "null") + "\n"); gyorgy@0: gyorgy@0: if (_mediaUrl != "") { gyorgy@0: _mediaElement.setSrc(_mediaUrl); gyorgy@0: } gyorgy@0: gyorgy@0: positionControls(); gyorgy@0: gyorgy@0: if (ExternalInterface.available) { // && !_showControls gyorgy@0: gyorgy@0: _output.appendText("Adding callbacks...\n"); gyorgy@0: try { gyorgy@0: if (ExternalInterface.objectID != null && ExternalInterface.objectID.toString() != "") { gyorgy@0: gyorgy@0: // add HTML media methods gyorgy@0: ExternalInterface.addCallback("playMedia", playMedia); gyorgy@0: ExternalInterface.addCallback("loadMedia", loadMedia); gyorgy@0: ExternalInterface.addCallback("pauseMedia", pauseMedia); gyorgy@0: ExternalInterface.addCallback("stopMedia", stopMedia); gyorgy@0: gyorgy@0: ExternalInterface.addCallback("setSrc", setSrc); gyorgy@0: ExternalInterface.addCallback("setCurrentTime", setCurrentTime); gyorgy@0: ExternalInterface.addCallback("setVolume", setVolume); gyorgy@0: ExternalInterface.addCallback("setMuted", setMuted); gyorgy@0: gyorgy@0: ExternalInterface.addCallback("setFullscreen", setFullscreen); gyorgy@0: ExternalInterface.addCallback("setVideoSize", setVideoSize); gyorgy@0: gyorgy@0: // fire init method gyorgy@0: ExternalInterface.call("mejs.MediaPluginBridge.initPlugin", ExternalInterface.objectID); gyorgy@0: } gyorgy@0: gyorgy@0: _output.appendText("Success...\n"); gyorgy@0: gyorgy@0: } catch (error:SecurityError) { gyorgy@0: _output.appendText("A SecurityError occurred: " + error.message + "\n"); gyorgy@0: } catch (error:Error) { gyorgy@0: _output.appendText("An Error occurred: " + error.message + "\n"); gyorgy@0: } gyorgy@0: gyorgy@0: } gyorgy@0: gyorgy@0: if (_preload != "none") { gyorgy@0: _mediaElement.load(); gyorgy@0: gyorgy@0: if (_autoplay) { gyorgy@0: _mediaElement.play(); gyorgy@0: } gyorgy@0: } else if (_autoplay) { gyorgy@0: _mediaElement.load(); gyorgy@0: _mediaElement.play(); gyorgy@0: } gyorgy@0: gyorgy@0: gyorgy@0: gyorgy@0: gyorgy@0: // connection to full screen gyorgy@0: //_connection = new LocalConnection(); gyorgy@0: //_connection.client = this; gyorgy@0: //_connection.connect(ExternalInterface.objectID + "_player"); gyorgy@0: gyorgy@0: // listen for rezie gyorgy@0: stage.addEventListener(Event.RESIZE, resizeHandler); gyorgy@0: gyorgy@0: // test gyorgy@0: stage.addEventListener(MouseEvent.MOUSE_DOWN, clickHandler); gyorgy@0: gyorgy@0: // resize gyorgy@0: stage.addEventListener(FullScreenEvent.FULL_SCREEN, stageFullScreen); gyorgy@0: } gyorgy@0: gyorgy@0: function clickHandler(e:MouseEvent):void { gyorgy@0: //_output.appendText("click: " + e.stageX.toString() +","+e.stageY.toString() + "\n"); gyorgy@0: sendEvent("click", ""); gyorgy@0: } gyorgy@0: gyorgy@0: function resizeHandler(e:Event):void { gyorgy@0: //_video.scaleX = stage.stageWidth / _stageWidth; gyorgy@0: //_video.scaleY = stage.stageHeight / _stageHeight; gyorgy@0: //positionControls(); gyorgy@0: gyorgy@0: repositionVideo(); gyorgy@0: } gyorgy@0: gyorgy@0: // START: Fullscreen gyorgy@0: gyorgy@0: // for local connection gyorgy@0: public function goFullscreen():void { gyorgy@0: setFullscreen(true); gyorgy@0: } gyorgy@0: gyorgy@0: gyorgy@0: function setFullscreen(gofullscreen:Boolean) { gyorgy@0: gyorgy@0: try { gyorgy@0: //_fullscreenButton.visible = false; gyorgy@0: gyorgy@0: if (gofullscreen) { gyorgy@0: var screenRectangle:Rectangle = new Rectangle(_video.x, _video.y, flash.system.Capabilities.screenResolutionX, flash.system.Capabilities.screenResolutionY); gyorgy@0: stage.fullScreenSourceRect = screenRectangle; gyorgy@0: gyorgy@0: stage.displayState = StageDisplayState.FULL_SCREEN; gyorgy@0: _isFullScreen = true; gyorgy@0: gyorgy@0: } else { gyorgy@0: stage.displayState = StageDisplayState.NORMAL; gyorgy@0: _isFullScreen = false; gyorgy@0: } gyorgy@0: gyorgy@0: } catch (error:Error) { gyorgy@0: gyorgy@0: // show the button when the security error doesn't let it work gyorgy@0: _fullscreenButton.visible = true; gyorgy@0: gyorgy@0: _isFullScreen = false; gyorgy@0: gyorgy@0: _output.appendText("error setting fullscreen: " + error.toString() + "\n"); gyorgy@0: } gyorgy@0: } gyorgy@0: gyorgy@0: function fullscreenClick(e:MouseEvent) { gyorgy@0: _fullscreenButton.visible = false; gyorgy@0: gyorgy@0: try { gyorgy@0: _controlBar.visible = true; gyorgy@0: setFullscreen(true); gyorgy@0: repositionVideo(true); gyorgy@0: } catch (error:Error) { gyorgy@0: } gyorgy@0: } gyorgy@0: gyorgy@0: function stageFullScreen(e:FullScreenEvent) { gyorgy@0: _output.appendText("fullscreen event: " + e.fullScreen.toString() + "\n"); gyorgy@0: gyorgy@0: _fullscreenButton.visible = false; gyorgy@0: _isFullScreen = e.fullScreen; gyorgy@0: gyorgy@0: if (!e.fullScreen) { gyorgy@0: _controlBar.visible = _showControls; gyorgy@0: } gyorgy@0: } gyorgy@0: // END: Fullscreen gyorgy@0: gyorgy@0: function playMedia() { gyorgy@0: _output.appendText("play\n"); gyorgy@0: _mediaElement.play(); gyorgy@0: } gyorgy@0: gyorgy@0: function loadMedia() { gyorgy@0: _output.appendText("load\n"); gyorgy@0: _mediaElement.load(); gyorgy@0: } gyorgy@0: gyorgy@0: function pauseMedia() { gyorgy@0: _output.appendText("pause\n"); gyorgy@0: _mediaElement.pause(); gyorgy@0: } gyorgy@0: gyorgy@0: function setSrc(url:String) { gyorgy@0: _output.appendText("setSrc: " + url + "\n"); gyorgy@0: _mediaElement.setSrc(url); gyorgy@0: } gyorgy@0: gyorgy@0: function stopMedia() { gyorgy@0: _output.appendText("stop\n"); gyorgy@0: _mediaElement.stop(); gyorgy@0: } gyorgy@0: gyorgy@0: function setCurrentTime(time:Number) { gyorgy@0: _output.appendText("seek: " + time.toString() + "\n"); gyorgy@0: _mediaElement.setCurrentTime(time); gyorgy@0: } gyorgy@0: gyorgy@0: function setVolume(volume:Number) { gyorgy@0: _output.appendText("volume: " + volume.toString() + "\n"); gyorgy@0: _mediaElement.setVolume(volume); gyorgy@0: } gyorgy@0: gyorgy@0: function setMuted(muted:Boolean) { gyorgy@0: _output.appendText("muted: " + muted.toString() + "\n"); gyorgy@0: _mediaElement.setMuted(muted); gyorgy@0: } gyorgy@0: gyorgy@0: function setVideoSize(width:Number, height:Number) { gyorgy@0: _output.appendText("setVideoSize: " + width.toString() + "," + height.toString() + "\n"); gyorgy@0: gyorgy@0: _stageWidth = width; gyorgy@0: _stageHeight = height; gyorgy@0: gyorgy@0: if (_video != null) { gyorgy@0: repositionVideo(); gyorgy@0: _fullscreenButton.x = stage.stageWidth - _fullscreenButton.width - 10; gyorgy@0: } gyorgy@0: gyorgy@0: _output.appendText("result: " + _video.width.toString() + "," + _video.height.toString() + "\n"); gyorgy@0: } gyorgy@0: gyorgy@0: function repositionVideo(fullscreen:Boolean = false):void { gyorgy@0: gyorgy@0: if (_nativeVideoWidth <= 0 || _nativeVideoHeight <= 0) gyorgy@0: return; gyorgy@0: gyorgy@0: _output.appendText("positioning video\n"); gyorgy@0: gyorgy@0: // calculate ratios gyorgy@0: var stageRatio, nativeRatio; gyorgy@0: gyorgy@0: if(fullscreen == true) { gyorgy@0: stageRatio = flash.system.Capabilities.screenResolutionX/flash.system.Capabilities.screenResolutionY; gyorgy@0: nativeRatio = _nativeVideoWidth/_nativeVideoHeight; gyorgy@0: gyorgy@0: // adjust size and position gyorgy@0: if (nativeRatio > stageRatio) { gyorgy@0: _video.width = flash.system.Capabilities.screenResolutionX; gyorgy@0: _video.height = _nativeVideoHeight * flash.system.Capabilities.screenResolutionX / _nativeVideoWidth; gyorgy@0: _video.y = flash.system.Capabilities.screenResolutionY/2 - _video.height/2; gyorgy@0: } else if (stageRatio > nativeRatio) { gyorgy@0: _video.height = flash.system.Capabilities.screenResolutionY; gyorgy@0: _video.width = _nativeVideoWidth * flash.system.Capabilities.screenResolutionY / _nativeVideoHeight; gyorgy@0: _video.x = flash.system.Capabilities.screenResolutionX/2 - _video.width/2; gyorgy@0: } else if (stageRatio == nativeRatio) { gyorgy@0: _video.height = flash.system.Capabilities.screenResolutionY; gyorgy@0: _video.width = flash.system.Capabilities.screenResolutionX; gyorgy@0: _video.x = 0; gyorgy@0: _video.y = 0; gyorgy@0: } gyorgy@0: } else { gyorgy@0: stageRatio = _stageWidth/_stageHeight; gyorgy@0: nativeRatio = _nativeVideoWidth/_nativeVideoHeight; gyorgy@0: gyorgy@0: // adjust size and position gyorgy@0: if (nativeRatio > stageRatio) { gyorgy@0: _video.width = _stageWidth; gyorgy@0: _video.height = _nativeVideoHeight * _stageWidth / _nativeVideoWidth; gyorgy@0: _video.y = _stageHeight/2 - _video.height/2; gyorgy@0: } else if (stageRatio > nativeRatio) { gyorgy@0: _video.height = _stageHeight; gyorgy@0: _video.width = _nativeVideoWidth * _stageHeight / _nativeVideoHeight; gyorgy@0: _video.x = _stageWidth/2 - _video.width/2; gyorgy@0: } else if (stageRatio == nativeRatio) { gyorgy@0: _video.height = _stageHeight; gyorgy@0: _video.width = _stageWidth; gyorgy@0: _video.x = 0; gyorgy@0: _video.y = 0; gyorgy@0: } gyorgy@0: } gyorgy@0: gyorgy@0: positionControls(); gyorgy@0: } gyorgy@0: gyorgy@0: // SEND events to JavaScript gyorgy@0: public function sendEvent(eventName:String, eventValues:String) { gyorgy@0: gyorgy@0: // special video event gyorgy@0: if (eventName == HtmlMediaEvent.LOADEDMETADATA && _isVideo) { gyorgy@0: _nativeVideoWidth = (_mediaElement as VideoElement).videoWidth; gyorgy@0: _nativeVideoHeight = (_mediaElement as VideoElement).videoHeight; gyorgy@0: gyorgy@0: repositionVideo(); gyorgy@0: } gyorgy@0: gyorgy@0: // update controls gyorgy@0: switch (eventName) { gyorgy@0: case "pause": gyorgy@0: case "paused": gyorgy@0: case "ended": gyorgy@0: _playButton.visible = true; gyorgy@0: _pauseButton.visible = false; gyorgy@0: break; gyorgy@0: case "play": gyorgy@0: case "playing": gyorgy@0: _playButton.visible = false; gyorgy@0: _pauseButton.visible = true; gyorgy@0: break; gyorgy@0: } gyorgy@0: _duration.text = secondsToTimeCode(_mediaElement.duration()); gyorgy@0: _currentTime.text = secondsToTimeCode(_mediaElement.currentTime()); gyorgy@0: gyorgy@0: gyorgy@0: if (ExternalInterface.objectID != null && ExternalInterface.objectID.toString() != "") { gyorgy@0: gyorgy@0: //_output.appendText("event:" + eventName + " : " + eventValues); gyorgy@0: trace("event", eventName, eventValues); gyorgy@0: gyorgy@0: if (eventValues == null) gyorgy@0: eventValues == ""; gyorgy@0: gyorgy@0: if (_isVideo) { gyorgy@0: eventValues += (eventValues != "" ? "," : "") + "isFullScreen:" + _isFullScreen; gyorgy@0: } gyorgy@0: gyorgy@0: eventValues = "{" + eventValues + "}"; gyorgy@0: gyorgy@0: /* gyorgy@0: OLD DIRECT METHOD gyorgy@0: ExternalInterface.call( gyorgy@0: "function(id, name) { mejs.MediaPluginBridge.fireEvent(id,name," + eventValues + "); }", gyorgy@0: ExternalInterface.objectID, gyorgy@0: eventName); gyorgy@0: */ gyorgy@0: gyorgy@0: // use set timeout for performance reasons gyorgy@0: //if (!_showControls) { gyorgy@0: ExternalInterface.call("setTimeout", "mejs.MediaPluginBridge.fireEvent('" + ExternalInterface.objectID + "','" + eventName + "'," + eventValues + ")",0); gyorgy@0: //} gyorgy@0: } gyorgy@0: } gyorgy@0: gyorgy@0: function secondsToTimeCode(seconds:Number):String { gyorgy@0: var timeCode:String = ""; gyorgy@0: seconds = Math.round(seconds); gyorgy@0: var minutes:Number = Math.floor(seconds / 60); gyorgy@0: timeCode = (minutes >= 10) ? minutes.toString() : "0" + minutes.toString(); gyorgy@0: seconds = Math.floor(seconds % 60); gyorgy@0: timeCode += ":" + ((seconds >= 10) ? seconds.toString() : "0" + seconds.toString()); gyorgy@0: return timeCode; //minutes.toString() + ":" + seconds.toString(); gyorgy@0: } gyorgy@0: gyorgy@0: function positionControls() { gyorgy@0: _controlBarBg.width = stage.stageWidth; gyorgy@0: _controlBar.y = stage.stageHeight - _controlBar.height; gyorgy@0: _duration.x = stage.stageWidth - _duration.width - 10; gyorgy@0: _currentTime.x = stage.stageWidth - _duration.width - 10 - _currentTime.width - 10; gyorgy@0: } gyorgy@0: } gyorgy@0: }