winlin

update the srs player, set the DAR.

@@ -15,8 +15,14 @@ @@ -15,8 +15,14 @@
15 <script type="text/javascript" src="js/jwplayer.js" ></script> 15 <script type="text/javascript" src="js/jwplayer.js" ></script>
16 <script type='text/javascript'>jwplayer.key = 'N8zhkmYvvRwOhz4aTGkySoEri4x+9pQwR7GHIQ=='; </script> 16 <script type='text/javascript'>jwplayer.key = 'N8zhkmYvvRwOhz4aTGkySoEri4x+9pQwR7GHIQ=='; </script>
17 <script type="text/javascript"> 17 <script type="text/javascript">
18 - function jwplayer_play(url) {  
19 var _player = null; 18 var _player = null;
  19 + var _url = null;
  20 + $(function(){
  21 + // get the vhost and port to set the default url.
  22 + // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo
  23 + // url set to: rtmp://demo:1935/live/livestream
  24 + srs_init("#txt_rtmp_url", "#txt_hls_url");
  25 +
20 $("#main_modal").on("hide", function(){ 26 $("#main_modal").on("hide", function(){
21 $("#div_container").remove(); 27 $("#div_container").remove();
22 _player.stop(); 28 _player.stop();
@@ -35,7 +41,7 @@ @@ -35,7 +41,7 @@
35 $("#player").append(obj); 41 $("#player").append(obj);
36 42
37 var conf = { 43 var conf = {
38 - file: url, 44 + file: _url,
39 width: "530", 45 width: "530",
40 height: "300", 46 height: "300",
41 autostart: true, 47 autostart: true,
@@ -44,23 +50,14 @@ @@ -44,23 +50,14 @@
44 _player = jwplayer('player_id').setup(conf); 50 _player = jwplayer('player_id').setup(conf);
45 }); 51 });
46 52
47 - $("#main_modal").modal({show:true, keyboard:false});  
48 - }  
49 -  
50 - $(function(){  
51 - // get the vhost and port to set the default url.  
52 - // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo  
53 - // url set to: rtmp://demo:1935/live/livestream  
54 - srs_init("#txt_rtmp_url", "#txt_hls_url");  
55 -  
56 $("#btn_play_rtmp").click(function(){ 53 $("#btn_play_rtmp").click(function(){
57 - var url = $("#txt_rtmp_url").val();  
58 - jwplayer_play(url); 54 + _url = $("#txt_rtmp_url").val();
  55 + $("#main_modal").modal({show:true, keyboard:false});
59 }); 56 });
60 57
61 $("#btn_play_hls").click(function(){ 58 $("#btn_play_hls").click(function(){
62 - var url = $("#txt_hls_url").val();  
63 - jwplayer_play(url); 59 + _url = $("#txt_hls_url").val();
  60 + $("#main_modal").modal({show:true, keyboard:false});
64 }); 61 });
65 }); 62 });
66 </script> 63 </script>
@@ -14,17 +14,7 @@ @@ -14,17 +14,7 @@
14 } 14 }
15 </style> 15 </style>
16 <script type="text/javascript"> 16 <script type="text/javascript">
17 - $(function(){  
18 - // get the vhost and port to set the default url.  
19 - // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo  
20 - // url set to: rtmp://demo:1935/live/livestream  
21 - srs_init($("#txt_url"));  
22 -  
23 - $("#btn_play").click(function(){  
24 - $("#main_modal").on("hide", function(){  
25 - $("#div_container").remove();  
26 - });  
27 - $("#main_modal").on("show", function(){ 17 + function osmf_play(url) {
28 $("#div_container").remove(); 18 $("#div_container").remove();
29 19
30 var obj = $("<div/>"); 20 var obj = $("<div/>");
@@ -36,8 +26,6 @@ @@ -36,8 +26,6 @@
36 26
37 $("#player").append(obj); 27 $("#player").append(obj);
38 28
39 - var url = $("#txt_url").val();  
40 -  
41 var flashvars = {}; 29 var flashvars = {};
42 flashvars.src = url; 30 flashvars.src = url;
43 flashvars.streamType = "live"; // live or recorded 31 flashvars.streamType = "live"; // live or recorded
@@ -57,7 +45,23 @@ @@ -57,7 +45,23 @@
57 "11.1", "js/AdobeFlashPlayerInstall.swf", 45 "11.1", "js/AdobeFlashPlayerInstall.swf",
58 flashvars, params, attributes 46 flashvars, params, attributes
59 ); 47 );
  48 + }
  49 + $(function(){
  50 + // get the vhost and port to set the default url.
  51 + // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo
  52 + // url set to: rtmp://demo:1935/live/livestream
  53 + srs_init($("#txt_url"));
  54 +
  55 + $("#main_modal").on("hide", function(){
  56 + osmf_play("http://localhost");
  57 + $("#div_container").remove();
  58 + });
  59 + $("#main_modal").on("show", function(){
  60 + var url = $("#txt_url").val();
  61 + osmf_play(url);
60 }); 62 });
  63 +
  64 + $("#btn_play").click(function(){
61 $("#main_modal").modal({show:true, keyboard:false}); 65 $("#main_modal").modal({show:true, keyboard:false});
62 }); 66 });
63 }); 67 });
@@ -14,26 +14,14 @@ @@ -14,26 +14,14 @@
14 } 14 }
15 </style> 15 </style>
16 <script type="text/javascript"> 16 <script type="text/javascript">
17 - var srs_player = null;  
18 -  
19 $(function(){ 17 $(function(){
20 // get the vhost and port to set the default url. 18 // get the vhost and port to set the default url.
21 // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo 19 // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo
22 // url set to: rtmp://demo:1935/live/livestream 20 // url set to: rtmp://demo:1935/live/livestream
23 srs_init($("#txt_url")); 21 srs_init($("#txt_url"));
24 22
25 - $("#btn_play").click(on_btn_play);  
26 - $("#btn_pause").click(function(){  
27 - if ($("#btn_pause").text() == "暂停") {  
28 - $("#btn_pause").text("继续");  
29 - srs_player.pause();  
30 - } else {  
31 - $("#btn_pause").text("暂停");  
32 - srs_player.resume();  
33 - }  
34 - });  
35 - });  
36 - function on_btn_play(){ 23 + var srs_player = null;
  24 +
37 $("#main_modal").on("show", function(){ 25 $("#main_modal").on("show", function(){
38 $("#div_container").remove(); 26 $("#div_container").remove();
39 27
@@ -50,9 +38,12 @@ @@ -50,9 +38,12 @@
50 38
51 srs_player = new SrsPlayer("player_id", url, 530, 300, 0.8); 39 srs_player = new SrsPlayer("player_id", url, 530, 300, 0.8);
52 srs_player.on_player_ready = function() { 40 srs_player.on_player_ready = function() {
53 - // hack the callback function, do something then play.  
54 return srs_player.play(); 41 return srs_player.play();
55 } 42 }
  43 + srs_player.on_player_metadata = function(metadata) {
  44 + $("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")");
  45 + return 0;
  46 + }
56 srs_player.start(); 47 srs_player.start();
57 }); 48 });
58 49
@@ -60,10 +51,37 @@ @@ -60,10 +51,37 @@
60 srs_player.stop(); 51 srs_player.stop();
61 }); 52 });
62 53
  54 + $("#btn_play").click(function(){
63 $("#main_modal").modal({show:true, keyboard:false}); 55 $("#main_modal").modal({show:true, keyboard:false});
  56 + });
  57 +
  58 + $("#btn_pause").click(function(){
  59 + if ($("#btn_pause").text() == "暂停") {
  60 + $("#btn_pause").text("继续");
  61 + srs_player.pause();
  62 + } else {
  63 + $("#btn_pause").text("暂停");
  64 + srs_player.resume();
64 } 65 }
  66 + });
