winlin

change ui version to 1.15, fix the publiser bug, support chrome/firefox/safari/ie browsers.

@@ -7,18 +7,31 @@ @@ -7,18 +7,31 @@
7 <span id="txt_log_msg">日志内容</span> 7 <span id="txt_log_msg">日志内容</span>
8 </div> 8 </div>
9 */ 9 */
  10 +var srs_log_disabled = false;
10 function info(desc) { 11 function info(desc) {
  12 + if (srs_log_disabled) {
  13 + return;
  14 + }
  15 +
11 $("#txt_log").addClass("alert-info").removeClass("alert-error").removeClass("alert-warn"); 16 $("#txt_log").addClass("alert-info").removeClass("alert-error").removeClass("alert-warn");
12 $("#txt_log_title").text("Info:"); 17 $("#txt_log_title").text("Info:");
13 - $("#txt_log_msg").text(desc); 18 + $("#txt_log_msg").html(desc);
14 } 19 }
15 function warn(code, desc) { 20 function warn(code, desc) {
  21 + if (srs_log_disabled) {
  22 + return;
  23 + }
  24 +
16 $("#txt_log").removeClass("alert-info").removeClass("alert-error").addClass("alert-warn"); 25 $("#txt_log").removeClass("alert-info").removeClass("alert-error").addClass("alert-warn");
17 $("#txt_log_title").text("Warn:"); 26 $("#txt_log_title").text("Warn:");
18 - $("#txt_log_msg").text("code: " + code + ", " + desc); 27 + $("#txt_log_msg").html("code: " + code + ", " + desc);
19 } 28 }
20 function error(code, desc) { 29 function error(code, desc) {
  30 + if (srs_log_disabled) {
  31 + return;
  32 + }
  33 +
21 $("#txt_log").removeClass("alert-info").addClass("alert-error").removeClass("alert-warn"); 34 $("#txt_log").removeClass("alert-info").addClass("alert-error").removeClass("alert-warn");
22 $("#txt_log_title").text("Error:"); 35 $("#txt_log_title").text("Error:");
23 - $("#txt_log_msg").text("code: " + code + ", " + desc); 36 + $("#txt_log_msg").html("code: " + code + ", " + desc);
24 } 37 }
@@ -10,7 +10,7 @@ function srs_get_player_width() { return srs_get_player_modal() - 30; } @@ -10,7 +10,7 @@ function srs_get_player_width() { return srs_get_player_modal() - 30; }
10 function srs_get_player_height() { return srs_get_player_width() * 9 / 19; } 10 function srs_get_player_height() { return srs_get_player_width() * 9 / 19; }
11 11
12 // to query the swf anti cache. 12 // to query the swf anti cache.
13 -function srs_get_version_code() { return "1.13"; } 13 +function srs_get_version_code() { return "1.15"; }
14 // get the default vhost for players. 14 // get the default vhost for players.
15 function srs_get_player_vhost() { return "players"; } 15 function srs_get_player_vhost() { return "players"; }
16 // the api server port, for chat room. 16 // the api server port, for chat room.
@@ -139,6 +139,21 @@ function srs_init_publish(rtmp_url) { @@ -139,6 +139,21 @@ function srs_init_publish(rtmp_url) {
139 } 139 }
140 } 140 }
141 141
  142 +// check whether can republish
  143 +function srs_can_republish() {
  144 + var browser = get_browser_agents();
  145 +
  146 + if (browser.Chrome || browser.Firefox) {
  147 + return true;
  148 + }
  149 +
  150 + if (browser.MSIE || browser.QQBrowser) {
  151 + return false;
  152 + }
  153 +
  154 + return false;
  155 +}
  156 +
