summaryrefslogtreecommitdiffstats
path: root/debian/missing-sources/mediaelement/src/htmlelements
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 07:56:53 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 07:56:53 +0000
commita9c818418b81b93680170e1a84d4e221e578ad2f (patch)
tree5b883aa428f1edb12f5d40f9768438ee16a7ed6b /debian/missing-sources/mediaelement/src/htmlelements
parentAdding upstream version 6.4.3+dfsg1. (diff)
downloadwordpress-a9c818418b81b93680170e1a84d4e221e578ad2f.tar.xz
wordpress-a9c818418b81b93680170e1a84d4e221e578ad2f.zip
Adding debian version 6.4.3+dfsg1-1.debian/6.4.3+dfsg1-1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/missing-sources/mediaelement/src/htmlelements')
-rw-r--r--debian/missing-sources/mediaelement/src/htmlelements/AudioElement.as332
-rw-r--r--debian/missing-sources/mediaelement/src/htmlelements/IMediaElement.as35
-rw-r--r--debian/missing-sources/mediaelement/src/htmlelements/VideoElement.as1
-rw-r--r--debian/missing-sources/mediaelement/src/htmlelements/YouTubeElement.as403
4 files changed, 771 insertions, 0 deletions
diff --git a/debian/missing-sources/mediaelement/src/htmlelements/AudioElement.as b/debian/missing-sources/mediaelement/src/htmlelements/AudioElement.as
new file mode 100644
index 0000000..750599d
--- /dev/null
+++ b/debian/missing-sources/mediaelement/src/htmlelements/AudioElement.as
@@ -0,0 +1,332 @@
+
+package htmlelements
+{
+ import flash.events.Event;
+ import flash.events.IOErrorEvent;
+ import flash.events.ProgressEvent;
+ import flash.events.TimerEvent;
+ import flash.media.ID3Info;
+ import flash.media.Sound;
+ import flash.media.SoundChannel;
+ import flash.media.SoundLoaderContext;
+ import flash.media.SoundTransform;
+ import flash.net.URLRequest;
+ import flash.utils.Timer;
+
+
+
+ /**
+ * ...
+ * @author DefaultUser (Tools -> Custom Arguments...)
+ */
+ public class AudioElement implements IMediaElement
+ {
+
+ private var _sound:Sound;
+ private var _soundTransform:SoundTransform;
+ private var _soundChannel:SoundChannel;
+ private var _soundLoaderContext:SoundLoaderContext;
+
+ private var _volume:Number = 1;
+ private var _preMuteVolume:Number = 0;
+ private var _isMuted:Boolean = false;
+ private var _isPaused:Boolean = true;
+ private var _isEnded:Boolean = false;
+ private var _isLoaded:Boolean = false;
+ private var _currentTime:Number = 0;
+ private var _duration:Number = 0;
+ private var _bytesLoaded:Number = 0;
+ private var _bytesTotal:Number = 0;
+ private var _bufferedTime:Number = 0;
+ private var _bufferingChanged:Boolean = false;
+
+ private var _currentUrl:String = "";
+ private var _autoplay:Boolean = true;
+ private var _preload:String = "";
+
+ private var _element:FlashMediaElement;
+ private var _timer:Timer;
+ private var _firedCanPlay:Boolean = false;
+
+ public function setSize(width:Number, height:Number):void {
+ // do nothing!
+ }
+
+ public function duration():Number {
+ return _duration;
+ }
+
+ public function currentTime():Number {
+ return _currentTime;
+ }
+
+ public function currentProgress():Number {
+ return Math.round(_bytesLoaded/_bytesTotal*100);
+ }
+
+ public function AudioElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number)
+ {
+ _element = element;
+ _autoplay = autoplay;
+ _volume = startVolume;
+ _preload = preload;
+
+ _timer = new Timer(timerRate);
+ _timer.addEventListener(TimerEvent.TIMER, timerEventHandler);
+
+ _soundTransform = new SoundTransform(_volume);
+ _soundLoaderContext = new SoundLoaderContext();
+ }
+
+ // events
+ function progressHandler(e:ProgressEvent):void {
+
+ _bytesLoaded = e.bytesLoaded;
+ _bytesTotal = e.bytesTotal;
+
+ // this happens too much to send every time
+ //sendEvent(HtmlMediaEvent.PROGRESS);
+
+ // so now we just trigger a flag and send with the timer
+ _bufferingChanged = true;
+ }
+
+ function id3Handler(e:Event):void {
+ sendEvent(HtmlMediaEvent.LOADEDMETADATA);
+
+ try {
+ var id3:ID3Info = _sound.id3;
+ var obj = {
+ type:'id3',
+ album:id3.album,
+ artist:id3.artist,
+ comment:id3.comment,
+ genre:id3.genre,
+ songName:id3.songName,
+ track:id3.track,
+ year:id3.year
+ }
+ } catch (err:Error) {}
+
+
+ }
+
+ function timerEventHandler(e:TimerEvent) {
+ _currentTime = _soundChannel.position/1000;
+
+ // calculate duration
+ var duration = Math.round(_sound.length * _sound.bytesTotal/_sound.bytesLoaded/100) / 10;
+
+ // check to see if the estimated duration changed
+ if (_duration != duration && !isNaN(duration)) {
+
+ _duration = duration;
+ sendEvent(HtmlMediaEvent.LOADEDMETADATA);
+ }
+
+ // check for progress
+ if (_bufferingChanged) {
+
+ sendEvent(HtmlMediaEvent.PROGRESS);
+
+ _bufferingChanged = false;
+ }
+
+ // send timeupdate
+ sendEvent(HtmlMediaEvent.TIMEUPDATE);
+
+ // sometimes the ended event doesn't fire, here's a fake one
+ if (_duration > 0 && _currentTime >= _duration-0.2) {
+ handleEnded();
+ }
+ }
+
+ function soundCompleteHandler(e:Event) {
+ handleEnded();
+ }
+
+ function handleEnded():void {
+ _timer.stop();
+ _currentTime = 0;
+ _isEnded = true;
+
+ sendEvent(HtmlMediaEvent.ENDED);
+ }
+
+ //events
+
+
+ // METHODS
+ public function setSrc(url:String):void {
+ _currentUrl = url;
+ _isLoaded = false;
+ }
+
+
+ public function load():void {
+
+ if (_currentUrl == "")
+ return;
+
+ _sound = new Sound();
+ //sound.addEventListener(IOErrorEvent.IO_ERROR,errorHandler);
+ _sound.addEventListener(ProgressEvent.PROGRESS,progressHandler);
+ _sound.addEventListener(Event.ID3,id3Handler);
+ _sound.load(new URLRequest(_currentUrl));
+ _currentTime = 0;
+
+ sendEvent(HtmlMediaEvent.LOADSTART);
+
+ _isLoaded = true;
+
+ sendEvent(HtmlMediaEvent.LOADEDDATA);
+ sendEvent(HtmlMediaEvent.CANPLAY);
+ _firedCanPlay = true;
+
+ if (_playAfterLoading) {
+ _playAfterLoading = false;
+ play();
+ }
+ }
+
+ private var _playAfterLoading:Boolean= false;
+
+ public function play():void {
+
+ if (!_isLoaded) {
+ _playAfterLoading = true;
+ load();
+ return;
+ }
+
+ _timer.stop();
+
+ _soundChannel = _sound.play(_currentTime*1000, 0, _soundTransform);
+ _soundChannel.removeEventListener(Event.SOUND_COMPLETE, soundCompleteHandler);
+ _soundChannel.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler);
+
+ _timer.start();
+
+ didStartPlaying();
+ }
+
+ public function pause():void {
+
+ _timer.stop();
+ if (_soundChannel != null) {
+ _currentTime = _soundChannel.position/1000;
+ _soundChannel.stop();
+ }
+
+ _isPaused = true;
+ sendEvent(HtmlMediaEvent.PAUSE);
+ }
+
+
+ public function stop():void {
+ if (_timer != null) {
+ _timer.stop();
+ }
+ if (_soundChannel != null) {
+ _soundChannel.stop();
+ _sound.close();
+ }
+ unload();
+ sendEvent(HtmlMediaEvent.STOP);
+ }
+
+ public function setCurrentTime(pos:Number):void {
+ sendEvent(HtmlMediaEvent.SEEKING);
+ _timer.stop();
+ _currentTime = pos;
+ _soundChannel.stop();
+ _sound.length
+ _soundChannel = _sound.play(_currentTime * 1000, 0, _soundTransform);
+ sendEvent(HtmlMediaEvent.SEEKED);
+
+ _timer.start();
+
+ didStartPlaying();
+ }
+
+ private function didStartPlaying():void {
+ _isPaused = false;
+ sendEvent(HtmlMediaEvent.PLAY);
+ sendEvent(HtmlMediaEvent.PLAYING);
+ if (!_firedCanPlay) {
+ sendEvent(HtmlMediaEvent.LOADEDDATA);
+ sendEvent(HtmlMediaEvent.CANPLAY);
+ _firedCanPlay = true;
+ }
+ }
+
+
+ public function setVolume(volume:Number):void {
+
+ _volume = volume;
+ _soundTransform.volume = volume;
+
+ if (_soundChannel != null) {
+ _soundChannel.soundTransform = _soundTransform;
+ }
+
+ _isMuted = (_volume == 0);
+
+ sendEvent(HtmlMediaEvent.VOLUMECHANGE);
+ }
+
+ public function getVolume():Number {
+ if(_isMuted) {
+ return 0;
+ } else {
+ return _volume;
+ }
+ }
+
+
+ public function setMuted(muted:Boolean):void {
+
+ // ignore if already set
+ if ( (muted && _isMuted) || (!muted && !_isMuted))
+ return;
+
+ if (muted) {
+ _preMuteVolume = _soundTransform.volume;
+ setVolume(0);
+ } else {
+ setVolume(_preMuteVolume);
+ }
+
+ _isMuted = muted;
+ }
+
+ public function unload():void {
+ _sound = null;
+ _isLoaded = false;
+ }
+
+ private function sendEvent(eventName:String) {
+
+ // calculate this to mimic HTML5
+ _bufferedTime = _bytesLoaded / _bytesTotal * _duration;
+
+ // build JSON
+ var values:String = "duration:" + _duration +
+ ",currentTime:" + _currentTime +
+ ",muted:" + _isMuted +
+ ",paused:" + _isPaused +
+ ",ended:" + _isEnded +
+ ",volume:" + _volume +
+ ",src:\"" + _currentUrl + "\"" +
+ ",bytesTotal:" + _bytesTotal +
+ ",bufferedBytes:" + _bytesLoaded +
+ ",bufferedTime:" + _bufferedTime +
+ "";
+
+ _element.sendEvent(eventName, values);
+ }
+
+ }
+
+}
+
diff --git a/debian/missing-sources/mediaelement/src/htmlelements/IMediaElement.as b/debian/missing-sources/mediaelement/src/htmlelements/IMediaElement.as
new file mode 100644
index 0000000..d626607
--- /dev/null
+++ b/debian/missing-sources/mediaelement/src/htmlelements/IMediaElement.as
@@ -0,0 +1,35 @@
+
+package htmlelements
+{
+
+ public interface IMediaElement {
+
+ function play():void;
+
+ function pause():void;
+
+ function load():void;
+
+ function stop():void;
+
+ function setSrc(url:String):void;
+
+ function setSize(width:Number, height:Number):void;
+
+ function setCurrentTime(pos:Number):void;
+
+ function setVolume(vol:Number):void;
+
+ function getVolume():Number;
+
+ function setMuted(muted:Boolean):void;
+
+ function duration():Number;
+
+ function currentTime():Number;
+
+ function currentProgress():Number;
+
+ }
+
+}
diff --git a/debian/missing-sources/mediaelement/src/htmlelements/VideoElement.as b/debian/missing-sources/mediaelement/src/htmlelements/VideoElement.as
new file mode 100644
index 0000000..7673c4f
--- /dev/null
+++ b/debian/missing-sources/mediaelement/src/htmlelements/VideoElement.as
@@ -0,0 +1 @@
+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 FlashMediaElement; import HtmlMediaEvent; public class VideoElement extends Sprite implements IMediaElement { private var _currentUrl:String = ""; private var _autoplay:Boolean = true; private var _preload:String = ""; private var _isPreloading:Boolean = false; private var _connection:NetConnection; private var _stream:NetStream; private var _video:Video; private var _element:FlashMediaElement; private var _soundTransform; private var _oldVolume:Number = 1; // event values 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 _bufferingChanged:Boolean = false; private var _seekOffset:Number = 0; private var _videoWidth:Number = -1; private var _videoHeight:Number = -1; private var _timer:Timer; private var _isRTMP:Boolean = false; private var _streamer:String = ""; private var _isConnected:Boolean = false; private var _playWhenConnected:Boolean = false; private var _hasStartedPlaying:Boolean = false; private var _parentReference:Object; private var _pseudoStreamingEnabled:Boolean = false; private var _pseudoStreamingStartQueryParam:String = "start"; public function setReference(arg:Object):void { _parentReference = arg; } public function setSize(width:Number, height:Number):void { _video.width = width; _video.height = height; } public function setPseudoStreaming(enablePseudoStreaming:Boolean):void { _pseudoStreamingEnabled = enablePseudoStreaming; } public function setPseudoStreamingStartParam(pseudoStreamingStartQueryParam:String):void { _pseudoStreamingStartQueryParam = pseudoStreamingStartQueryParam; } public function get video():Video { return _video; } 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(_stream != null) { return Math.round(_stream.bytesLoaded/_stream.bytesTotal*100); } else { return 0; } } public function currentTime():Number { var currentTime:Number = 0; if (_stream != null) { currentTime = _stream.time; if (_pseudoStreamingEnabled) { currentTime += _seekOffset; } } return currentTime; } // (1) load() // calls _connection.connect(); // waits for NetConnection.Connect.Success // _stream gets created public function VideoElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number, streamer:String) { _element = element; _autoplay = autoplay; _volume = startVolume; _preload = preload; _streamer = streamer; _video = new Video(); addChild(_video); _connection = new NetConnection(); _connection.client = { onBWDone: function():void{} }; _connection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); _connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); //_connection.connect(null); _timer = new Timer(timerRate); _timer.addEventListener("timer", timerHandler); } private function timerHandler(e:TimerEvent) { _bytesLoaded = _stream.bytesLoaded; _bytesTotal = _stream.bytesTotal; if (!_isPaused) { sendEvent(HtmlMediaEvent.TIMEUPDATE); } //trace("bytes", _bytesLoaded, _bytesTotal); if (_bytesLoaded < _bytesTotal) sendEvent(HtmlMediaEvent.PROGRESS); } // internal events private function netStatusHandler(event:NetStatusEvent):void { trace("netStatus", event.info.code); switch (event.info.code) { case "NetStream.Buffer.Empty": _bufferEmpty = true; _isEnded ? sendEvent(HtmlMediaEvent.ENDED) : null; break; case "NetStream.Buffer.Full": _bytesLoaded = _stream.bytesLoaded; _bytesTotal = _stream.bytesTotal; _bufferEmpty = false; sendEvent(HtmlMediaEvent.PROGRESS); break; case "NetConnection.Connect.Success": connectStream(); break; case "NetStream.Play.StreamNotFound": trace("Unable to locate video"); break; // STREAM case "NetStream.Play.Start": _isPaused = false; sendEvent(HtmlMediaEvent.LOADEDDATA); sendEvent(HtmlMediaEvent.CANPLAY); if (!_isPreloading) { sendEvent(HtmlMediaEvent.PLAY); sendEvent(HtmlMediaEvent.PLAYING); } _timer.start(); break; case "NetStream.Seek.Notify": sendEvent(HtmlMediaEvent.SEEKED); break; case "NetStream.Pause.Notify": _isPaused = true; sendEvent(HtmlMediaEvent.PAUSE); break; case "NetStream.Play.Stop": _isEnded = true; _isPaused = false; _timer.stop(); _bufferEmpty ? sendEvent(HtmlMediaEvent.ENDED) : null; break; } } private function securityErrorHandler(event:SecurityErrorEvent):void { trace("securityErrorHandler: " + event); } private function asyncErrorHandler(event:AsyncErrorEvent):void { // ignore AsyncErrorEvent events. } private function onMetaDataHandler(info:Object):void { // Only set the duration when we first load the video if (_duration == 0) { _duration = info.duration; } _framerate = info.framerate; _videoWidth = info.width; _videoHeight = info.height; // set size? sendEvent(HtmlMediaEvent.LOADEDMETADATA); if (_isPreloading) { _stream.pause(); _isPaused = true; _isPreloading = false; sendEvent(HtmlMediaEvent.PROGRESS); sendEvent(HtmlMediaEvent.TIMEUPDATE); } } // interface members public function setSrc(url:String):void { if (_isConnected && _stream) { // stop and restart _stream.pause(); } _currentUrl = url; _isRTMP = !!_currentUrl.match(/^rtmp(s|t|e|te)?\:\/\//) || _streamer != ""; _isConnected = false; _hasStartedPlaying = false; } public function load():void { // disconnect existing stream and connection if (_isConnected && _stream) { _stream.pause(); _stream.close(); _connection.close(); } _isConnected = false; _isPreloading = false; _isEnded = false; _bufferEmpty = false; // start new connection if (_isRTMP) { var rtmpInfo:Object = parseRTMP(_currentUrl); if (_streamer != "") { rtmpInfo.server = _streamer; rtmpInfo.stream = _currentUrl; } _connection.connect(rtmpInfo.server); } else { _connection.connect(null); } // in a few moments the "NetConnection.Connect.Success" event will fire // and call createConnection which finishes the "load" sequence sendEvent(HtmlMediaEvent.LOADSTART); } private function connectStream():void { trace("connectStream"); _stream = new NetStream(_connection); // explicitly set the sound since it could have come before the connection was made _soundTransform = new SoundTransform(_volume); _stream.soundTransform = _soundTransform; // set the buffer to ensure nice playback _stream.bufferTime = 1; _stream.bufferTimeMax = 3; _stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); // same event as connection _stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler); var customClient:Object = new Object(); customClient.onMetaData = onMetaDataHandler; _stream.client = customClient; _video.attachNetStream(_stream); // start downloading without playing )based on preload and play() hasn't been called) // I wish flash had a load() command to make this less awkward if (_preload != "none" && !_playWhenConnected) { _isPaused = true; //stream.bufferTime = 20; _stream.play(getCurrentUrl(0), 0, 0); _stream.pause(); _isPreloading = true; //_stream.pause(); // //sendEvent(HtmlMediaEvent.PAUSE); // have to send this because the "playing" event gets sent via event handlers } _isConnected = true; if (_playWhenConnected && !_hasStartedPlaying) { play(); _playWhenConnected = false; } } public function play():void { if (!_hasStartedPlaying && !_isConnected) { _playWhenConnected = true; load(); return; } if (_hasStartedPlaying) { if (_isPaused) { _stream.resume(); _timer.start(); _isPaused = false; sendEvent(HtmlMediaEvent.PLAY); sendEvent(HtmlMediaEvent.PLAYING); } } else { if (_isRTMP) { var rtmpInfo:Object = parseRTMP(_currentUrl); _stream.play(rtmpInfo.stream); } else { _stream.play(getCurrentUrl(0)); } _timer.start(); _isPaused = false; _hasStartedPlaying = true; // don't toss play/playing events here, because we haven't sent a // canplay / loadeddata event yet. that'll be handled in the net // event listener } } public function pause():void { if (_stream == null) return; _stream.pause(); _isPaused = true; if (_bytesLoaded == _bytesTotal) { _timer.stop(); } _isPaused = true; sendEvent(HtmlMediaEvent.PAUSE); } public function stop():void { if (_stream == null) return; _stream.close(); _isPaused = false; _timer.stop(); sendEvent(HtmlMediaEvent.STOP); } public function setCurrentTime(pos:Number):void { if (_stream == null) { return; } // Calculate the position of the buffered video var bufferPosition:Number = _bytesLoaded / _bytesTotal * _duration; if (_pseudoStreamingEnabled) { sendEvent(HtmlMediaEvent.SEEKING); // Normal seek if it is in buffer and this is the first seek if (pos < bufferPosition && _seekOffset == 0) { _stream.seek(pos); } else { // Uses server-side pseudo-streaming to seek _stream.play(getCurrentUrl(pos)); _seekOffset = pos; } } else { sendEvent(HtmlMediaEvent.SEEKING); _stream.seek(pos); } if (!_isEnded) { sendEvent(HtmlMediaEvent.TIMEUPDATE); } } public function setVolume(volume:Number):void { if (_stream != null) { _soundTransform = new SoundTransform(volume); _stream.soundTransform = _soundTransform; } _volume = volume; _isMuted = (_volume == 0); sendEvent(HtmlMediaEvent.VOLUMECHANGE); } public function getVolume():Number { if(_isMuted) { return 0; } else { return _volume; } } public function setMuted(muted:Boolean):void { if (_isMuted == muted) return; if (muted) { _oldVolume = (_stream == null) ? _oldVolume : _stream.soundTransform.volume; setVolume(0); } else { setVolume(_oldVolume); } _isMuted = muted; } private function sendEvent(eventName:String) { // calculate this to mimic HTML5 _bufferedTime = _bytesLoaded / _bytesTotal * _duration; // build JSON var values:String = "duration:" + _duration + ",framerate:" + _framerate + ",currentTime:" + currentTime() + ",muted:" + _isMuted + ",paused:" + _isPaused + ",ended:" + _isEnded + ",volume:" + _volume + ",src:\"" + _currentUrl + "\"" + ",bytesTotal:" + _bytesTotal + ",bufferedBytes:" + _bytesLoaded + ",bufferedTime:" + _bufferedTime + ",videoWidth:" + _videoWidth + ",videoHeight:" + _videoHeight + ""; _element.sendEvent(eventName, values); } private function parseRTMP(url:String) { var match:Array = url.match(/(.*)\/((flv|mp4|mp3):.*)/); var rtmpInfo:Object = { server: null, stream: null }; if (match) { rtmpInfo.server = match[1]; rtmpInfo.stream = match[2]; } else { rtmpInfo.server = url.replace(/\/[^\/]+$/,"/"); rtmpInfo.stream = url.split("/").pop(); } trace("parseRTMP - server: " + rtmpInfo.server + " stream: " + rtmpInfo.stream); return rtmpInfo; } private function getCurrentUrl(pos:Number):String { var url:String = _currentUrl; if (_pseudoStreamingEnabled) { if (url.indexOf('?') > -1) { url = url + '&' + _pseudoStreamingStartQueryParam + '=' + pos; } else { url = url + '?' + _pseudoStreamingStartQueryParam + '=' + pos; } } return url; } } } \ No newline at end of file
diff --git a/debian/missing-sources/mediaelement/src/htmlelements/YouTubeElement.as b/debian/missing-sources/mediaelement/src/htmlelements/YouTubeElement.as
new file mode 100644
index 0000000..80986fa
--- /dev/null
+++ b/debian/missing-sources/mediaelement/src/htmlelements/YouTubeElement.as
@@ -0,0 +1,403 @@
+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<parameters.length; i++) {
+ var paramParts = parameters[i].split('=');
+ if (paramParts[0] == "v") {
+
+ youTubeId = paramParts[1];
+ break;
+ }
+
+ }
+
+
+ return youTubeId;
+ }
+
+
+ // http://www.youtube.com/v/VIDEO_ID?version=3
+ // http://youtu.be/Djd6tPrxc08
+ private function getYouTubeIdFromUrl(url:String):String {
+
+
+ var youTubeId:String = "";
+
+ // remove any querystring elements
+ var parts:Array = url.split('?');
+ url = parts[0];
+
+ youTubeId = url.substring(url.lastIndexOf("/")+1);
+
+ return youTubeId;
+ }
+
+
+ // interface members
+ public function setSrc(url:String):void {
+ trace("yt setSrc()" + url );
+
+ _currentUrl = url;
+
+ _youTubeId = getYouTubeId(url);
+
+ if (!_playerIsLoaded && !_isChromeless) {
+ _playerLoader.load(new URLRequest("//www.youtube.com/v/" + _youTubeId + "?version=3&controls=0&rel=0&showinfo=0&iv_load_policy=1"));
+ }
+ }
+
+
+
+
+ public function load():void {
+ // do nothing
+ trace("yt load()");
+
+ if (_playerIsLoaded) {
+ player.loadVideoById(_youTubeId);
+ _timer.start();
+ } else {
+ /*
+ if (!_isChromless && _youTubeId != "") {
+ _playerLoader.load(new URLRequest("http://www.youtube.com/v/" + _youTubeId + "?version=3&controls=0&rel=0&showinfo=0&iv_load_policy=1"));
+ }
+ */
+ }
+ }
+
+ public function play():void {
+ if (_playerIsLoaded) {
+ _player.playVideo();
+ }
+
+ }
+
+ public function pause():void {
+ if (_playerIsLoaded) {
+ _player.pauseVideo();
+ }
+ }
+
+ public function stop():void {
+ if (_playerIsLoaded) {
+ _player.pauseVideo();
+ }
+ }
+
+ public function setCurrentTime(pos:Number):void {
+ //_player.seekTo(pos, false);
+ _player.seekTo(pos, true); // works in all places now
+ }
+
+ public function setVolume(volume:Number):void {
+ _player.setVolume(volume*100);
+ _volume = volume;
+ }
+
+ public function getVolume():Number {
+ return _player.getVolume()*100;
+ }
+
+ public function setMuted(muted:Boolean):void {
+ if (muted) {
+ _player.mute();
+
+ } else {
+ _player.unMute();
+ }
+ _isMuted = _player.isMuted();
+ sendEvent(HtmlMediaEvent.VOLUMECHANGE);
+ }
+
+
+ private function sendEvent(eventName:String) {
+
+ // calculate this to mimic HTML5
+ _bufferedTime = _bytesLoaded / _bytesTotal * _duration;
+
+ // build JSON
+ var values:String =
+ "duration:" + _duration +
+ ",framerate:" + _framerate +
+ ",currentTime:" + _currentTime +
+ ",muted:" + _isMuted +
+ ",paused:" + _isPaused +
+ ",ended:" + _isEnded +
+ ",volume:" + _volume +
+ ",src:\"" + _currentUrl + "\"" +
+ ",bytesTotal:" + _bytesTotal +
+ ",bufferedBytes:" + _bytesLoaded +
+ ",bufferedTime:" + _bufferedTime +
+ ",videoWidth:" + _videoWidth +
+ ",videoHeight:" + _videoHeight +
+ "";
+
+ _element.sendEvent(eventName, values);
+ }
+ }
+}