You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
srs/trunk/research/players/srs_gb28181.html

1246 lines
54 KiB
HTML

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE html>
<html>
<head>
<title>SRS</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
<style>
body{
padding-top: 55px;
}
#my_modal_footer {
margin-top: -20px;
padding-top: 3px;
}
#main_modal {
margin-top: -60px;
}
#rtc_player_modal {
margin-top: -60px;
}
.div_play_time {
margin-top: 10px;
}
#pb_buffer_bg {
margin-top: -4px;
margin-bottom: 10px;
}
</style>
</head>
<body>
<img src='https://ossrs.net/gif/v1/sls.gif?site=ossrs.net&path=/player/srsplayer'/>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a id="srs_index" class="brand" href="#">SRS</a>
<div class="nav-collapse collapse">
<ul class="nav">
<li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li>
<li><a id="nav_rtc_player" href="rtc_player.html">RTC播放器</a></li>
<li><a id="nav_rtc_publisher" href="rtc_publisher.html">RTC推流</a></li>
<!--<li><a id="nav_srs_publisher" href="srs_publisher.html">SRS编码器</a></li>-->
<!--<li><a id="nav_srs_chat" href="srs_chat.html">SRS会议</a></li>-->
<!--<li><a id="nav_srs_bwt" href="srs_bwt.html">SRS测网速</a></li>-->
<!--<li><a id="nav_jwplayer6" href="jwplayer6.html">JWPlayer6播放器</a></li>-->
<!--<li><a id="nav_osmf" href="osmf.html">AdobeOSMF播放器</a></li>-->
<!--<li><a id="nav_vlc" href="vlc.html">VLC播放器</a></li>-->
<li class="active" ><a id="nav_gb28181" href="srs_gb28181.html">GB28181</a></li>
<li><a href="https://github.com/ossrs/srs">源码</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="container">
<div name="detect_flash">
<div id="main_flash_alert" class="alert alert-danger fade in hide">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong><p>Usage:</p></strong>
<p>
请点击下面的图标启用Flash
</p>
<p>
若没有见到这个图标Chrome浏览器请打开
<span class="text-info">chrome://settings/content/flash</span> 并修改为"Ask first"。
</p>
</div>
<div id="main_flash_hdr" class="hide">
</div>
</div>
<div class="form-inline">
API地址与端口
<input type="text" id="txt_api_url" class="input-xxlarge">
<p></p>
</div>
<div>
<div class="row">
<div class="span4" id="divSipSessionList">
<span>sip会话(需内部启用sip)</span><label id="lab_sip_session"></label>
<div style="overflow:scroll; height:330px; width:310px">
<ul id="sipSessionList"></ul>
</div>
</div>
<div class="span8">
<button class="btn btn-primary" id="btn_sip_query_session">查询所有会话</button>
<button class="btn btn-primary" id="btn_sip_unregister">unregister</button>
<button class="btn btn-primary" id="btn_sip_invite">invite</button>
<button class="btn btn-primary" id="btn_sip_bye">bye</button>
<button class="btn btn-primary" id="btn_sip_querycatalog">querycatalog</button>
<div id="context2">
当前会话:<a id="sipSessionId"></a>
<div>
<pre id="sipSessionMessage" style="overflow:scroll; height:280px"></pre>
</div>
</div>
</div>
</div>
</div>
<p></p>
<div>
<div class="row">
<div class="span4" id="divMediaChannelList">
<span>GB28181媒体通道</span><label id="lab_gb28181_ch"></label>
<div style="overflow:scroll; height:400px; width:310px">
<ul id="gb28181ChList"></ul>
</div>
</div>
<div class="span8">
<button class="btn btn-primary" id="btn_query_channel">查询所有通道</button>
<button class="btn btn-primary" id="btn_create_channel">创建通道</button>
<button class="btn btn-primary" id="btn_delete_channel">删除通道</button>
<div id="context2">
当前通道:<a id="gb28181ChannelId"></a>
<div>
<textarea class="span6" id="txt_rtmp_url" rows="2"></textarea>
<button class="btn btn-primary" id="btn_play">RTMP播放</button>
</div>
<div>
<textarea class="span6" id="txt_rtc_url" rows="2"></textarea>
<button class="btn btn-primary" id="btn_rtc_play">RTC播放</button>
<div>RTC播放需要后台启用RTC功能才能正常播放
<a href='https://github.com/ossrs/srs/wiki/v4_CN_RTCWiki'>RTC配置参考</a>
</div>
</div>
<div>
<pre id="gb28181ChannelMessage" style="overflow:scroll; height:210px"></pre>
</div>
</div>
</div>
</div>
</div>
<div id="main_content" class="hide">
<div id="link_modal" class="modal hide fade">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3><a href="https://github.com/ossrs/srs">SRS Link Generator</a></h3>
</div>
<div class="modal-body">
<div class="form-horizontal">
<div class="control-group">
<label class="control-label" for="link_server">服务器地址</label>
<div class="controls">
<span id="link_server" class="span4 uneditable-input"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="link_port">服务器端口</label>
<div class="controls">
<span id="link_port" class="span2 uneditable-input"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="link_vhost">RTMP Vhost</label>
<div class="controls">
<span id="link_vhost" class="span4 uneditable-input"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="link_app">RTMP App</label>
<div class="controls">
<span id="link_app" class="span4 uneditable-input"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="link_stream">RTMP Stream</label>
<div class="controls">
<span id="link_stream" class="span4 uneditable-input"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="link_rtmp">RTMP地址</label>
<div class="controls">
<span id="link_rtmp" class="span4 uneditable-input"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="link_url">播放链接地址</label>
<div class="controls">
<div style="margin-top:5px;"><a href="#" id="link_url" target="_blank">请右键拷贝此链接地址.</a></div>
</div>
</div>
</div>
</div>
<div class="modal-footer"></div>
</div>
<div id="main_modal" class="modal hide fade">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3><a href="https://github.com/ossrs/srs">SrsPlayer</a></h3>
</div>
<div class="modal-body">
<div id="player"></div>
<div class="progress progress-striped active" id="pb_buffer_bg">
<div class="bar" style="width: 0%;" id="pb_buffer"></div>
</div>
</div>
<div class="modal-footer" id="my_modal_footer">
<div>
<div class="btn-group dropup">
<button class="btn dropdown-toggle" data-toggle="dropdown">
全屏比例大小<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a id="btn_fs_size_screen_100" href="#">屏幕大小(100%)</a></li>
<li><a id="btn_fs_size_screen_75" href="#">屏幕大小(75%)</a></li>
<li><a id="btn_fs_size_screen_50" href="#">屏幕大小(50%)</a></li>
<li><a id="btn_fs_size_video_100" href="#">视频大小(100%)</a></li>
<li><a id="btn_fs_size_video_75" href="#">视频大小(75%)</a></li>
<li><a id="btn_fs_size_video_50" href="#">视频大小(50%)</a></li>
</ul>
</div>
<div class="btn-group dropup">
<button class="btn dropdown-toggle" data-toggle="dropdown">显示比例<span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a id="btn_dar_original" href="#">视频原始比例</a></li>
<li><a id="btn_dar_21_9" href="#">宽屏影院(21:9)</a></li>
<li><a id="btn_dar_16_9" href="#">宽屏电视(16:9)</a></li>
<li><a id="btn_dar_4_3" href="#">窄屏(4:3)</a></li>
<li><a id="btn_dar_fill" href="#">填充(容器比例)</a></li>
</ul>
</div>
<div class="btn-group dropup">
<button class="btn dropdown-toggle" data-toggle="dropdown">缓冲区大小<span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a id="btn_bt_0_1" href="#">0.1秒(实时)</a></li>
<li><a id="btn_bt_0_2" href="#">0.2秒(实时)</a></li>
<li><a id="btn_bt_0_3" href="#">0.3秒(实时)</a></li>
<li><a id="btn_bt_0_5" href="#">0.5秒(实时)</a></li>
<li><a id="btn_bt_0_8" href="#">0.8秒(会议)</a></li>
<li><a id="btn_bt_1_0" href="#">1秒(低延迟)</a></li>
<li><a id="btn_bt_2_0" href="#">2秒(较低延时)</a></li>
<li><a id="btn_bt_3_0" href="#">3秒(流畅播放)</a></li>
<li><a id="btn_bt_4_0" href="#">4秒(流畅播放)</a></li>
<li><a id="btn_bt_5_0" href="#">5秒(网速较低)</a></li>
<li><a id="btn_bt_6_0" href="#">6秒(网速较低)</a></li>
<li><a id="btn_bt_8_0" href="#">8秒(网速较低)</a></li>
<li><a id="btn_bt_10_0" href="#">10秒(无所谓延迟)</a></li>
<li><a id="btn_bt_15_0" href="#">15秒(无所谓延迟)</a></li>
<li><a id="btn_bt_20_0" href="#">20秒(无所谓延迟)</a></li>
<li><a id="btn_bt_30_0" href="#">30秒(流畅第一)</a></li>
</ul>
</div>
<div class="btn-group dropup">
<button class="btn dropdown-toggle" data-toggle="dropdown">最大缓冲区<span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a id="btn_mbt_0_6" href="#">0.6秒(实时)</a></li>
<li><a id="btn_mbt_0_9" href="#">0.9秒(实时)</a></li>
<li><a id="btn_mbt_1_2" href="#">1.2秒(实时)</a></li>
<li><a id="btn_mbt_1_5" href="#">1.5秒(实时)</a></li>
<li><a id="btn_mbt_2_4" href="#">2.4秒(会议)</a></li>
<li><a id="btn_mbt_3_0" href="#">3秒(低延迟)</a></li>
<li><a id="btn_mbt_6_0" href="#">6秒(较低延时)</a></li>
<li><a id="btn_mbt_9_0" href="#">9秒(流畅播放)</a></li>
<li><a id="btn_mbt_12_0" href="#">12秒(流畅播放)</a></li>
<li><a id="btn_mbt_15_0" href="#">15秒(网速较低)</a></li>
<li><a id="btn_mbt_18_0" href="#">18秒(网速较低)</a></li>
<li><a id="btn_mbt_24_0" href="#">24秒(网速较低)</a></li>
<li><a id="btn_mbt_30_0" href="#">30秒(无所谓延迟)</a></li>
<li><a id="btn_mbt_45_0" href="#">45秒(无所谓延迟)</a></li>
<li><a id="btn_mbt_60_0" href="#">60秒(无所谓延迟)</a></li>
<li><a id="btn_mbt_90_0" href="#">90秒(流畅第一)</a></li>
</ul>
</div>
<div class="btn-group dropup">
<a id="btn_fullscreen" class="btn">全屏</a>
</div>
<div class="btn-group dropup">
<button id="btn_pause" class="btn">暂停播放</button>
<button id="btn_resume" class="btn hide">继续播放</button>
</div>
<div class="btn-group dropup">
<button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">关闭播放器</button>
</div>
</div>
<div class="hide" id="fullscreen_tips">
<font color="red">点击视频</font>进入全屏模式~<br/>
由于安全原因Flash全屏无法使用JS触发
</div>
<div>
<div class="input-prepend div_play_time" title="BufferLength/BufferTime/MaxBufferTime">
<span class="add-on">@B</span>
<input class="span2" style="width:80px" id="txt_buffer" type="text" placeholder="0/0/0s">
</div>
<div class="input-prepend div_play_time" title="视频的播放流畅度">
<span class="add-on">@F</span>
<input class="span2" style="width:57px" id="txt_fluency" type="text" placeholder="100%">
</div>
<div class="input-prepend div_play_time" title="视频总共卡顿次数">
<span class="add-on">@E</span>
<input class="span2" style="width:45px" id="txt_empty_count" type="text" placeholder="0">
</div>
<div class="input-prepend div_play_time" title="视频当前的帧率FPS">
<span class="add-on">@F</span>
<input class="span2" style="width:55px" id="txt_fps" type="text" placeholder="fps">
</div>
<div class="input-prepend div_play_time" title="视频当前的码率(视频+音频)单位Kbps">
<span class="add-on">@B</span>
<input class="span2" style="width:55px" id="txt_bitrate" type="text" placeholder="kbps">
</div>
<div class="input-prepend div_play_time" title="播放时长,格式:天 时:分:秒">
<span class="add-on">@T</span>
<input class="span2" style="width:85px" id="txt_time" type="text" placeholder="天 时:分:秒">
</div>
</div>
<div style="margin-top:-12px;">
<span id="debug_info"></span>
URL: <a href="#" id="player_url"></a>
<div class="input-prepend div_play_time" title="当前时间:年-月-日 时:分:秒">
<span class="add-on">@N</span>
<input class="span2" style="width:135px" id="player_clock" type="text" placeholder="年-月-日 时:分:秒">
</div>
</div>
<div>
<div class="btn-group dropup">
<button class="btn btn-primary" id="btn_ptz_up"> 上↑ </button>
<button class="btn btn-primary" id="btn_ptz_down"> 下↓ </button>
<button class="btn btn-primary" id="btn_ptz_left"> ←左 </button>
<button class="btn btn-primary" id="btn_ptz_right"> 右→ </button>
<button class="btn btn-primary" id="btn_ptz_zoomin"> 放大+ </button>
<button class="btn btn-primary" id="btn_ptz_zoomout"> 缩小- </button>
</div>
[注意] !!! 云台控制需要启用内部sip功能
<div class="input-prepend" title="首播时间,点播放到开始播放的时间,秒">
<span class="add-on">@PST</span>
<input class="span1" style="width:60px" id="txt_pst" type="text" placeholder="N秒">
</div>
</div>
</div>
</div>
<div id="rtc_player_modal" class="modal hide fade">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3><a href="https://github.com/ossrs/srs">RtcPlayer</a></h3>
</div>
<div class="modal-body">
<video id="rtc_media_player" controls autoplay ></video>
</div>
<div class="modal-footer" id="my_modal_footer">
<div>
<div class="btn-group dropup">
<button class="btn btn-primary" id="btn_ptz_up_rtc"> 上↑ </button>
<button class="btn btn-primary" id="btn_ptz_down_rtc"> 下↓ </button>
<button class="btn btn-primary" id="btn_ptz_left_rtc"> ←左 </button>
<button class="btn btn-primary" id="btn_ptz_right_rtc"> 右→ </button>
<button class="btn btn-primary" id="btn_ptz_zoomin_rtc"> 放大+ </button>
<button class="btn btn-primary" id="btn_ptz_zoomout_rtc"> 缩小- </button>
</div>
[注意] !!! 云台控制需要启用内部sip功能
</div>
</div>
</div>
<div id="create_channel_modal" class="modal hide fade">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3>创建通道</h3>
</div>
<div class="modal-body">
<div>
<span class="add-on">通道ID</span>
<input class="span1" style="width:200px" id="txt_channel_id" type="text" >
</div>
<div>
<span class="add-on">app</span>
<input class="span1" style="width:200px" id="txt_app" type="text" value="live">
</div>
<div>
<div>可以参数化: [stream]--通道ID; [ssrc]--rtp中ssrc; [timestamp]--当前时间戳</div>
<span class="add-on">stream</span>
<input class="span1" style="width:200px" id="txt_stream" type="text" value="[stream]">
</div>
<div>
<span>端口模式</span>
<select id="sel_ch_mode_type" onclick="selectChannelModeType(this)">
<option value="fixed">固定</option>
<option value="random">随机</option>
</select>
</div>
</div>
<div class="modal-footer" id="my_modal_footer">
<div class="btn-group dropup">
<button id="btn_channel_cancel" class="btn btn-primary">取消</button>
</div>
<div class="btn-group dropup">
<button id="btn_channel_submit" class="btn btn-primary">提交</button>
</div>
</div>
</div>
</div>
<footer>
<p></p>
<p><a href="https://github.com/ossrs/srs">SRS Team &copy; 2013</a></p>
</footer>
</div>
</body>
<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/swfobject.js"></script>
<script type="text/javascript" src="js/json2.js"></script>
<script type="text/javascript" src="js/srs.page.js"></script>
<script type="text/javascript" src="js/srs.log.js"></script>
<script type="text/javascript" src="js/srs.player.js"></script>
<script type="text/javascript" src="js/srs.publisher.js"></script>
<script type="text/javascript" src="js/srs.utility.js"></script>
<script type="text/javascript" src="js/winlin.utility.js"></script>
<script type="text/javascript">
var __on_flash_ready = null;
$(function(){
// 探测Flash是否正常启用。
$('#main_flash_hdr').html(
'\
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="100%" height="100%"> \
<param name="movie" value="srs_player/release/srs_player.swf"> \
<param name="quality" value="autohigh"> \
<param name="swliveconnect" value="true"> \
<param name="allowScriptAccess" value="always"> \
<param name="bgcolor" value="#0"> \
<param name="allowFullScreen" value="true"> \
<param name="wmode" value="opaque"> \
<param name="FlashVars" value="log=1"> \
<param name="flashvars" value="id=1&on_player_ready=__on_flash_ready"> \
<embed src="srs_player/release/srs_player.swf" width="100%" height="100%" \
quality="autohigh" bgcolor="#0" align="middle" allowfullscreen="true" allowscriptaccess="always" \
type="application/x-shockwave-flash" swliveconnect="true" wmode="opaque" \
flashvars="id=1&on_player_ready=__on_flash_ready" \
pluginspage="http://www.macromedia.com/go/getflashplayer"> \
</object> \
'
);
$('#main_flash_hdr').show();
var showFlashHdr = setTimeout(function(){
$('#main_flash_alert').show();
}, 300);
__on_flash_ready = function (id) {
clearTimeout(showFlashHdr);
$('#main_flash_alert').hide();
$('#main_flash_hdr').hide();
$('#main_content').show();
autoLoadPage();
};
});
</script>
<script type="text/javascript">
var srs_player = null;
var url = null;
var query = parse_query_string();
$("#txt_api_url").val("http://" + query.host + ":1985")
var __active_dar = null;
function select_dar(dar_id, num, den) {
srs_player.set_dar(num, den);
if (__active_dar) {
__active_dar.removeClass("active");
}
__active_dar = $(dar_id).parent();
__active_dar.addClass("active");
}
var __active_size = null;
function select_fs_size(size_id, refer, percent) {
srs_player.set_fs(refer, percent);
if (__active_size) {
__active_size.removeClass("active");
}
__active_size = $(size_id).parent();
__active_size.addClass("active");
}
function select_buffer(buffer_time) {
var bt = buffer_time;
var bt_id = "#btn_bt_" + bt.toFixed(1).replace(".", "_");
select_buffer_time(bt_id, bt);
}
function select_max_buffer(max_buffer_time) {
var mbt = max_buffer_time;
var mbt_id = "#btn_mbt_" + mbt.toFixed(1).replace(".", "_");
select_max_buffer_time(mbt_id, mbt);
}
var __active_bt = null;
function select_buffer_time(bt_id, buffer_time) {
srs_player.set_bt(buffer_time);
if (__active_bt) {
__active_bt.removeClass("active");
}
__active_bt = $(bt_id).parent();
__active_bt.addClass("active");
select_max_buffer(srs_player.max_buffer_time);
}
var __active_mbt = null;
function select_max_buffer_time(mbt_id, max_buffer_time) {
srs_player.set_mbt(max_buffer_time);
if (__active_mbt) {
__active_mbt.removeClass("active");
}
__active_mbt = $(mbt_id).parent();
__active_mbt.addClass("active");
}
//格式化json显示
function syntaxHighlight(json) {
if (typeof json != 'string') {
json = JSON.stringify(json, undefined, 2);
}
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function(match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
}
function http_get(url){
var retdata = null;
console.log("GET", url);
$.ajax({
type : "GET",
async : false,
url : url,
contentType: "text/html",
data : "",
complete : function() {
},
error : function(ret) {
alert("GET 请求失败:" + url);
},
success : function(ret) {
console.log(ret);
//var jdata = JSON.parse(ret);
retdata = ret;//.data;
}
});
return retdata;
}
function refreshSipSessionList(sessionList){
$("#sipSessionList").empty();
for (idx in sessionList.sessions)
{
//href="javascript:void(0)" onclick="fn(this)">
var session = sessionList.sessions[idx];
var id = "id:" +session.id;
var li = "<li><a id='linkChannelId1' href='javascript:void(0)' onclick='sipSessionOnClick(this)'>" +id + "</a></li>";
$("#sipSessionList").append(li);
var devices = session.devices;
for (idx2 in devices)
{
//href="javascript:void(0)" onclick="fn(this)">
var id = "-->" + devices[idx2].device_id + ":" + devices[idx2].device_status + ":" + devices[idx2].invite_status;
var li = "<li><a id='linkChannelId1' href='javascript:void(0)' onclick='sipSessionOnClick(this)' rel='"+ session.id + "'>" +id + "</a></li>";
$("#sipSessionList").append(li);
}
}
//if (sessionList == undefined)
// $("#lab_chlist").text("(0)");
//else
// $("#lab_chlist").text("("+sessionList.length+")");
}
function sipSessionOnClick(chidObj){
id = chidObj.rel + chidObj.text;
if (id.indexOf("id:") != -1) {
var aa = id.split(":")
sessionid = aa[1];
url = $("#txt_api_url").val();
var apiurl = url + "/api/v1/gb28181?action=sip_query_session&id=" + sessionid
var ret = http_get(apiurl);
$('#sipSessionMessage').html(syntaxHighlight(ret));
if (ret.code == 0 && ret.data != undefined ) {
};
}
$("#sipSessionId").text(id);
}
function channelOnClick(chidObj){
id = chidObj.text;
$("#gb28181ChannelId").text(id);
url = $("#txt_api_url").val();
var apiurl = url + "/api/v1/gb28181?action=query_channel&id=" + id
var ret = http_get(apiurl);
$('#gb28181ChannelMessage').html(syntaxHighlight(ret));
if (ret.code == 0 && ret.data != undefined ) {
$("#txt_rtmp_url").val(ret.data.channels[0].rtmp_url);
ret.data.channels[0].rtmp_url.split("//")
var urlObject = parse_rtmp_url(ret.data.channels[0].rtmp_url);
var werbrtc_url = "webrtc://"+ urlObject.server + "/" + urlObject.app + "/" + urlObject.stream;
$("#txt_rtc_url").val(werbrtc_url);
}
}
function refreshGb28181ChList(gb28181ChList){
$("#gb28181ChList").empty();
for (idx in gb28181ChList.channels)
{
//href="javascript:void(0)" onclick="fn(this)">
var channel = gb28181ChList.channels[idx];
var id = channel.id;
var li = "<li><a id='linkChannelId' href='javascript:void(0)' onclick='channelOnClick(this)'>" +id + "</a></li>";
$("#gb28181ChList").append(li);
}
//if (sessionList == undefined)
// $("#lab_chlist").text("(0)");
//else
// $("#lab_chlist").text("("+sessionList.length+")");
}
/****
* The parameters for this page:
* schema, the protocol schema, rtmp or http.
* server, the ip of the url.
* port, the rtmp port of url.
* vhost, the vhost of url, can equals to server.
* app, the app of url.
* stream, the stream of url, can endwith .flv or .mp4 or nothing for RTMP.
* autostart, whether auto play the stream.
* buffer, the buffer time in seconds.
* extra params:
* shp_identify, hls+ param.
* for example:
* http://localhost:8088/players/srs_player.html?vhost=ossrs.net&app=live&stream=livestream&server=ossrs.net&port=1935&autostart=true&schema=rtmp
* http://localhost:8088/players/srs_player.html?vhost=ossrs.net&app=live&stream=livestream.flv&server=ossrs.net&port=8080&autostart=true&schema=http
*/
var autoLoadPage = function() {
var query = parse_query_string();
// get the vhost and port to set the default url.
// for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo
// url set to: rtmp://demo:1935/live/livestream
srs_init_rtmp("#txt_url", "#main_modal");
srs_init_rtmp("#txt_url", "#rtc_player_modal");
// consts for buffer and max buffer.
var bts = [0.1, 0.2, 0.3, 0.5, 0.8, 1, 2, 3, 4, 5, 6, 8, 10, 15, 20, 30];
var mbts = [0.6, 0.9, 1.2, 1.5, 2.4, 3, 6, 9, 12, 15, 18, 24, 30, 45, 60, 90];
// the play startup time.
var pst = new Date();
var pc = null; // Global handler to do cleanup when replaying.
$("#main_modal").on("show", function(){
if (srs_player) {
return;
}
$("#div_container").remove();
$("#debug_info").text("");
var div_container = $("<div/>");
$(div_container).attr("id", "div_container");
$("#player").append(div_container);
var player = $("<div/>");
$(player).attr("id", "player_id");
$(div_container).append(player);
srs_player = new SrsPlayer("player_id", srs_get_player_width(), srs_get_player_height());
srs_player.on_player_ready = function() {
var buffer_time = 0.5;
if (url.indexOf('.m3u8') > 0) {
buffer_time = 2;
}
if (query.buffer) {
for (var i = 0; i < bts.length - 1; i++) {
var cur = bts[i];
var next = bts[i+1];
if (Number(query.buffer) >= cur && Number(query.buffer) < next) {
buffer_time = cur;
break;
}
}
}
select_buffer(buffer_time);
this.play(url);
pst = new Date();
};
srs_player.on_player_status = function(code, desc) {
//console.log("[播放器状态] code=" + code + ", desc=" + desc);
};
srs_player.on_player_metadata = function(metadata) {
$("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")");
if (metadata.ip && metadata.pid && metadata.cid) {
$("#debug_info").text("ID:" + metadata.ip + '/' + metadata.pid + '/' + metadata.cid + '');
}
select_dar("#btn_dar_original", 0, 0);
select_fs_size("#btn_fs_size_screen_100", "screen", 100);
};
srs_player.on_player_timer = function(time, buffer_length, kbps, fps, rtime) {
if (time > 0 && pst) {
var diff = (new Date().getTime() - pst.getTime()) / 1000.0;
$("#txt_pst").val(Number(diff).toFixed(2) + "秒");
pst = null;
}
var buffer = buffer_length / this.max_buffer_time * 100;
$("#pb_buffer").width(Number(buffer).toFixed(1) + "%");
$("#pb_buffer_bg").attr("title",
"缓冲区:" + buffer_length.toFixed(1) + "秒, 最大缓冲区:"
+ this.max_buffer_time.toFixed(1) + "秒, 当前:"
+ buffer.toFixed(1) + "%");
var bts = this.buffer_time >= 1? this.buffer_time.toFixed(0) : this.buffer_time.toFixed(1);
var mbts = this.buffer_time >= 1? this.max_buffer_time.toFixed(0) : this.max_buffer_time.toFixed(1);
$("#txt_buffer").val(buffer_length.toFixed(1) + "/" + bts + "/" + mbts + "s");
$("#txt_bitrate").val(kbps.toFixed(0) + "kbps");
$("#txt_fps").val(fps.toFixed(1) + "fps");
$("#txt_empty_count").val(srs_player.empty_count() + "次");
$("#txt_fluency").val(srs_player.fluency().toFixed(2) + "%");
var time_str = "";
// day
time_str = padding(parseInt(time / 24 / 3600), 2, '0') + " ";
// hour
time = time % (24 * 3600);
time_str += padding(parseInt(time / 3600), 2, '0') + ":";
// minute
time = time % (3600);
time_str += padding(parseInt(time / 60), 2, '0') + ":";
// seconds
time = time % (60);
time_str += padding(parseInt(time), 2, '0');
// show
$("#txt_time").val(time_str);
var clock = new Date().getTime() / 1000;
$("#player_clock").val(absolute_seconds_to_YYYYmmdd(clock) + " " + absolute_seconds_to_HHMMSS(clock));
};
srs_player.start();
});
$("#main_modal").on("hide", function(){
if (srs_player) {
// report the log to backend.
//console.log(srs_player.dump_log());
srs_player.stop();
srs_player = null;
}
});
var apply_url_change = function() {
var rtmp = parse_rtmp_url($("#txt_url").val());
var url = "http://" + query.host + query.pathname + "?"
+ "app=" + rtmp.app + "&stream=" + rtmp.stream
+ "&server=" + rtmp.server + "&port=" + rtmp.port
+ "&autostart=true";
if (query.shp_identify) {
url += "&shp_identify=" + query.shp_identify;
}
if (rtmp.vhost == "__defaultVhost__") {
url += "&vhost=" + rtmp.server;
} else {
url += "&vhost=" + rtmp.vhost;
}
if (rtmp.schema == "http") {
url += "&schema=http";
}
if (query.buffer) {
url += "&buffer=" + query.buffer;
}
if (query.api_port) {
url += "&api_port=" + query.api_port;
}
var queries = user_extra_params(query);
if (queries && queries.length) {
url += '&' + queries.join('&');
}
$("#player_url").text($("#txt_url").val()).attr("href", url);
$("#link_server").text(rtmp.server);
$("#link_port").text(rtmp.port);
$("#link_vhost").text(rtmp.vhost);
$("#link_app").text(rtmp.app);
$("#link_stream").text(rtmp.stream);
$("#link_rtmp").text($("#txt_url").val());
$("#link_url").attr("href", url);
};
$("#txt_url").change(function(){
apply_url_change();
});
$("#btn_generate_link").click(function(){
$("#link_modal").modal({show:true, keyboard:true});
});
$("#btn_play").click(function(){
url = $("#txt_rtmp_url").val();
$("#main_modal").modal({show:true, keyboard:true});
});
$("#btn_fullscreen").click(function(){
$("#fullscreen_tips").toggle();
});
$("#btn_pause").click(function() {
$("#btn_resume").toggle();
$("#btn_pause").toggle();
srs_player.pause();
});
$("#btn_resume").click(function(){
$("#btn_resume").toggle();
$("#btn_pause").toggle();
srs_player.resume();
});
if (true) {
$("#srs_publish").click(function () {
url = $("#srs_publish").text();
$("#main_modal").modal({show: true, keyboard: false});
});
$("#srs_publish_ld").click(function () {
url = $("#srs_publish_ld").text();
$("#main_modal").modal({show: true, keyboard: false});
});
$("#srs_publish_sd").click(function () {
url = $("#srs_publish_sd").text();
$("#main_modal").modal({show: true, keyboard: false});
});
$("#srs_publish_fw").click(function () {
url = $("#srs_publish_fw").text();
$("#main_modal").modal({show: true, keyboard: false});
});
$("#srs_publish_fw_ld").click(function () {
url = $("#srs_publish_fw_ld").text();
$("#main_modal").modal({show: true, keyboard: false});
});
$("#srs_publish_fw_sd").click(function () {
url = $("#srs_publish_fw_sd").text();
$("#main_modal").modal({show: true, keyboard: false});
});
}
var jwplayer_url = "http://" + query.host + query.dir + "/jwplayer6.html?vhost=demo.srs.com&app=live&hls_autostart=true";
if (true) {
$("#srs_publish_hls").attr("href", jwplayer_url + "&stream=livestream");
$("#srs_publish_ld_hls").attr("href", jwplayer_url + "&stream=livestream_ld");
$("#srs_publish_sd_hls").attr("href", jwplayer_url + "&stream=livestream_sd");
var jwplayer_url = "http://" + query.host + query.dir + "/jwplayer6.html?vhost=demo.srs.com&app=forward/live&hls_autostart=true";
$("#srs_publish_fw_hls").attr("href", jwplayer_url + "&stream=livestream");
$("#srs_publish_fw_ld_hls").attr("href", jwplayer_url + "&stream=livestream_ld");
$("#srs_publish_fw_sd_hls").attr("href", jwplayer_url + "&stream=livestream_sd");
}
if (true) {
$("#btn_dar_original").click(function(){
select_dar("#btn_dar_original", 0, 0);
});
$("#btn_dar_21_9").click(function(){
select_dar("#btn_dar_21_9", 21, 9);
});
$("#btn_dar_16_9").click(function(){
select_dar("#btn_dar_16_9", 16, 9);
});
$("#btn_dar_4_3").click(function(){
select_dar("#btn_dar_4_3", 4, 3);
});
$("#btn_dar_fill").click(function(){
select_dar("#btn_dar_fill", -1, -1);
});
}
if (true) {
$("#btn_fs_size_video_100").click(function(){
select_fs_size("#btn_fs_size_video_100", "video", 100);
});
$("#btn_fs_size_video_75").click(function(){
select_fs_size("#btn_fs_size_video_75", "video", 75);
});
$("#btn_fs_size_video_50").click(function(){
select_fs_size("#btn_fs_size_video_50", "video", 50);
});
$("#btn_fs_size_screen_100").click(function(){
select_fs_size("#btn_fs_size_screen_100", "screen", 100);
});
$("#btn_fs_size_screen_75").click(function(){
select_fs_size("#btn_fs_size_screen_75", "screen", 75);
});
$("#btn_fs_size_screen_50").click(function(){
select_fs_size("#btn_fs_size_screen_50", "screen", 50);
});
}
if (true) {
for (var i = 0; i < bts.length; i++) {
var bt = bts[i];
var bt_id = "#btn_bt_" + bt.toFixed(1).replace(".", "_");
var bt_fun = function(id, v){
$(bt_id).click(function(){
select_buffer_time(id, v);
// remember the chagned buffer.
if (Number(query.buffer) != srs_player.buffer_time) {
query.buffer = srs_player.buffer_time;
apply_url_change();
}
});
};
bt_fun(bt_id, bt);
}
}
if (true) {
for (var i = 0; i < mbts.length; i++) {
var mbt = mbts[i];
var mbt_id = "#btn_mbt_" + mbt.toFixed(1).replace(".", "_");
var mbt_fun = function(id, v){
$(mbt_id).click(function(){
select_max_buffer_time(id, v);
});
};
mbt_fun(mbt_id, mbt);
}
}
if (true){
$("#btn_sip_query_session").click(function(){
url = $("#txt_api_url").val();
$("#txt_api_url").val();
var apiurl = url + "/api/v1/gb28181?action=sip_query_session"
var ret = http_get(apiurl);
$('#sipSessionMessage').html(syntaxHighlight(ret));
if (ret != undefined && ret.code == 0){
refreshSipSessionList(ret.data);
}
});
var time_query = function(){
$("#btn_sip_query_session").click();
setTimeout(function () {$("#btn_sip_query_session").click()}, 1000);
}
$("#btn_sip_unregister").click(function(){
var id = $("#sipSessionId").text();
if (id.indexOf("id:") != -1) {
var str = id.split(":")
url = $("#txt_api_url").val();
var apiurl = url + "/api/v1/gb28181?action=sip_unregister&id=" + str[1];
var ret = http_get(apiurl);
$('#sipSessionMessage').html(syntaxHighlight(ret));
if (ret != undefined && ret.code == 0){
time_query();
}
}
});
$("#btn_sip_invite").click(function(){
var text = $("#sipSessionId").text();
if (text.indexOf("-->") != -1) {
var str = text.split("-->");
id = str[0];
var str2 = str[1].split(":")
chid = str2[0];
url = $("#txt_api_url").val();
var apiurl = url + "/api/v1/gb28181?action=sip_invite&id=" + id + "&chid="+chid;
var ret = http_get(apiurl);
$('#sipSessionMessage').html(syntaxHighlight(ret));
if (ret != undefined && ret.code == 0){
time_query();
}
}
});
$("#btn_sip_bye").click(function(){
var text = $("#sipSessionId").text();
if (text.indexOf("-->") != -1) {
var str = text.split("-->");
id = str[0];
var str2 = str[1].split(":")
chid = str2[0];
url = $("#txt_api_url").val();
var apiurl = url + "/api/v1/gb28181?action=sip_bye&id=" + id + "&chid="+chid;
var ret = http_get(apiurl);
$('#sipSessionMessage').html(syntaxHighlight(ret));
if (ret != undefined && ret.code == 0){
time_query();
}
}
});
$("#btn_sip_querycatalog").click(function(){
var text = $("#sipSessionId").text();
if (text.indexOf("-->") != -1) {
var str = text.split("-->");
id = str[0];
var str2 = str[1].split(":")
chid = str2[0];
url = $("#txt_api_url").val();
var apiurl = url + "/api/v1/gb28181?action=sip_query_catalog&id=" + id + "&chid="+chid;
var ret = http_get(apiurl);
$('#sipSessionMessage').html(syntaxHighlight(ret));
if (ret != undefined && ret.code == 0){
time_query();
}
}
});
$("#btn_query_channel").click(function(){
url = $("#txt_api_url").val();
var apiurl = url + "/api/v1/gb28181?action=query_channel"
var ret = http_get(apiurl);
$('#gb28181ChannelMessage').html(syntaxHighlight(ret));
if (ret != undefined && ret.code == 0){
refreshGb28181ChList(ret.data);
}
});
$("#btn_delete_channel").click(function(){
var id = $("#gb28181ChannelId").text();
url = $("#txt_api_url").val();
var apiurl = url + "/api/v1/gb28181?action=delete_channel&id=" + id;
var ret = http_get(apiurl);
$('#gb28181ChannelMessage').html(syntaxHighlight(ret));
if (ret != undefined && ret.code == 0){
$("#btn_query_channel").click();
}
});
var call_ptz_cmd = function(cmd) {
var str = $("#gb28181ChannelId").text();
var str_array = str.split("@")
var chid = "";
var id = "";
if (str_array.length < 1){
return;
}
var speed = "136";
id = str_array[0];
chid = str_array[1];
url = $("#txt_api_url").val();
var apiurl = url + "/api/v1/gb28181?action=sip_ptz&id=" + id + "&chid="+chid+ "&ptzcmd="+cmd + "&speed=" + speed;
var ret = http_get(apiurl);
$('#gb28181ChannelMessage').html(syntaxHighlight(ret));
};
var ptz_cmd = ["up", "down", "right", "left", "zoomin", "zoomout"]
for (var i=0; i<ptz_cmd.length; i++){
var bt_fun = function(id, cmd){
$(bt_id).mousedown(function(){
call_ptz_cmd(cmd);
});
$(bt_id).mouseup(function(){
call_ptz_cmd("stop");
});
};
var bt_id = "#btn_ptz_"+ptz_cmd[i]+ "_rtc";
bt_fun(bt_id, ptz_cmd[i]);
bt_id = "#btn_ptz_"+ptz_cmd[i];
bt_fun(bt_id, ptz_cmd[i]);
}
$("#btn_create_channel").click(function(){
$("#create_channel_modal").modal({show: true, keyboard: false});
});
$("#btn_channel_cancel").click(function(){
$("#create_channel_modal").modal('hide');
});
$("#btn_channel_submit").click(function(){
var chid = $("#txt_channel_id").val();
var app = $("#txt_app").val();
var stream = $("#txt_stream").val();
var port_mode = $("#sel_ch_mode_type").val();
if (chid == ""){
alert("通道id不能为空")
return
}
url = $("#txt_api_url").val();
var apiurl = url + "/api/v1/gb28181?action=create_channel&id=" + chid + "&app=" + app + "&stream=" + stream + "&port_mode="+ port_mode
var ret = http_get(apiurl);
$('#gb28181ChannelMessage').html(syntaxHighlight(ret));
if (ret != undefined && ret.code == 0){
$("#btn_query_channel").click();
}
$("#create_channel_modal").modal('hide');
});
$("#btn_rtc_play").click(function(){
$('#rtc_media_player').width(srs_get_player_width);
$('#rtc_media_player').height(srs_get_player_height);
$("#rtc_player_modal").modal({show: true, keyboard: false});
startPlay($("#txt_rtc_url").val());
});
$("#rtc_player_modal").on("hide", function(){
if (pc) {
pc.close();
}
});
var startPlay = function(url) {
$('#rtc_media_player').show();
var urlObject = parse_rtmp_url(url);
var schema = window.location.protocol;
// Close PC when user replay.
if (pc) {
pc.close();
}
pc = new RTCPeerConnection(null);
pc.onaddstream = function (event) {
console.debug(event.stream);
$('#rtc_media_player').prop('srcObject', event.stream);
};
new Promise(function(resolve, reject) {
pc.addTransceiver("audio", {direction: "recvonly"});
pc.addTransceiver("video", {direction: "recvonly"});
pc.createOffer(function(offer){
resolve(offer);
},function(reason){
reject(reason);
});
}).then(function(offer) {
return pc.setLocalDescription(offer).then(function(){ return offer; });
}).then(function(offer) {
return new Promise(function(resolve, reject) {
var port = urlObject.port || 1985;
// @see https://github.com/rtcdn/rtcdn-draft
var api = urlObject.user_query.play || '/rtc/v1/play/';
if (api.lastIndexOf('/') != api.length - 1) {
api += '/';
}
var url = schema + '//' + urlObject.server + ':' + port + api;
for (var key in urlObject.user_query) {
if (key != 'api' && key != 'play') {
url += '&' + key + '=' + urlObject.user_query[key];
}
}
// Replace /rtc/v1/play/&k=v to /rtc/v1/play/?k=v
url = url.replace(api + '&', api + '?');
// @see https://github.com/rtcdn/rtcdn-draft
var data = {
api: url, streamurl: urlObject.url, clientip: null, sdp: offer.sdp
};
console.log("offer: " + JSON.stringify(data));
$.ajax({
type: "POST", url: url, data: JSON.stringify(data),
contentType:'application/json', dataType: 'json'
}).done(function(data) {
console.log("answer: " + JSON.stringify(data));
resolve(data.sdp);
}).fail(function(reason){
reject(reason);
});
});
}).then(function(answer) {
return pc.setRemoteDescription(new RTCSessionDescription({type: 'answer', sdp: answer}));
}).catch(function(reason) {
throw reason;
});
};
}
apply_url_change();
};
</script>
</html>