142 // without default values set. 157 // without default values set.
143 function srs_initialize_codec_page( 158 function srs_initialize_codec_page(
144 cameras, microphones, 159 cameras, microphones,
@@ -54,6 +54,8 @@ SrsPublisher.prototype.start = function() { @@ -54,6 +54,8 @@ SrsPublisher.prototype.start = function() {
54 // embed the flash. 54 // embed the flash.
55 var flashvars = {}; 55 var flashvars = {};
56 flashvars.id = this.id; 56 flashvars.id = this.id;
  57 + flashvars.width = this.width;
  58 + flashvars.height = this.height;
57 flashvars.on_publisher_ready = "__srs_on_publisher_ready"; 59 flashvars.on_publisher_ready = "__srs_on_publisher_ready";
58 flashvars.on_publisher_error = "__srs_on_publisher_error"; 60 flashvars.on_publisher_error = "__srs_on_publisher_error";
59 flashvars.on_publisher_warn = "__srs_on_publisher_warn"; 61 flashvars.on_publisher_warn = "__srs_on_publisher_warn";
@@ -81,3 +81,54 @@ function srs_parse_rtmp_url(rtmp_url) { @@ -81,3 +81,54 @@ function srs_parse_rtmp_url(rtmp_url) {
81 81
82 return ret; 82 return ret;
83 } 83 }
  84 +
  85 +/**
  86 +* get the agent.
  87 +* @return an object specifies some browser.
  88 +* for example, get_browser_agents().MSIE
  89 +*/
  90 +function get_browser_agents() {
  91 + var agent = navigator.userAgent;
  92 +
  93 + /**
  94 + WindowsPC platform, Win7:
  95 + chrome 31.0.1650.63:
  96 + Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36
  97 + (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
  98 + firefox 23.0.1:
  99 + Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101
  100 + Firefox/23.0
  101 + safari 5.1.7(7534.57.2):
  102 + Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2
  103 + (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2
  104 + opera 15.0.1147.153:
  105 + Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36
  106 + (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
  107 + OPR/15.0.1147.153
  108 + 360 6.2.1.272:
  109 + Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64;
  110 + Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729;
  111 + .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C;
  112 + .NET4.0E)
  113 + IE 10.0.9200.16750(update: 10.0.12):
  114 + Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64;
  115 + Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729;
  116 + .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C;
  117 + .NET4.0E)
  118 + */
  119 +
  120 + return {
  121 + // platform
  122 + Android: agent.indexOf("Android") != -1,
  123 + Windows: agent.indexOf("Windows") != -1,
  124 + iPhone: agent.indexOf("iPhone") != -1,
  125 + // Windows Browsers
  126 + Chrome: agent.indexOf("Chrome") != -1,
  127 + Firefox: agent.indexOf("Firefox") != -1,
  128 + QQBrowser: agent.indexOf("QQBrowser") != -1,
  129 + MSIE: agent.indexOf("MSIE") != -1,
  130 + // Android Browsers
  131 + Opera: agent.indexOf("Presto") != -1,
  132 + MQQBrowser: agent.indexOf("MQQBrowser") != -1
  133 + };
  134 +}
@@ -27,18 +27,23 @@ @@ -27,18 +27,23 @@
27 var previous_chats = []; 27 var previous_chats = [];
28 var no_play = false; 28 var no_play = false;
29 29
  30 + var query = parse_query_string();
30 $(function(){ 31 $(function(){
31 // get the vhost and port to set the default url. 32 // get the vhost and port to set the default url.
32 // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo 33 // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo
33 // url set to: rtmp://demo:1935/live/livestream 34 // url set to: rtmp://demo:1935/live/livestream
34 srs_init_publish("#txt_url"); 35 srs_init_publish("#txt_url");
35 36
  37 + if (query.agent == "true") {
  38 + document.write(navigator.userAgent);
  39 + return;
  40 + }
  41 +
36 $("#realtime_player_url").tooltip({ 42 $("#realtime_player_url").tooltip({
37 title: "右键复制RTMP地址" 43 title: "右键复制RTMP地址"
38 }); 44 });
39 45
40 // if no play specified, donot show the player, for debug the publisher. 46 // if no play specified, donot show the player, for debug the publisher.
41 - var query = parse_query_string();  
42 if (query.no_play == "true") { 47 if (query.no_play == "true") {
43 no_play = true; 48 no_play = true;
44 } 49 }
@@ -65,6 +70,10 @@ @@ -65,6 +70,10 @@
65 ); 70 );
66 }; 71 };
67 srs_publisher.on_publisher_error = function(code, desc) { 72 srs_publisher.on_publisher_error = function(code, desc) {
  73 + if (!on_publish_stop()) {
  74 + return;
  75 + }
  76 +
68 error(code, desc + "请重试。"); 77 error(code, desc + "请重试。");
69 }; 78 };
70 srs_publisher.on_publisher_warn = function(code, desc) { 79 srs_publisher.on_publisher_warn = function(code, desc) {
@@ -107,6 +116,18 @@ @@ -107,6 +116,18 @@
107 refresh(); 116 refresh();
108 }); 117 });
109 118
  119 + function on_publish_stop() {
  120 + if (!srs_can_republish()) {
  121 + $("#btn_join").attr("disabled", true);
  122 + error(0, "您使用的浏览器很弱,请关闭页面后重新打开页面(刷新也不管用)。<br/>推荐使用Chrome/Firefox/Safari/Opera浏览器,支持重试");
  123 +
  124 + srs_log_disabled = true;
  125 + return false;
  126 + }
  127 +
  128 + return true;
  129 + }
  130 +
110 function update_play_url() { 131 function update_play_url() {
111 var url = $("#txt_url").val(); 132 var url = $("#txt_url").val();
112 133
@@ -432,6 +453,10 @@ @@ -432,6 +453,10 @@
432 data : "", 453 data : "",
433 dataType : "json", 454 dataType : "json",
434 complete : function() { 455 complete : function() {
  456 + if (!on_publish_stop()) {
  457 + return;
  458 + }
  459 +
435 $("#btn_join").attr("disabled", false); 460 $("#btn_join").attr("disabled", false);
436 if (complete_pfn) { 461 if (complete_pfn) {
437 complete_pfn(); 462 complete_pfn();
@@ -23,12 +23,18 @@ @@ -23,12 +23,18 @@
23 var remote_player = null; 23 var remote_player = null;
24 var realtime_player = null; 24 var realtime_player = null;
25 25
  26 + var query = parse_query_string();
26 $(function(){ 27 $(function(){
27 // get the vhost and port to set the default url. 28 // get the vhost and port to set the default url.
28 // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo 29 // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo
29 // url set to: rtmp://demo:1935/live/livestream 30 // url set to: rtmp://demo:1935/live/livestream
30 srs_init("#txt_url", null, null); 31 srs_init("#txt_url", null, null);
31 32
  33 + if (query.agent == "true") {
  34 + document.write(navigator.userAgent);
  35 + return;
  36 + }
  37 +
32 $("#btn_video_settings").click(function(){ 38 $("#btn_video_settings").click(function(){
33 $("#video_modal").modal({show:true}); 39 $("#video_modal").modal({show:true});
34 }); 40 });
@@ -65,6 +71,9 @@ @@ -65,6 +71,9 @@
65 ); 71 );
66 }; 72 };
67 srs_publisher.on_publisher_error = function(code, desc) { 73 srs_publisher.on_publisher_error = function(code, desc) {
  74 + if (!on_publish_stop()) {
  75 + return;
  76 + }
68 error(code, desc + "请重试。"); 77 error(code, desc + "请重试。");
69 }; 78 };
70 srs_publisher.on_publisher_warn = function(code, desc) { 79 srs_publisher.on_publisher_warn = function(code, desc) {
@@ -75,7 +84,6 @@ @@ -75,7 +84,6 @@
75 update_play_url(); 84 update_play_url();
76 85
77 // if no play specified, donot show the player, for debug the publisher. 86 // if no play specified, donot show the player, for debug the publisher.
78 - var query = parse_query_string();  
79 if (query.no_play != "true") { 87 if (query.no_play != "true") {
80 // start the normal player with HLS supported. 88 // start the normal player with HLS supported.
81 remote_player = new SrsPlayer("remote_player", 430, 185); 89 remote_player = new SrsPlayer("remote_player", 430, 185);
@@ -101,6 +109,18 @@ @@ -101,6 +109,18 @@
101 } 109 }
102 }); 110 });
103 111
  112 + function on_publish_stop() {
  113 + if (!srs_can_republish()) {
  114 + $("#btn_join").attr("disabled", true);
  115 + error(0, "您使用的浏览器很弱,请关闭页面后重新打开页面(刷新也不管用)。<br/>推荐使用Chrome/Firefox/Safari/Opera浏览器,支持重试");
  116 +
  117 + srs_log_disabled = true;
  118 + return false;
  119 + }
  120 +
  121 + return true;
  122 + }
  123 +
104 /** 124 /**
105 * we generate the transcoded stream url for flash publish donot support HLS 125 * we generate the transcoded stream url for flash publish donot support HLS
106 * which requires aac, so the publish vhost maybe players for example, we 126 * which requires aac, so the publish vhost maybe players for example, we
@@ -112,7 +132,6 @@ @@ -112,7 +132,6 @@
112 function update_play_url() { 132 function update_play_url() {
113 var url = $("#txt_url").val(); 133 var url = $("#txt_url").val();
114 var ret = srs_parse_rtmp_url(url); 134 var ret = srs_parse_rtmp_url(url);
115 - var query = parse_query_string();  
116 135
117 var remote_url = "rtmp://" + ret.server + ":" + ret.port + "/" + ret.app + "...vhost..." + srs_get_player_publish_vhost(ret.vhost) + "/" + ret.stream; 136 var remote_url = "rtmp://" + ret.server + ":" + ret.port + "/" + ret.app + "...vhost..." + srs_get_player_publish_vhost(ret.vhost) + "/" + ret.stream;
118 $("#realtime_player_url").attr("href", url).attr("target", "_blank"); 137 $("#realtime_player_url").attr("href", url).attr("target", "_blank");
@@ -147,6 +166,10 @@ @@ -147,6 +166,10 @@
147 //$("#remote_player_url").attr("href", "#").attr("target", "_self"); 166 //$("#remote_player_url").attr("href", "#").attr("target", "_self");
148 //$("#txt_play_hls").text("HLS-m3u8(请发布视频)").attr("href", "#").attr("target", "_self"); 167 //$("#txt_play_hls").text("HLS-m3u8(请发布视频)").attr("href", "#").attr("target", "_self");
149 //$("#txt_play_jwplayer").text("HLS-JWPlayer(请发布视频)").attr("href", "#").attr("target", "_self"); 168 //$("#txt_play_jwplayer").text("HLS-JWPlayer(请发布视频)").attr("href", "#").attr("target", "_self");
  169 +
  170 + if (!on_publish_stop()) {
  171 + return;
  172 + }
150 return; 173 return;
151 } 174 }
152 175
@@ -16,6 +16,8 @@ package @@ -16,6 +16,8 @@ package
16 import flash.media.Video; 16 import flash.media.Video;
17 import flash.net.NetConnection; 17 import flash.net.NetConnection;
18 import flash.net.NetStream; 18 import flash.net.NetStream;
  19 + import flash.system.Security;
  20 + import flash.system.SecurityPanel;
19 import flash.ui.ContextMenu; 21 import flash.ui.ContextMenu;
20 import flash.ui.ContextMenuItem; 22 import flash.ui.ContextMenuItem;
21 import flash.utils.setTimeout; 23 import flash.utils.setTimeout;
@@ -84,6 +86,18 @@ package @@ -84,6 +86,18 @@ package
84 this.js_on_publisher_error = flashvars.on_publisher_error; 86 this.js_on_publisher_error = flashvars.on_publisher_error;
85 this.js_on_publisher_warn = flashvars.on_publisher_warn; 87 this.js_on_publisher_warn = flashvars.on_publisher_warn;
86 88
  89 + // initialized size.
  90 + this.user_w = flashvars.width;
  91 + this.user_h = flashvars.height;
  92 +
  93 + // try to get the camera, if muted, alert the security and requires user to open it.
  94 + var c:Camera = Camera.getCamera();
  95 + if (c.muted) {
  96 + Security.showSettings(SecurityPanel.PRIVACY);
  97 + }
  98 +
  99 + __show_local_camera(c);
  100 +
87 flash.utils.setTimeout(this.system_on_js_ready, 0); 101 flash.utils.setTimeout(this.system_on_js_ready, 0);
88 } 102 }
89 103
@@ -221,17 +235,7 @@ package @@ -221,17 +235,7 @@ package
221 var streamName:String = url.substr(url.lastIndexOf("/")); 235 var streamName:String = url.substr(url.lastIndexOf("/"));
222 media_stream.publish(streamName); 236 media_stream.publish(streamName);
223 237
224 - media_video = new Video();  
225 - media_video.width = _width;  
226 - media_video.height = _height;  
227 - media_video.attachCamera(media_camera);  
228 - media_video.smoothing = true;  
229 - addChild(media_video);  
230 -  
231 - //__draw_black_background(_width, _height);  
232 -  
233 - // lowest layer, for mask to cover it.  
234 - setChildIndex(media_video, 0); 238 + __show_local_camera(media_camera);
235 }); 239 });
236 240
237 var tcUrl:String = this.user_url.substr(0, this.user_url.lastIndexOf("/")); 241 var tcUrl:String = this.user_url.substr(0, this.user_url.lastIndexOf("/"));
@@ -242,11 +246,6 @@ package @@ -242,11 +246,6 @@ package
242 * function for js to call: to stop the stream. ignore if not publish. 246 * function for js to call: to stop the stream. ignore if not publish.
243 */ 247 */
244 private function js_call_stop():void { 248 private function js_call_stop():void {
245 - if (this.media_video) {  
246 - this.media_video.attachCamera(null);  
247 - this.removeChild(this.media_video);  
248 - this.media_video = null;  
249 - }  
250 if (this.media_stream) { 249 if (this.media_stream) {
251 this.media_stream.attachAudio(null); 250 this.media_stream.attachAudio(null);
252 this.media_stream.attachCamera(null); 251 this.media_stream.attachCamera(null);
@@ -363,5 +362,52 @@ package @@ -363,5 +362,52 @@ package
363 // quality=1 is lowest quality, 100 is highest quality. 362 // quality=1 is lowest quality, 100 is highest quality.
364 c.setQuality(cameraBitrate / 8.0 * 1000, cameraQuality); 363 c.setQuality(cameraBitrate / 8.0 * 1000, cameraQuality);
365 } 364 }
  365 +
  366 + private function __show_local_camera(c:Camera):void {
  367 + if (this.media_video) {
  368 + this.media_video.attachCamera(null);
  369 + this.removeChild(this.media_video);
  370 + this.media_video = null;
  371 + }
  372 +
  373 + // show local camera
  374 + media_video = new Video();
  375 + media_video.attachCamera(c);
  376 + media_video.smoothing = true;
  377 + addChild(media_video);
  378 +
  379 + // rescale the local camera.
  380 + var cw:Number = user_h * c.width / c.height;
  381 + if (cw > user_w) {
  382 + var ch:Number = user_w * c.height / c.width;
  383 + media_video.width = user_w;
  384 + media_video.height = ch;
  385 + } else {
  386 + media_video.width = cw;
  387 + media_video.height = user_h;
  388 + }
  389 + media_video.x = (user_w - media_video.width) / 2;
  390 + media_video.y = (user_h - media_video.height) / 2;
  391 +
  392 + __draw_black_background(user_w, user_h);
  393 +
  394 + // lowest layer, for mask to cover it.
  395 + setChildIndex(media_video, 0);
  396 + }
  397 +
  398 + /**
  399 + * draw black background and draw the fullscreen mask.
  400 + */
  401 + private function __draw_black_background(_width:int, _height:int):void {
  402 + // draw black bg.
  403 + this.graphics.beginFill(0x00, 1.0);
  404 + this.graphics.drawRect(0, 0, _width, _height);
  405 + this.graphics.endFill();
  406 +
  407 + // draw the fs mask.
  408 + //this.control_fs_mask.graphics.beginFill(0xff0000, 0);
  409 + //this.control_fs_mask.graphics.drawRect(0, 0, _width, _height);
  410 + //this.control_fs_mask.graphics.endFill();
  411 + }
366 } 412 }
367 } 413 }