From 821e7e01df2716ec69e2f0d268cb52c9c424957a Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 21 Dec 2013 12:53:02 +0800 Subject: [PATCH] refine the ui buffer effect --- trunk/research/players/js/srs.js | 59 +-- trunk/research/players/srs_player.html | 6 +- .../players/srs_player/release/srs_player.swf | Bin 5126 -> 5159 bytes .../players/srs_player/src/srs_player.as | 468 ++++++++++-------- 4 files changed, 281 insertions(+), 252 deletions(-) diff --git a/trunk/research/players/js/srs.js b/trunk/research/players/js/srs.js index 8ac49c084..83ae3919e 100755 --- a/trunk/research/players/js/srs.js +++ b/trunk/research/players/js/srs.js @@ -234,7 +234,7 @@ SrsPlayer.prototype.on_player_metadata = function(metadata) { SrsPlayer.prototype.on_player_timer = function(time, buffer_length) { // ignore. } -function __srs_on_player_ready(id) { +function __srs_find_player(id) { for (var i = 0; i < SrsPlayer.__players.length; i++) { var player = SrsPlayer.__players[i]; @@ -242,49 +242,34 @@ function __srs_on_player_ready(id) { continue; } - player.on_player_ready(); - return; + return player; } throw new Error("player not found. id=" + id); } +function __srs_on_player_ready(id) { + var player = __srs_find_player(id); + player.on_player_ready(); +} function __srs_on_player_metadata(id, metadata) { - for (var i = 0; i < SrsPlayer.__players.length; i++) { - var player = SrsPlayer.__players[i]; - - if (player.id != id) { - continue; - } - - // user may override the on_player_metadata, - // so set the data before invoke it. - player.metadata = metadata; - - player.on_player_metadata(metadata); - return; - } + var player = __srs_find_player(id); - throw new Error("player not found. id=" + id); + // user may override the on_player_metadata, + // so set the data before invoke it. + player.metadata = metadata; + + player.on_player_metadata(metadata); } function __srs_on_player_timer(id, time, buffer_length) { - for (var i = 0; i < SrsPlayer.__players.length; i++) { - var player = SrsPlayer.__players[i]; - - if (player.id != id) { - continue; - } - - buffer_length = Math.max(0, buffer_length); - buffer_length = Math.min(player.buffer_time, buffer_length); - - // user may override the on_player_timer, - // so set the data before invoke it. - player.time = time; - player.buffer_length = buffer_length; - - player.on_player_timer(time, buffer_length); - return; - } + var player = __srs_find_player(id); - throw new Error("player not found. id=" + id); + buffer_length = Math.max(0, buffer_length); + buffer_length = Math.min(player.buffer_time, buffer_length); + + // user may override the on_player_timer, + // so set the data before invoke it. + player.time = time; + player.buffer_length = buffer_length; + + player.on_player_timer(time, buffer_length); } diff --git a/trunk/research/players/srs_player.html b/trunk/research/players/srs_player.html index 846670987..7faf75a1b 100755 --- a/trunk/research/players/srs_player.html +++ b/trunk/research/players/srs_player.html @@ -100,12 +100,16 @@ $("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")"); select_dar("#btn_dar_original", 0, 0); select_fs_size("#btn_fs_size_screen_100", "screen", 100); - select_buffer_time("#btn_bt_0_8", 0.8); } srs_player.on_player_timer = function(time, buffer_length) { var buffer = buffer_length / srs_player.buffer_time * 100; $("#pb_buffer").width(Number(buffer).toFixed(1) + "%"); + // @remark, hack the default buffer time. + if (!__active_bt && time > 3) { + select_buffer_time("#btn_bt_2", 2); + } + $("#pb_buffer_bg").attr("title", "缓冲区长度:" + Number(buffer_length).toFixed(1) + "秒(" + Number(buffer).toFixed(1) + "%)"); diff --git a/trunk/research/players/srs_player/release/srs_player.swf b/trunk/research/players/srs_player/release/srs_player.swf index 765ecb3b2d0e3ec9b3daccb3018313fe5a299491..e7966ab25820088ad2d5cb1486360ba9d4a3d26f 100755 GIT binary patch literal 5159 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 diff --git a/trunk/research/players/srs_player/src/srs_player.as b/trunk/research/players/srs_player/src/srs_player.as index c3f06a604..0abde2d12 100755 --- a/trunk/research/players/srs_player/src/srs_player.as +++ b/trunk/research/players/srs_player/src/srs_player.as @@ -22,54 +22,60 @@ package public class srs_player extends Sprite { // user set id. - private var id:String = null; + private var js_id:String = null; // user set callback - private var on_player_ready:String = null; - private var on_player_metadata:String = null; - private var on_player_timer:String = null; + private var js_on_player_ready:String = null; + private var js_on_player_metadata:String = null; + private var js_on_player_timer:String = null; // play param url. - private var url:String = null; + private var user_url:String = null; // play param, user set width and height - private var w:int = 0; - private var h:int = 0; + private var user_w:int = 0; + private var user_h:int = 0; // user set dar den:num - private var dar_num:int = 0; - private var dar_den:int = 0; + private var user_dar_num:int = 0; + private var user_dar_den:int = 0; // user set fs(fullscreen) refer and percent. - private var fs_refer:String = null; - private var fs_percent:int = 0; + private var user_fs_refer:String = null; + private var user_fs_percent:int = 0; - private var conn:NetConnection = null; - private var stream:NetStream = null; - private var video:Video = null; - private var metadata:Object = {}; - private var timer:Timer = new Timer(300); + // media specified. + private var media_conn:NetConnection = null; + private var media_stream:NetStream = null; + private var media_video:Video = null; + private var media_metadata:Object = {}; + private var media_timer:Timer = new Timer(300); + // controls. // flash donot allow js to set to fullscreen, // only allow user click to enter fullscreen. - private var fs_mask:Sprite = new Sprite(); + private var control_fs_mask:Sprite = new Sprite(); public function srs_player() { - flash.system.Security.allowDomain("*"); - if (!this.stage) { - this.addEventListener(Event.ADDED_TO_STAGE, this.onAddToStage); + this.addEventListener(Event.ADDED_TO_STAGE, this.system_on_add_to_stage); } else { - this.onAddToStage(null); + this.system_on_add_to_stage(null); } } - private function onAddToStage(evt:Event):void { + /** + * system event callback, when this control added to stage. + * the main function. + */ + private function system_on_add_to_stage(evt:Event):void { + this.removeEventListener(Event.ADDED_TO_STAGE, this.system_on_add_to_stage); + this.stage.align = StageAlign.TOP_LEFT; this.stage.scaleMode = StageScaleMode.NO_SCALE; - this.stage.addEventListener(FullScreenEvent.FULL_SCREEN, this.on_stage_fullscreen); + this.stage.addEventListener(FullScreenEvent.FULL_SCREEN, this.user_on_stage_fullscreen); - this.addChild(this.fs_mask); - this.fs_mask.buttonMode = true; - this.fs_mask.addEventListener(MouseEvent.CLICK, on_user_click_video); + this.addChild(this.control_fs_mask); + this.control_fs_mask.buttonMode = true; + this.control_fs_mask.addEventListener(MouseEvent.CLICK, user_on_click_video); this.contextMenu = new ContextMenu(); this.contextMenu.hideBuiltInItems(); @@ -83,40 +89,25 @@ package throw new Error("must specifies the on_player_ready"); } - this.id = flashvars.id; - this.on_player_ready = flashvars.on_player_ready; - this.on_player_metadata = flashvars.on_player_metadata; - this.on_player_timer = flashvars.on_player_timer; + this.js_id = flashvars.id; + this.js_on_player_ready = flashvars.on_player_ready; + this.js_on_player_metadata = flashvars.on_player_metadata; + this.js_on_player_timer = flashvars.on_player_timer; - this.timer.addEventListener(TimerEvent.TIMER, this.on_timer); - this.timer.start(); + this.media_timer.addEventListener(TimerEvent.TIMER, this.system_on_timer); + this.media_timer.start(); - flash.utils.setTimeout(this.on_js_ready, 0); + flash.utils.setTimeout(this.system_on_js_ready, 0); } - private function on_timer(evt:TimerEvent):void { - if (!this.stream) { - trace("stream is null, ignore timer event."); - return; - } - - trace("notify js the timer event."); - flash.external.ExternalInterface.call( - this.on_player_timer, this.id, this.stream.time, this.stream.bufferLength); - } - - private function on_stage_fullscreen(evt:FullScreenEvent):void { - if (!evt.fullScreen) { - execute_user_set_dar(); - } else { - execute_user_enter_fullscreen(); - } - } - - private function on_js_ready():void { + /** + * system callack event, when js ready, register callback for js. + * the actual main function. + */ + private function system_on_js_ready():void { if (!flash.external.ExternalInterface.available) { trace("js not ready, try later."); - flash.utils.setTimeout(this.on_js_ready, 100); + flash.utils.setTimeout(this.system_on_js_ready, 100); return; } @@ -128,53 +119,74 @@ package flash.external.ExternalInterface.addCallback("__set_fs", this.js_call_set_fs_size); flash.external.ExternalInterface.addCallback("__set_bt", this.js_call_set_bt); - flash.external.ExternalInterface.call(this.on_player_ready, this.id); - } - - private function js_call_pause():void { - if (this.stream) { - this.stream.pause(); - } - } - - private function js_call_resume():void { - if (this.stream) { - this.stream.resume(); - } + flash.external.ExternalInterface.call(this.js_on_player_ready, this.js_id); } /** - * to set the DAR, for example, DAR=16:9 - * @param num, for example, 9. - * use metadata height if 0. - * use user specified height if -1. - * @param den, for example, 16. - * use metadata width if 0. - * use user specified width if -1. - */ - private function js_call_dar(num:int, den:int):void { - dar_num = num; - dar_den = den; - - flash.utils.setTimeout(execute_user_set_dar, 0); - } - - /** - * set the fullscreen size data. - * @refer the refer fullscreen mode. it can be: - * video: use video orignal size. - * screen: use screen size to rescale video. - * @param percent, the rescale percent, where - * 100 means 100%. - */ - private function js_call_set_fs_size(refer:String, percent:int):void { - fs_refer = refer; - fs_percent = percent; - } - /** - * js cannot enter the fullscreen mode, user must click to. + * system callack event, timer to do some regular tasks. */ - private function on_user_click_video(evt:MouseEvent):void { + private function system_on_timer(evt:TimerEvent):void { + if (!this.media_stream) { + trace("stream is null, ignore timer event."); + return; + } + + trace("notify js the timer event."); + flash.external.ExternalInterface.call( + this.js_on_player_timer, this.js_id, this.media_stream.time, this.media_stream.bufferLength); + } + + /** + * system callack event, when got metadata from stream. + * or got video dimension change event(the DAR notification), to update the metadata manually. + */ + private function system_on_metadata(metadata:Object):void { + this.media_metadata = metadata; + + // for context menu + var customItems:Array = [new ContextMenuItem("SrsPlayer")]; + if (metadata.hasOwnProperty("server")) { + customItems.push(new ContextMenuItem("Server: " + metadata.server)); + } + if (metadata.hasOwnProperty("contributor")) { + customItems.push(new ContextMenuItem("Contributor: " + metadata.contributor)); + } + contextMenu.customItems = customItems; + + // for js. + var obj:Object = __get_video_size_object(); + + obj.server = 'srs'; + obj.contributor = 'winlin'; + + if (metadata.hasOwnProperty("server")) { + obj.server = metadata.server; + } + if (metadata.hasOwnProperty("contributor")) { + obj.contributor = metadata.contributor; + } + + var code:int = flash.external.ExternalInterface.call(js_on_player_metadata, js_id, obj); + if (code != 0) { + throw new Error("callback on_player_metadata failed. code=" + code); + } + } + + /** + * player callack event, when user click video to enter or leave fullscreen. + */ + private function user_on_stage_fullscreen(evt:FullScreenEvent):void { + if (!evt.fullScreen) { + __execute_user_set_dar(); + } else { + __execute_user_enter_fullscreen(); + } + } + + /** + * user event callback, js cannot enter the fullscreen mode, user must click to. + */ + private function user_on_click_video(evt:MouseEvent):void { if (!this.stage.allowsFullScreen) { trace("donot allow fullscreen."); return; @@ -188,55 +200,100 @@ package } } + /** + * function for js to call: to pause the stream. ignore if not play. + */ + private function js_call_pause():void { + if (this.media_stream) { + this.media_stream.pause(); + } + } + + /** + * function for js to call: to resume the stream. ignore if not play. + */ + private function js_call_resume():void { + if (this.media_stream) { + this.media_stream.resume(); + } + } + + /** + * to set the DAR, for example, DAR=16:9 + * @param num, for example, 9. + * use metadata height if 0. + * use user specified height if -1. + * @param den, for example, 16. + * use metadata width if 0. + * use user specified width if -1. + */ + private function js_call_dar(num:int, den:int):void { + user_dar_num = num; + user_dar_den = den; + + flash.utils.setTimeout(__execute_user_set_dar, 0); + } + + /** + * set the fullscreen size data. + * @refer the refer fullscreen mode. it can be: + * video: use video orignal size. + * screen: use screen size to rescale video. + * @param percent, the rescale percent, where + * 100 means 100%. + */ + private function js_call_set_fs_size(refer:String, percent:int):void { + user_fs_refer = refer; + user_fs_percent = percent; + } + /** * set the stream buffer time in seconds. * @buffer_time the buffer time in seconds. */ private function js_call_set_bt(buffer_time:Number):void { - if (this.stream) { - this.stream.bufferTime = buffer_time; + if (this.media_stream) { + this.media_stream.bufferTime = buffer_time; } } + /** + * function for js to call: to stop the stream. ignore if not play. + */ private function js_call_stop():void { - if (this.stream) { - this.stream.close(); - this.stream = null; + if (this.media_stream) { + this.media_stream.close(); + this.media_stream = null; } - if (this.conn) { - this.conn.close(); - this.conn = null; + if (this.media_conn) { + this.media_conn.close(); + this.media_conn = null; } - if (this.video) { - this.removeChild(this.video); - this.video = null; + if (this.media_video) { + this.removeChild(this.media_video); + this.media_video = null; } } - private function draw_black_background(_width:int, _height:int):void { - // draw black bg. - this.graphics.beginFill(0x00, 1.0); - this.graphics.drawRect(0, 0, _width, _height); - this.graphics.endFill(); - - // draw the fs mask. - this.fs_mask.graphics.beginFill(0xff0000, 0); - this.fs_mask.graphics.drawRect(0, 0, _width, _height); - this.fs_mask.graphics.endFill(); - } - - private function js_call_play(url:String, _width:int, _height:int, _buffer_time:Number):void { - this.url = url; - this.w = _width; - this.h = _height; - trace("start to play url: " + this.url + ", w=" + this.w + ", h=" + this.h); + /** + * function for js to call: to play the stream. stop then play. + * @param url, the rtmp/http url to play. + * @param _width, the player width. + * @param _height, the player height. + * @param buffer_time, the buffer time in seconds. recommend to >=0.5 + */ + private function js_call_play(url:String, _width:int, _height:int, buffer_time:Number):void { + this.user_url = url; + this.user_w = _width; + this.user_h = _height; + trace("start to play url: " + this.user_url + ", w=" + this.user_w + ", h=" + this.user_h); js_call_stop(); - this.conn = new NetConnection(); - this.conn.client = {}; - this.conn.client.onBWDone = function():void {}; - this.conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { + this.media_conn = new NetConnection(); + this.media_conn.client = {}; + this.media_conn.client.onBWDone = function():void {}; + this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { trace ("NetConnection: code=" + evt.info.code); // TODO: FIXME: failed event. @@ -244,77 +301,45 @@ package return; } - stream = new NetStream(conn); - stream.bufferTime = _buffer_time; - stream.client = {}; - stream.client.onMetaData = on_metadata; - stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { + media_stream = new NetStream(media_conn); + media_stream.bufferTime = buffer_time; + media_stream.client = {}; + media_stream.client.onMetaData = system_on_metadata; + media_stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { trace ("NetStream: code=" + evt.info.code); if (evt.info.code == "NetStream.Video.DimensionChange") { - on_metadata(metadata); + system_on_metadata(media_metadata); } // TODO: FIXME: failed event. }); if (url.indexOf("http") == 0) { - stream.play(url); + media_stream.play(url); } else { var streamName:String = url.substr(url.lastIndexOf("/")); - stream.play(streamName); + media_stream.play(streamName); } - video = new Video(); - video.width = _width; - video.height = _height; - video.attachNetStream(stream); - video.smoothing = true; - addChild(video); + media_video = new Video(); + media_video.width = _width; + media_video.height = _height; + media_video.attachNetStream(media_stream); + media_video.smoothing = true; + addChild(media_video); - draw_black_background(_width, _height); + __draw_black_background(_width, _height); // lowest layer, for mask to cover it. - setChildIndex(video, 0); + setChildIndex(media_video, 0); }); if (url.indexOf("http") == 0) { - this.conn.connect(null); + this.media_conn.connect(null); } else { - var tcUrl:String = this.url.substr(0, this.url.lastIndexOf("/")); - this.conn.connect(tcUrl); - } - } - - private function on_metadata(metadata:Object):void { - this.metadata = metadata; - - // for context menu - var customItems:Array = [new ContextMenuItem("SrsPlayer")]; - if (metadata.hasOwnProperty("server")) { - customItems.push(new ContextMenuItem("Server: " + metadata.server)); - } - if (metadata.hasOwnProperty("contributor")) { - customItems.push(new ContextMenuItem("Contributor: " + metadata.contributor)); - } - contextMenu.customItems = customItems; - - // for js. - var obj:Object = get_video_size_object(); - - obj.server = 'srs'; - obj.contributor = 'winlin'; - - if (metadata.hasOwnProperty("server")) { - obj.server = metadata.server; - } - if (metadata.hasOwnProperty("contributor")) { - obj.contributor = metadata.contributor; - } - - var code:int = flash.external.ExternalInterface.call(on_player_metadata, id, obj); - if (code != 0) { - throw new Error("callback on_player_metadata failed. code=" + code); + var tcUrl:String = this.user_url.substr(0, this.user_url.lastIndexOf("/")); + this.media_conn.connect(tcUrl); } } @@ -324,26 +349,26 @@ package * 2. override with metadata size if specified. * 3. override with codec size if specified. */ - private function get_video_size_object():Object { + private function __get_video_size_object():Object { var obj:Object = { - width: video.width, - height: video.height + width: media_video.width, + height: media_video.height }; // override with metadata size. - if (metadata.hasOwnProperty("width")) { - obj.width = metadata.width; + if (this.media_metadata.hasOwnProperty("width")) { + obj.width = this.media_metadata.width; } - if (metadata.hasOwnProperty("height")) { - obj.height = metadata.height; + if (this.media_metadata.hasOwnProperty("height")) { + obj.height = this.media_metadata.height; } // override with codec size. - if (video.videoWidth > 0) { - obj.width = video.videoWidth; + if (media_video.videoWidth > 0) { + obj.width = media_video.videoWidth; } - if (video.videoHeight > 0) { - obj.height = video.videoHeight; + if (media_video.videoHeight > 0) { + obj.height = media_video.videoHeight; } return obj; @@ -352,17 +377,17 @@ package /** * execute the enter fullscreen action. */ - private function execute_user_enter_fullscreen():void { - if (!fs_refer || fs_percent <= 0) { + private function __execute_user_enter_fullscreen():void { + if (!user_fs_refer || user_fs_percent <= 0) { return; } // change to video size if refer to video. - var obj:Object = get_video_size_object(); + var obj:Object = __get_video_size_object(); // get the DAR - var num:int = dar_num; - var den:int = dar_den; + var num:int = user_dar_num; + var den:int = user_dar_den; if (num == 0) { num = obj.height; @@ -379,7 +404,7 @@ package } // for refer is screen. - if (fs_refer == "screen") { + if (user_fs_refer == "screen") { obj = { width: this.stage.fullScreenWidth, height: this.stage.fullScreenHeight @@ -387,34 +412,34 @@ package } // rescale to fs - update_video_size(num, den, obj.width * fs_percent / 100, obj.height * fs_percent / 100, this.stage.fullScreenWidth, this.stage.fullScreenHeight); + __update_video_size(num, den, obj.width * user_fs_percent / 100, obj.height * user_fs_percent / 100, this.stage.fullScreenWidth, this.stage.fullScreenHeight); } /** * for user set dar, or leave fullscreen to recover the dar. */ - private function execute_user_set_dar():void { + private function __execute_user_set_dar():void { // get the DAR - var num:int = dar_num; - var den:int = dar_den; + var num:int = user_dar_num; + var den:int = user_dar_den; - var obj:Object = get_video_size_object(); + var obj:Object = __get_video_size_object(); if (num == 0) { num = obj.height; } if (num == -1) { - num = this.h; + num = this.user_h; } if (den == 0) { den = obj.width; } if (den == -1) { - den = this.w; + den = this.user_w; } - update_video_size(num, den, this.w, this.h, this.w, this.h); + __update_video_size(num, den, this.user_w, this.user_h, this.user_w, this.user_h); } /** @@ -426,8 +451,8 @@ package * @param _w/_h the video draw paper size. used to rescale the player together with DAR. * @param _sw/_wh the stage size, >= paper size. used to center the player. */ - private function update_video_size(_num:int, _den:int, _w:int, _h:int, _sw:int, _sh:int):void { - if (!this.video || _num <= 0 || _den <= 0) { + private function __update_video_size(_num:int, _den:int, _w:int, _h:int, _sw:int, _sh:int):void { + if (!this.media_video || _num <= 0 || _den <= 0) { return; } @@ -435,21 +460,36 @@ package // calc the height by DAR var _height:int = _w * _num / _den; if (_height <= _h) { - this.video.width = _w; - this.video.height = _height; + this.media_video.width = _w; + this.media_video.height = _height; } else { // height overflow, calc the width by DAR var _width:int = _h * _den / _num; - this.video.width = _width; - this.video.height = _h; + this.media_video.width = _width; + this.media_video.height = _h; } // align center. - this.video.x = (_sw - this.video.width) / 2; - this.video.y = (_sh - this.video.height) / 2; + this.media_video.x = (_sw - this.media_video.width) / 2; + this.media_video.y = (_sh - this.media_video.height) / 2; - draw_black_background(_sw, _sh); + __draw_black_background(_sw, _sh); + } + + /** + * draw black background and draw the fullscreen mask. + */ + private function __draw_black_background(_width:int, _height:int):void { + // draw black bg. + this.graphics.beginFill(0x00, 1.0); + this.graphics.drawRect(0, 0, _width, _height); + this.graphics.endFill(); + + // draw the fs mask. + this.control_fs_mask.graphics.beginFill(0xff0000, 0); + this.control_fs_mask.graphics.drawRect(0, 0, _width, _height); + this.control_fs_mask.graphics.endFill(); } } } \ No newline at end of file