package htmlelements { import flash.display.Sprite; import flash.events.*; import flash.net.NetConnection; import flash.net.NetStream; import flash.media.Video; import flash.media.SoundTransform; import flash.utils.Timer; import flash.net.URLLoader; import flash.net.URLRequest; import flash.net.URLVariables; import flash.net.URLRequestMethod; import flash.display.MovieClip; import flash.display.Loader; import flash.display.DisplayObject; import FlashMediaElement; import HtmlMediaEvent; public class YouTubeElement extends Sprite implements IMediaElement { private var _currentUrl:String = ""; private var _autoplay:Boolean = true; private var _preload:String = ""; private var _element:FlashMediaElement; // event values private var _currentTime:Number = 0; private var _duration:Number = 0; private var _framerate:Number; private var _isPaused:Boolean = true; private var _isEnded:Boolean = false; private var _volume:Number = 1; private var _isMuted:Boolean = false; private var _bytesLoaded:Number = 0; private var _bytesTotal:Number = 0; private var _bufferedTime:Number = 0; private var _bufferEmpty:Boolean = false; private var _videoWidth:Number = -1; private var _videoHeight:Number = -1; private var _timer:Timer; // YouTube stuff private var _playerLoader:Loader; private var _player:Object = null; private var _playerIsLoaded:Boolean = false; private var _youTubeId:String = ""; //http://code.google.com/p/gdata-samples/source/browse/trunk/ytplayer/actionscript3/com/google/youtube/examples/AS3Player.as private static const WIDESCREEN_ASPECT_RATIO:String = "widescreen"; private static const QUALITY_TO_PLAYER_WIDTH:Object = { small: 320, medium: 640, large: 854, hd720: 1280 }; private static const STATE_ENDED:Number = 0; private static const STATE_PLAYING:Number = 1; private static const STATE_PAUSED:Number = 2; private static const STATE_CUED:Number = 5; public function get player():DisplayObject { return _player; } public function setSize(width:Number, height:Number):void { if (_player != null) { _player.setSize(width, height); } else { initHeight = height; initWidth = width; } } public function get videoHeight():Number { return _videoHeight; } public function get videoWidth():Number { return _videoWidth; } public function duration():Number { return _duration; } public function currentProgress():Number { if(_bytesTotal> 0) { return Math.round(_bytesLoaded/_bytesTotal*100); } else { return 0; } } public function currentTime():Number { return _currentTime; } public var initHeight:Number; public var initWidth:Number; // (1) load() // calls _connection.connect(); // waits for NetConnection.Connect.Success // _stream gets created private var _isChromeless:Boolean = false; public function YouTubeElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number) { _element = element; _autoplay = autoplay; _volume = startVolume; _preload = preload; initHeight = 0; initWidth = 0; _playerLoader = new Loader(); _playerLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, playerLoaderInitHandler); // chromeless if (_isChromeless) { _playerLoader.load(new URLRequest("//www.youtube.com/apiplayer?version=3&controls=1&rel=0&showinfo=0&iv_load_policy=1")); } _timer = new Timer(timerRate); _timer.addEventListener("timer", timerHandler); _timer.start(); } private function playerLoaderInitHandler(event:Event):void { trace("yt player init"); _element.addChild(_playerLoader.content); _element.setControlDepth(); _playerLoader.content.addEventListener("onReady", onPlayerReady); _playerLoader.content.addEventListener("onError", onPlayerError); _playerLoader.content.addEventListener("onStateChange", onPlayerStateChange); _playerLoader.content.addEventListener("onPlaybackQualityChange", onVideoPlaybackQualityChange); } private function onPlayerReady(event:Event):void { _playerIsLoaded = true; _player = _playerLoader.content; if (initHeight > 0 && initWidth > 0) _player.setSize(initWidth, initHeight); if (_youTubeId != "") { // && _isChromeless) { if (_autoplay) { player.loadVideoById(_youTubeId); } else { player.cueVideoById(_youTubeId); } _timer.start(); } } private function onPlayerError(event:Event):void { // trace("Player error:", Object(event).data); } private function onPlayerStateChange(event:Event):void { trace("State is", Object(event).data); _duration = _player.getDuration(); switch (Object(event).data) { case STATE_ENDED: _isEnded = true; _isPaused = false; sendEvent(HtmlMediaEvent.ENDED); break; case STATE_PLAYING: _isEnded = false; _isPaused = false; sendEvent(HtmlMediaEvent.PLAY); sendEvent(HtmlMediaEvent.PLAYING); break; case STATE_PAUSED: _isEnded = false; _isPaused = true; sendEvent(HtmlMediaEvent.PAUSE); break; case STATE_CUED: sendEvent(HtmlMediaEvent.CANPLAY); // resize? break; } } private function onVideoPlaybackQualityChange(event:Event):void { trace("Current video quality:", Object(event).data); //resizePlayer(Object(event).data); } private function timerHandler(e:TimerEvent) { if (_playerIsLoaded) { _bytesLoaded = _player.getVideoBytesLoaded(); _bytesTotal = _player.getVideoBytesTotal(); _currentTime = player.getCurrentTime(); if (!_isPaused) sendEvent(HtmlMediaEvent.TIMEUPDATE); if (_bytesLoaded < _bytesTotal) sendEvent(HtmlMediaEvent.PROGRESS); } } private function getYouTubeId(url:String):String { // http://www.youtube.com/watch?feature=player_embedded&v=yyWWXSwtPP0 // http://www.youtube.com/v/VIDEO_ID?version=3 // http://youtu.be/Djd6tPrxc08 url = unescape(url); var youTubeId:String = ""; if (url.indexOf("?") > 0) { // assuming: http://www.youtube.com/watch?feature=player_embedded&v=yyWWXSwtPP0 youTubeId = getYouTubeIdFromParam(url); // if it's http://www.youtube.com/v/VIDEO_ID?version=3 if (youTubeId == "") { youTubeId = getYouTubeIdFromUrl(url); } } else { youTubeId = getYouTubeIdFromUrl(url); } return youTubeId; } // http://www.youtube.com/watch?feature=player_embedded&v=yyWWXSwtPP0 private function getYouTubeIdFromParam(url:String):String { var youTubeId:String = ""; var parts:Array = url.split('?'); var parameters:Array = parts[1].split('&'); for (var i:Number=0; i