package htmlelements {
import flash.display.Sprite;
import flash.media.Video;
import flash.media.SoundTransform;
import org.mangui.hls.HLS;
import org.mangui.hls.HLSSettings;
import org.mangui.hls.event.HLSEvent;
import org.mangui.hls.constant.HLSPlayStates;
import org.mangui.hls.utils.Log;
public class HLSMediaElement extends Sprite implements IMediaElement {
private var _element:FlashMediaElement;
private var _playqueued:Boolean = false;
private var _autoplay:Boolean = true;
private var _preload:String = "";
private var _hls:HLS;
private var _url:String;
private var _video:Video;
private var _hlsState:String = HLSPlayStates.IDLE;
// event values
private var _position:Number = 0;
private var _duration:Number = 0;
private var _framerate:Number;
private var _isManifestLoaded:Boolean = false;
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;
public function HLSMediaElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number) {
_element = element;
_autoplay = autoplay;
_volume = startVolume;
_preload = preload;
_video = new Video();
addChild(_video);
//HLSSettings.logDebug = true;
_hls = new HLS();
_hls.addEventListener(HLSEvent.PLAYBACK_COMPLETE,_completeHandler);
_hls.addEventListener(HLSEvent.ERROR,_errorHandler);
_hls.addEventListener(HLSEvent.MANIFEST_LOADED,_manifestHandler);
_hls.addEventListener(HLSEvent.MEDIA_TIME,_mediaTimeHandler);
_hls.addEventListener(HLSEvent.PLAYBACK_STATE,_stateHandler);
_hls.addEventListener(HLSEvent.FRAGMENT_PLAYING,_fragmentHandler);
_hls.stream.soundTransform = new SoundTransform(_volume);
_video.attachNetStream(_hls.stream);
}
private function _completeHandler(event:HLSEvent):void {
_isEnded = true;
_isPaused = true;
sendEvent(HtmlMediaEvent.PAUSE);
sendEvent(HtmlMediaEvent.ENDED);
};
private function _errorHandler(event:HLSEvent):void {
_element.logMessage(event.toString());
};
private function _fragmentHandler(event:HLSEvent):void {
sendEvent(HtmlMediaEvent.FRAGMENT_PLAYING);
};
private function _manifestHandler(event:HLSEvent):void {
_duration = event.levels[0].duration;
_videoWidth = event.levels[0].width;
_videoHeight = event.levels[0].height;
_isManifestLoaded = true;
_hls.stage = _video.stage;
sendEvent(HtmlMediaEvent.LOADEDMETADATA);
sendEvent(HtmlMediaEvent.CANPLAY);
if(_autoplay || _playqueued) {
_playqueued = false;
_hls.stream.play();
}
};
private function _mediaTimeHandler(event:HLSEvent):void {
_position = event.mediatime.position;
_duration = event.mediatime.duration;
_bufferedTime = event.mediatime.buffer+event.mediatime.position;
sendEvent(HtmlMediaEvent.PROGRESS);
sendEvent(HtmlMediaEvent.TIMEUPDATE);
var videoWidth:int = _video.videoWidth;
var videoHeight:int = _video.videoHeight;
var neverSetted:Boolean = _videoWidth <= 0 || _videoHeight <= 0;
if (videoWidth && videoHeight && neverSetted) {
_videoHeight = videoHeight;
_videoWidth = videoWidth;
_element.setVideoSize(_videoWidth, _videoHeight);
}
};
private function _stateHandler(event:HLSEvent):void {
_hlsState = event.state;
//Log.txt("state:"+ _hlsState);
switch(event.state) {
case HLSPlayStates.IDLE:
break;
case HLSPlayStates.PAUSED_BUFFERING:
case HLSPlayStates.PLAYING_BUFFERING:
_isPaused = true;
sendEvent(HtmlMediaEvent.BUFFERING);
break;
case HLSPlayStates.PLAYING:
_isPaused = false;
_isEnded = false;
_video.visible = true;
sendEvent(HtmlMediaEvent.LOADEDDATA);
sendEvent(HtmlMediaEvent.PLAY);
sendEvent(HtmlMediaEvent.PLAYING);
break;
case HLSPlayStates.PAUSED:
_isPaused = true;
_isEnded = false;
sendEvent(HtmlMediaEvent.PAUSE);
sendEvent(HtmlMediaEvent.CANPLAY);
break;
}
};
public function get video():Video {
return _video;
}
public function get videoHeight():Number {
return _videoHeight;
}
public function get videoWidth():Number {
return _videoWidth;
}
public function play():void {
//Log.txt("HLSMediaElement:play");
if(!_isManifestLoaded) {
_playqueued = true;
return;
}
if (_hlsState == HLSPlayStates.PAUSED || _hlsState == HLSPlayStates.PAUSED_BUFFERING) {
_hls.stream.resume();
} else {
_hls.stream.play();
}
}
public function pause():void {
if(!_isManifestLoaded)
return;
//Log.txt("HLSMediaElement:pause");
_hls.stream.pause();
}
public function load():void{
//Log.txt("HLSMediaElement:load");
if(_url) {
sendEvent(HtmlMediaEvent.LOADSTART);
_hls.load(_url);
}
}
public function stop():void{
_hls.stream.close();
_video.clear();
_isManifestLoaded = false;
_duration = 0;
_position = 0;
_playqueued = false;
sendEvent(HtmlMediaEvent.STOP);
}
public function setSrc(url:String):void{
//Log.txt("HLSMediaElement:setSrc:"+url);
stop();
_url = url;
_hls.load(_url);
}
public function setSize(width:Number, height:Number):void{
_video.width = width;
_video.height = height;
}
public function setCurrentTime(pos:Number):void{
if(!_isManifestLoaded)
return;
sendEvent(HtmlMediaEvent.SEEKING);
_hls.stream.seek(pos);
}
public function setVolume(vol:Number):void{
_volume = vol;
_isMuted = (_volume == 0);
_hls.stream.soundTransform = new SoundTransform(vol);
sendEvent(HtmlMediaEvent.VOLUMECHANGE);
}
public function getVolume():Number {
if(_isMuted) {
return 0;
} else {
return _volume;
}
}
public function setMuted(muted:Boolean):void {
// ignore if no change
if (muted === _isMuted)
return;
_isMuted = muted;
if (muted) {
_hls.stream.soundTransform = new SoundTransform(0);
sendEvent(HtmlMediaEvent.VOLUMECHANGE);
} else {
setVolume(_volume);
}
}
public function duration():Number{
return _duration;
}
public function currentTime():Number{
return _position;
}
public function seekLimit():Number {
return _duration;
}
public function currentProgress():Number {
var progress:Number = 0;
if (_duration != 0) {
progress = Math.round( (_bufferedTime / _duration) * 100 );
}
return progress;
}
private function sendEvent(eventName:String):void {
// build JSON
var values:String =
"duration:" + _duration +
",framerate:" + _hls.stream.currentFPS +
",currentTime:" + _position +
",muted:" + _isMuted +
",paused:" + _isPaused +
",ended:" + _isEnded +
",volume:" + _volume +
",src:\"" + _url + "\"" +
",bytesTotal:" + Math.round(1000*_duration) +
",bufferedBytes:" + Math.round(1000*(_position+_bufferedTime)) +
",bufferedTime:" + _bufferedTime +
",videoWidth:" + _videoWidth +
",videoHeight:" + _videoHeight +
"";
_element.sendEvent(eventName, values);
}
}
}