65 67
66 - // the SrsPlayer object. 68 + $("#btn_dar_original").click(function(){
  69 + srs_player.dar(0, 0);
  70 + });
  71 + $("#btn_dar_21_9").click(function(){
  72 + srs_player.dar(9, 21);
  73 + });
  74 + $("#btn_dar_16_9").click(function(){
  75 + srs_player.dar(9, 16);
  76 + });
  77 + $("#btn_dar_4_3").click(function(){
  78 + srs_player.dar(3, 4);
  79 + });
  80 + });
  81 +
  82 + /*
  83 + * the SrsPlayer object.
  84 + */
67 function SrsPlayer(container, stream_url, width, height, buffer_time) { 85 function SrsPlayer(container, stream_url, width, height, buffer_time) {
68 if (!SrsPlayer.__id) { 86 if (!SrsPlayer.__id) {
69 SrsPlayer.__id = 100; 87 SrsPlayer.__id = 100;
@@ -81,18 +99,27 @@ @@ -81,18 +99,27 @@
81 this.buffer_time = buffer_time; 99 this.buffer_time = buffer_time;
82 this.id = SrsPlayer.__id++; 100 this.id = SrsPlayer.__id++;
83 this.callbackObj = null; 101 this.callbackObj = null;
  102 +
  103 + // callback set the following values.
  104 + this.meatadata = {}; // for on_player_metadata
84 } 105 }
85 - // user can set some callback, then start the player.  
86 - // callbacks:  
87 - // on_player_ready():int, when srs player ready, user can play. 106 + /*
  107 + * user can set some callback, then start the player.
  108 + * callbacks:
  109 + * on_player_ready():int, when srs player ready, user can play.
  110 + * on_player_metadata(metadata:Object):int, when srs player get metadata.
  111 + */
88 SrsPlayer.prototype.start = function() { 112 SrsPlayer.prototype.start = function() {
89 // embed the flash. 113 // embed the flash.
90 var flashvars = {}; 114 var flashvars = {};
91 flashvars.id = this.id; 115 flashvars.id = this.id;
92 flashvars.on_player_ready = "__srs_on_player_ready"; 116 flashvars.on_player_ready = "__srs_on_player_ready";
  117 + flashvars.on_player_metadata = "__srs_on_player_metadata";
93 118
94 var params = {}; 119 var params = {};
  120 + params.wmode = "opaque";
95 params.allowFullScreen = true; 121 params.allowFullScreen = true;
  122 + params.allowScriptAccess = "always";
96 123
97 var attributes = {}; 124 var attributes = {};
98 125
@@ -114,6 +141,16 @@ @@ -114,6 +141,16 @@
114 return this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time); 141 return this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time);
115 } 142 }
116 SrsPlayer.prototype.stop = function() { 143 SrsPlayer.prototype.stop = function() {
  144 + for (var i = 0; i < SrsPlayer.__players.length; i++) {
  145 + var player = SrsPlayer.__players[i];
  146 +
  147 + if (player.id != this.id) {
  148 + continue;
  149 + }
  150 +
  151 + SrsPlayer.__players.splice(i, 1);
  152 + break;
  153 + }
117 return this.callbackObj.ref.__stop(); 154 return this.callbackObj.ref.__stop();
118 } 155 }
119 SrsPlayer.prototype.pause = function() { 156 SrsPlayer.prototype.pause = function() {
@@ -122,9 +159,26 @@ @@ -122,9 +159,26 @@
122 SrsPlayer.prototype.resume = function() { 159 SrsPlayer.prototype.resume = function() {
123 return this.callbackObj.ref.__resume(); 160 return this.callbackObj.ref.__resume();
124 } 161 }
  162 + /*
  163 + * to set the DAR, for example, DAR=16:9
  164 + * @param num, for example, 9. use metadata height if 0.
  165 + * @param den, for example, 16. use metadata width if 0.
  166 + */
  167 + SrsPlayer.prototype.dar = function(num, den) {
  168 + if (num == 0 && this.metadata) {
  169 + num = this.metadata.height;
  170 + }
  171 + if (den == 0 && this.metadata) {
  172 + den = this.metadata.width;
  173 + }
  174 + return this.callbackObj.ref.__dar(num, den);
  175 + }
125 SrsPlayer.prototype.on_player_ready = function() { 176 SrsPlayer.prototype.on_player_ready = function() {
126 return this.play(); 177 return this.play();
127 } 178 }
  179 + SrsPlayer.prototype.on_player_metadata = function(metadata) {
  180 + return 0;
  181 + }
128 function __srs_on_player_ready(id) { 182 function __srs_on_player_ready(id) {
129 for (var i = 0; i < SrsPlayer.__players.length; i++) { 183 for (var i = 0; i < SrsPlayer.__players.length; i++) {
130 var player = SrsPlayer.__players[i]; 184 var player = SrsPlayer.__players[i];
@@ -138,6 +192,23 @@ @@ -138,6 +192,23 @@
138 192
139 throw new Error("player not found. id=" + id); 193 throw new Error("player not found. id=" + id);
140 } 194 }
  195 + function __srs_on_player_metadata(id, metadata) {
  196 + for (var i = 0; i < SrsPlayer.__players.length; i++) {
  197 + var player = SrsPlayer.__players[i];
  198 +
  199 + if (player.id != id) {
  200 + continue;
  201 + }
  202 +
  203 + // user may override the on_player_metadata,
  204 + // so set the data before invoke it.
  205 + player.metadata = metadata;
  206 +
  207 + return player.on_player_metadata(metadata);
  208 + }
  209 +
  210 + throw new Error("player not found. id=" + id);
  211 + }
141 </script> 212 </script>
142 </head> 213 </head>
143 <body> 214 <body>
@@ -176,6 +247,15 @@ @@ -176,6 +247,15 @@
176 <div class="modal-body" id="player"> 247 <div class="modal-body" id="player">
177 </div> 248 </div>
178 <div class="modal-footer"> 249 <div class="modal-footer">
  250 + <div class="btn-group dropup">
  251 + <button class="btn dropdown-toggle" data-toggle="dropdown">宽高比 <span class="caret"></span></button>
  252 + <ul class="dropdown-menu">
  253 + <li><a id="btn_dar_original" href="#">视频原始比例</a></li>
  254 + <li><a id="btn_dar_21_9" href="#">宽屏影院(21:9)</a></li>
  255 + <li><a id="btn_dar_16_9" href="#">宽屏电影(16:9)</a></li>
  256 + <li><a id="btn_dar_4_3" href="#">窄屏(4:3)</a></li>
  257 + </ul>
  258 + </div>
179 <button id="btn_pause" class="btn">暂停</button> 259 <button id="btn_pause" class="btn">暂停</button>
180 <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">关闭</button> 260 <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">关闭</button>
181 </div> 261 </div>
@@ -15,14 +15,23 @@ package @@ -15,14 +15,23 @@ package
15 15
16 public class srs_player extends Sprite 16 public class srs_player extends Sprite
17 { 17 {
  18 + // user set id.
18 private var id:String = null; 19 private var id:String = null;
  20 + // user set callback
19 private var on_player_ready:String = null; 21 private var on_player_ready:String = null;
  22 + private var on_player_metadata:String = null;
20 23
  24 + // play param url.
21 private var url:String = null; 25 private var url:String = null;
  26 + // play param, user set width
  27 + private var w:int = 0;
  28 + // play param, user set height.
  29 + private var h:int = 0;
22 30
23 private var conn:NetConnection = null; 31 private var conn:NetConnection = null;
24 private var stream:NetStream = null; 32 private var stream:NetStream = null;
25 private var video:Video = null; 33 private var video:Video = null;
  34 + private var metadata:Object = {};
26 35
27 public function srs_player() 36 public function srs_player()
28 { 37 {
@@ -51,6 +60,7 @@ package @@ -51,6 +60,7 @@ package
51 60
52 this.id = flashvars.id; 61 this.id = flashvars.id;
53 this.on_player_ready = flashvars.on_player_ready; 62 this.on_player_ready = flashvars.on_player_ready;
  63 + this.on_player_metadata = flashvars.on_player_metadata;
54 64
55 flash.utils.setTimeout(this.onJsReady, 0); 65 flash.utils.setTimeout(this.onJsReady, 0);
56 } 66 }
@@ -66,6 +76,7 @@ package @@ -66,6 +76,7 @@ package
66 flash.external.ExternalInterface.addCallback("__stop", this.js_call_stop); 76 flash.external.ExternalInterface.addCallback("__stop", this.js_call_stop);
67 flash.external.ExternalInterface.addCallback("__pause", this.js_call_pause); 77 flash.external.ExternalInterface.addCallback("__pause", this.js_call_pause);
68 flash.external.ExternalInterface.addCallback("__resume", this.js_call_resume); 78 flash.external.ExternalInterface.addCallback("__resume", this.js_call_resume);
  79 + flash.external.ExternalInterface.addCallback("__dar", this.js_call_dar);
69 80
70 var code:int = flash.external.ExternalInterface.call(this.on_player_ready, this.id); 81 var code:int = flash.external.ExternalInterface.call(this.on_player_ready, this.id);
71 if (code != 0) { 82 if (code != 0) {
@@ -87,6 +98,37 @@ package @@ -87,6 +98,37 @@ package
87 return 0; 98 return 0;
88 } 99 }
89 100
  101 + /**
  102 + * to set the DAR, for example, DAR=16:9
  103 + * @param num, for example, 9.
  104 + * @param den, for example, 16.
  105 + */
  106 + public function js_call_dar(num:int, den:int):int {
  107 + if (this.video && num > 0 && den > 0 && this.video.width > 0) {
  108 + // set DAR.
  109 + if (num < den) {
  110 + // calc the height by DAR
  111 + var _height:int = this.video.width * num / den;
  112 +
  113 + // height overflow, calc the width by DAR
  114 + if (_height > this.h) {
  115 + var _width:int = this.video.height * den / num;
  116 +
  117 + this.video.width = _width;
  118 + this.video.height = this.h;
  119 + } else {
  120 + this.video.width = this.w;
  121 + this.video.height = _height;
  122 + }
  123 + }
  124 +
  125 + // align center.
  126 + this.video.y = (this.h - this.video.height) / 2;
  127 + this.video.x = (this.w - this.video.width) / 2;
  128 + }
  129 + return 0;
  130 + }
  131 +
90 public function js_call_stop():int { 132 public function js_call_stop():int {
91 if (this.stream) { 133 if (this.stream) {
92 this.stream.close(); 134 this.stream.close();
@@ -106,7 +148,14 @@ package @@ -106,7 +148,14 @@ package
106 148
107 public function js_call_play(url:String, _width:int, _height:int, _buffer_time:Number):int { 149 public function js_call_play(url:String, _width:int, _height:int, _buffer_time:Number):int {
108 this.url = url; 150 this.url = url;
109 - trace("start to play url: " + this.url); 151 + this.w = _width;
  152 + this.h = _height;
  153 + trace("start to play url: " + this.url + ", w=" + this.w + ", h=" + this.h);
  154 +
  155 + // draw black bg.
  156 + this.graphics.beginFill(0x00, 1.0);
  157 + this.graphics.drawRect(0, 0, this.w, this.h);
  158 + this.graphics.endFill();
110 159
111 js_call_stop(); 160 js_call_stop();
112 161
@@ -122,18 +171,13 @@ package @@ -122,18 +171,13 @@ package
122 stream = new NetStream(conn); 171 stream = new NetStream(conn);
123 stream.bufferTime = _buffer_time; 172 stream.bufferTime = _buffer_time;
124 stream.client = {}; 173 stream.client = {};
125 - stream.client.onMetaData = function(metadata:Object):void {  
126 - var customItems:Array = [new ContextMenuItem("SrsPlayer")];  
127 - if (metadata.hasOwnProperty("server")) {  
128 - customItems.push(new ContextMenuItem("Server: " + metadata.server));  
129 - }  
130 - if (metadata.hasOwnProperty("contributor")) {  
131 - customItems.push(new ContextMenuItem("Contributor: " + metadata.contributor));  
132 - }  
133 - contextMenu.customItems = customItems;  
134 - }; 174 + stream.client.onMetaData = on_metadata;
135 stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { 175 stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void {
136 trace ("NetStream: code=" + evt.info.code); 176 trace ("NetStream: code=" + evt.info.code);
  177 +
  178 + if (evt.info.code == "NetStream.Video.DimensionChange") {
  179 + on_metadata(metadata);
  180 + }
137 }); 181 });
138 stream.play(url.substr(url.lastIndexOf("/"))); 182 stream.play(url.substr(url.lastIndexOf("/")));
139 183
@@ -148,5 +192,53 @@ package @@ -148,5 +192,53 @@ package
148 192
149 return 0; 193 return 0;
150 } 194 }
  195 +
  196 + private function on_metadata(metadata:Object):void {
  197 + this.metadata = metadata;
  198 +
  199 + // for context menu
  200 + var customItems:Array = [new ContextMenuItem("SrsPlayer")];
  201 + if (metadata.hasOwnProperty("server")) {
  202 + customItems.push(new ContextMenuItem("Server: " + metadata.server));
  203 + }
  204 + if (metadata.hasOwnProperty("contributor")) {
  205 + customItems.push(new ContextMenuItem("Contributor: " + metadata.contributor));
  206 + }
  207 + contextMenu.customItems = customItems;
  208 +
  209 + // for js.
  210 + var obj:Object = {
  211 + width: video.width,
  212 + height: video.height,
  213 + server: 'srs',
  214 + contributor: 'winlin'
  215 + };
  216 +
  217 + if (metadata.hasOwnProperty("width")) {
  218 + obj.width = metadata.width;
  219 + }
  220 + if (metadata.hasOwnProperty("height")) {
  221 + obj.height = metadata.height;
  222 + }
  223 +
  224 + if (video.videoWidth > 0) {
  225 + obj.width = video.videoWidth;
  226 + }
  227 + if (video.videoHeight > 0) {
  228 + obj.height = video.videoHeight;
  229 + }
  230 +
  231 + if (metadata.hasOwnProperty("server")) {
  232 + obj.server = metadata.server;
  233 + }
  234 + if (metadata.hasOwnProperty("contributor")) {
  235 + obj.contributor = metadata.contributor;
  236 + }
  237 +
  238 + var code:int = flash.external.ExternalInterface.call(on_player_metadata, id, obj);
  239 + if (code != 0) {
  240 + throw new Error("callback on_player_metadata failed. code=" + code);
  241 + }
  242 + }
151 } 243 }
152 } 244 }