winlin

update the publisher, to auto prompt the dialog to get the publisher.

... ... @@ -401,13 +401,18 @@ function SrsPublisher(container, width, height) {
this.code = 0;
// error code defines.
this.error_device_muted = 100;
this.errors = {
"100": "无法获取指定的摄像头", //error_camera_get
"101": "无法获取指定的麦克风", //error_microphone_get
"102": "摄像头为禁用状态,推流时请允许flash访问摄像头", //error_camera_muted
};
}
/**
* user can set some callback, then start the publisher.
* callbacks:
* on_publisher_ready(cameras, microphones):int, when srs publisher ready, user can publish.
* on_publisher_error(code):int, when srs publisher error, callback this method.
* on_publisher_error(code, desc):int, when srs publisher error, callback this method.
* on_publisher_warn(code, desc):int, when srs publisher warn, callback this method.
*/
SrsPublisher.prototype.start = function() {
// embed the flash.
... ... @@ -415,6 +420,7 @@ SrsPublisher.prototype.start = function() {
flashvars.id = this.id;
flashvars.on_publisher_ready = "__srs_on_publisher_ready";
flashvars.on_publisher_error = "__srs_on_publisher_error";
flashvars.on_publisher_warn = "__srs_on_publisher_warn";
var params = {};
params.wmode = "opaque";
... ... @@ -464,9 +470,13 @@ SrsPublisher.prototype.on_publisher_ready = function(cameras, microphones) {
/**
* when publisher error.
* @code the error code.
* @desc the error desc message.
*/
SrsPublisher.prototype.on_publisher_error = function(code) {
throw new Error("publisher error. code=" + code);
SrsPublisher.prototype.on_publisher_error = function(code, desc) {
throw new Error("publisher error. code=" + code + ", desc=" + desc);
}
SrsPublisher.prototype.on_publisher_warn = function(code, desc) {
throw new Error("publisher warn. code=" + code + ", desc=" + desc);
}
function __srs_find_publisher(id) {
for (var i = 0; i < SrsPublisher.__publishers.length; i++) {
... ... @@ -494,6 +504,13 @@ function __srs_on_publisher_error(id, code) {
publisher.code = code;
publisher.on_publisher_error(code);
publisher.on_publisher_error(code, publisher.errors[""+code]);
}
function __srs_on_publisher_warn(id, code) {
var publisher = __srs_find_publisher(id);
publisher.code = code;
publisher.on_publisher_warn(code, publisher.errors[""+code]);
}
... ...
... ... @@ -115,30 +115,33 @@
}
$("#sl_bitrate option[value='350']").attr("selected", true);
};
srs_publisher.on_publisher_error = function(code) {
if (code == srs_publisher.error_device_muted) {
error(code, "摄像头和麦克风被禁用,请右键flash播放器启用。");
} else {
error(code, "未知系统错误");
}
srs_publisher.on_publisher_error = function(code, desc) {
error(code, desc);
};
srs_publisher.start();
// start the normal player with HLS supported.
remote_player = new SrsPlayer("remote_player", 430, 185);
remote_player.on_player_ready = function() {
remote_player.set_bt(0.8);
remote_player.set_fs("screen", 100);
srs_publisher.on_publisher_warn = function(code, desc) {
warn(code, desc);
};
remote_player.start();
srs_publisher.start();
// start the realtime player.
realtime_player = new SrsPlayer("realtime_player", 430, 185);
realtime_player.on_player_ready = function() {
realtime_player.set_bt(0.8);
realtime_player.set_fs("screen", 100);
};
realtime_player.start();
// if no play specified, donot show the player, for debug the publisher.
var query = parse_query_string();
if (query.no_play != "true") {
// start the normal player with HLS supported.
remote_player = new SrsPlayer("remote_player", 430, 185);
remote_player.on_player_ready = function() {
remote_player.set_bt(0.8);
remote_player.set_fs("screen", 100);
};
remote_player.start();
// start the realtime player.
realtime_player = new SrsPlayer("realtime_player", 430, 185);
realtime_player.on_player_ready = function() {
realtime_player.set_bt(0.8);
realtime_player.set_fs("screen", 100);
};
realtime_player.start();
}
});
/**
... ... @@ -209,28 +212,37 @@
info("开始推流到服务器");
srs_publisher.publish(url, vcodec, acodec);
// directly play the url for the realtime player.
realtime_player.stop();
realtime_player.play(url);
if (realtime_player) {
// directly play the url for the realtime player.
realtime_player.stop();
realtime_player.play(url);
}
// the normal player should play the transcoded stream in another vhost.
// for example, publish stream to vhost players,
// the realtime player play the vhost players, which may donot support HLS,
// the normal player play the vhost players_pub, which transcoded to h264/aac with HLS.
var ret = srs_parse_rtmp_url(url);
var pub_url = "rtmp://" + ret.server + ":" + ret.port + "/" + ret.app;
pub_url += "?vhost=" + srs_get_player_publish_vhost(ret.vhost) + "/" + ret.stream;
remote_player.stop();
remote_player.play(pub_url);
if (remote_player) {
// the normal player should play the transcoded stream in another vhost.
// for example, publish stream to vhost players,
// the realtime player play the vhost players, which may donot support HLS,
// the normal player play the vhost players_pub, which transcoded to h264/aac with HLS.
var ret = srs_parse_rtmp_url(url);
var pub_url = "rtmp://" + ret.server + ":" + ret.port + "/" + ret.app;
pub_url += "?vhost=" + srs_get_player_publish_vhost(ret.vhost) + "/" + ret.stream;
remote_player.stop();
remote_player.play(pub_url);
}
}
function info(desc) {
$("#txt_log").removeClass("alert-error").addClass("alert-info");
$("#txt_log").addClass("alert-info").removeClass("alert-error").removeClass("alert-warn");
$("#txt_log_title").text("Info:");
$("#txt_log_msg").text(desc);
}
function warn(code, desc) {
$("#txt_log").removeClass("alert-info").removeClass("alert-error").addClass("alert-warn");
$("#txt_log_title").text("Warn:");
$("#txt_log_msg").text("code: " + code + ", " + desc);
}
function error(code, desc) {
$("#txt_log").removeClass("alert-info").addClass("alert-error");
$("#txt_log").removeClass("alert-info").addClass("alert-error").removeClass("alert-warn");
$("#txt_log_title").text("Error:");
$("#txt_log_msg").text("code: " + code + ", " + desc);
}
... ... @@ -258,7 +270,7 @@
<div class="alert alert-info fade in" id="txt_log">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong><span id="txt_log_title">Usage:</span></strong>
<span id="txt_log_msg">允许Flash访问摄像头,设置编码参数,点“发布视频”即可推流</span>
<span id="txt_log_msg">设置编码参数,点“发布视频”,允许Flash访问摄像头即可推流</span>
</div>
<div class="control-group">
<div class="form-inline">
... ...
... ... @@ -24,6 +24,7 @@ package
// user set callback
private var js_on_publisher_ready:String = null;
private var js_on_publisher_error:String = null;
private var js_on_publisher_warn:String = null;
// publish param url.
private var user_url:String = null;
... ... @@ -41,7 +42,9 @@ package
private var media_microphone:Microphone = null;
// error code.
private const error_device_muted:int = 100;
private const error_camera_get:int = 100;
private const error_microphone_get:int = 101;
private const error_camera_muted:int = 102;
public function srs_publisher()
{
... ... @@ -74,6 +77,7 @@ package
this.js_id = flashvars.id;
this.js_on_publisher_ready = flashvars.on_publisher_ready;
this.js_on_publisher_error = flashvars.on_publisher_error;
this.js_on_publisher_warn = flashvars.on_publisher_warn;
flash.utils.setTimeout(this.system_on_js_ready, 0);
}
... ... @@ -106,6 +110,10 @@ package
trace("system error, code=" + code + ", error=" + desc);
flash.external.ExternalInterface.call(this.js_on_publisher_error, this.js_id, code);
}
private function system_warn(code:int, desc:String):void {
trace("system warn, code=" + code + ", error=" + desc);
flash.external.ExternalInterface.call(this.js_on_publisher_warn, this.js_id, code);
}
/**
* publish stream to server.
... ... @@ -129,27 +137,22 @@ package
// microphone and camera
var m:Microphone = Microphone.getMicrophone(acodec.device_code);
if(m == null){
trace("failed to open microphone " + acodec.device_code + "(" + acodec.device_name + ")");
}
if(m.muted){
trace("Access Denied, microphone " + acodec.device_code + "(" + acodec.device_name + ") is muted");
m = null;
this.system_error(this.error_microphone_get, "failed to open microphone " + acodec.device_code + "(" + acodec.device_name + ")");
return;
}
// ignore muted, for flash will require user to access it.
// Remark: the name is the index!
var c:Camera = Camera.getCamera(vcodec.device_code);
if(c == null){
trace("failed to open camera " + vcodec.device_code + "(" + vcodec.device_name + ")");
}
if(c.muted){
trace("Access Denied, camera " + vcodec.device_code + "(" + vcodec.device_name + ") is muted");
c = null;
}
if (m == null && c == null) {
system_error(error_device_muted, "failed to publish, for neither camera or microphone is ok.");
this.system_error(this.error_camera_get, "failed to open camera " + vcodec.device_code + "(" + vcodec.device_name + ")");
return;
}
// ignore muted, for flash will require user to access it.
// but we still warn user.
if(c && c.muted){
this.system_warn(this.error_camera_muted, "Access Denied, camera " + vcodec.device_code + "(" + vcodec.device_name + ") is muted");
}
this.media_camera = c;
this.media_microphone = m;
... ...