You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
776 lines
44 KiB
776 lines
44 KiB
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<link rel="stylesheet" href="./lib/WSPlayer/player.css">
|
|
<link rel="stylesheet" href="./lib/WSPlayer/window.division.css">
|
|
<link rel="stylesheet" href="./bootstrap.min.css">
|
|
<!-- 滚动进度条样式,按需引入 -->
|
|
<link rel="stylesheet" href="./scroll_style.css">
|
|
<title>APIdemo</title>
|
|
<style>
|
|
.platform-info {
|
|
display: flex;
|
|
margin-bottom: 20px;
|
|
flex-wrap: wrap;
|
|
padding: 20px;
|
|
}
|
|
|
|
.tab {
|
|
width: 100%;
|
|
}
|
|
|
|
.player-container {
|
|
display: flex;
|
|
margin-top: 20px;
|
|
width: 100%;
|
|
padding: 30px;
|
|
}
|
|
|
|
.right-player-container {
|
|
flex: 2;
|
|
}
|
|
|
|
.api-btn-container {
|
|
flex: 1;
|
|
margin-right: 20px;
|
|
}
|
|
|
|
h3 {
|
|
margin-top: 16px;
|
|
}
|
|
|
|
.api-ipt {
|
|
display: flex;
|
|
width: 100%;
|
|
height: 300px;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.api-ipt>div {
|
|
flex: 1;
|
|
}
|
|
|
|
.has-success .valid-feedback {
|
|
display: unset;
|
|
}
|
|
|
|
#ws-record-player,
|
|
#ws-record-player {
|
|
overflow: hidden;
|
|
}
|
|
|
|
.list-group a {
|
|
text-decoration: none;
|
|
color: #13425c;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<div class="alert alert-dismissible alert-primary">
|
|
<!-- <button type="button" class="btn-close" data-bs-dismiss="alert"></button> -->
|
|
<span id="notify"></span>
|
|
</div>
|
|
<h3>视频web无插件播放器 V1.3.4</h3>
|
|
<!-- 右侧固定小弹窗 -->
|
|
<div style="position: fixed; right: 0; top: 60px; width: 250px;">
|
|
<p style="font-size: 20px;">
|
|
<button type="button" class="btn btn-outline-secondary"><a href="/demo.html">点击跳转到简易拉流页面</a></button>
|
|
</p>
|
|
<div class="platform-info">
|
|
大华平台信息
|
|
<div class="form-floating mb-3">
|
|
<input type="text" class="form-control" id="ip" placeholder="10.10.10.10">
|
|
<label for="floatingInput">平台IP:</label>
|
|
</div>
|
|
<div class="form-floating mb-3">
|
|
<input type="text" class="form-control" id="platform_port" placeholder="443">
|
|
<label for="floatingInput">平台端口:</label>
|
|
</div>
|
|
<div class="form-floating mb-3">
|
|
<input type="text" class="form-control" id="real_port" placeholder="443">
|
|
<label id="real_port_label" for="floatingInput"></label>
|
|
</div>
|
|
<div class="form-floating mb-3">
|
|
<input type="text" class="form-control" id="record_port" placeholder="443">
|
|
<label id="record_port_label" for="floatingInput"></label>
|
|
</div>
|
|
<button type="button" class="btn btn-outline-secondary btn-sm" id="open-icc-info">一键填写开放平台联调环境</button>
|
|
<button type="button" class="btn btn-outline-secondary btn-sm" id="submit-platform">确认信息自动生成 wsUrl</button>
|
|
<span id="certificate-message" style="color: red;"></span>
|
|
</div>
|
|
</div>
|
|
<!-- 左侧固定小弹窗 -->
|
|
<ul class="list-group" style="position: fixed; left: 8px; top: 150px; width: 200px;">
|
|
<li
|
|
class="list-group-item list-group-item-primary d-flex justify-content-between align-items-center cursor-pointer">
|
|
<a href="https://open-icc.dahuatech.com/iccdoc/openfaq/wiki/iccfaq/question/admin.html#WSPlayer%E6%8B%89%E6%B5%81wss%E9%85%8D%E7%BD%AE%EF%BC%9B%E8%A7%86%E9%A2%91%E5%BA%94%E7%94%A8"
|
|
target="_blank">跳转证书配置</a>
|
|
</li>
|
|
<li
|
|
class="list-group-item list-group-item-secondary d-flex justify-content-between align-items-center cursor-pointer">
|
|
<a href="https://open-icc.dahuatech.com/iccdoc/enterprisebase/5.0.15/wiki/admin/replay.html#%E5%BD%95%E5%83%8F%E4%B8%8B%E8%BD%BD"
|
|
target="_blank">跳转下载录像功能</a>
|
|
</li>
|
|
<li
|
|
class="list-group-item list-group-item-success d-flex justify-content-between align-items-center cursor-pointer">
|
|
<a href="https://open-icc.dahuatech.com/wsplayer/#/api" target="_blank">跳转到国际化方案</a>
|
|
</li>
|
|
<li
|
|
class="list-group-item list-group-item-info d-flex justify-content-between align-items-center cursor-pointer">
|
|
<a href="https://open-icc.dahuatech.com/#/videoIntegration" target="_blank">音视频集成方案</a>
|
|
</li>
|
|
<li
|
|
class="list-group-item list-group-item-warning d-flex justify-content-between align-items-center cursor-pointer">
|
|
<a href="https://open-icc.dahuatech.com/wsplayer/#/remember" target="_blank">跳转FAQ</a>
|
|
</li>
|
|
<li
|
|
class="list-group-item list-group-item-danger d-flex justify-content-between align-items-center cursor-pointer">
|
|
<a href="https://open-icc.dahuatech.com/wsplayer/#/index" target="_blank">跳转老版本demo</a>
|
|
</li>
|
|
<li
|
|
class="list-group-item list-group-item-light d-flex justify-content-between align-items-center cursor-pointer">
|
|
<a href="https://open-icc.dahuatech.com/iccdoc/videoIntegrationShowDoc/partone.html#wsplayer"
|
|
target="_blank">跳转性能规格</a>
|
|
</li>
|
|
<li
|
|
class="list-group-item list-group-item-dark d-flex justify-content-between align-items-center cursor-pointer">
|
|
<a href="https://open-icc.dahuatech.com/wsplayer/#/changelog" target="_blank">跳转到版本更新说明</a>
|
|
</li>
|
|
</ul>
|
|
<div class="container" style="width: 90%!important;">
|
|
<div class="tab btn-group" role="group" aria-label="Basic radio toggle button group">
|
|
<input type="radio" class="btn-check" name="btnradio" id="btnradio1" autocomplete="off" checked>
|
|
<label class="btn btn-outline-primary" for="btnradio1">实时预览</label>
|
|
<input type="radio" class="btn-check" name="btnradio" id="btnradio2" autocomplete="off">
|
|
<label class="btn btn-outline-primary" for="btnradio2">录像回放</label>
|
|
</div>
|
|
<!-- 内容 -->
|
|
<div class="player-container">
|
|
<!-- 功能输入框 -->
|
|
<div class="api-btn-container">
|
|
<div class="accordion" id="accordionExample">
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header" id="headingOne">
|
|
<button class="accordion-button" type="button" data-bs-toggle="collapse"
|
|
data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
|
|
拉流测试
|
|
</button>
|
|
</h2>
|
|
<div id="collapseOne" class="accordion-collapse collapse show" data-id="api"
|
|
aria-labelledby="headingOne" data-bs-parent="#accordionExample">
|
|
<div class="accordion-body">
|
|
<!-- 内容1 -->
|
|
<!-- 实时预览 -->
|
|
<div class="real-container">
|
|
<div class="has-success">
|
|
<label class="form-label mt-4" for="real-ws">请输入websocket地址(必传,非接口返回,需自行拼接)</label>
|
|
<input id="real-ws" placeholder="wss://10.10.10.10:9100" type="text"
|
|
class="form-control">
|
|
<div class="valid-feedback">可通过右侧填写平台信息, 自动拼接, 对讲和实时预览通用,实时预览/对讲端口默认 ws 是 9100 wss 是 9102</div>
|
|
</div>
|
|
<div class="has-success">
|
|
<label class="form-label mt-4" for="real-rtsp">请输入实时预览 rtsp 地址: </label>
|
|
<input id="real-rtsp"
|
|
placeholder="rtsp://10.10.10.10/dss/monitor/param/cameraid=1000000%240%26substream=1?token=1"
|
|
type="text" class="form-control">
|
|
<div class="valid-feedback">获取预览rtsp地址 <a target="_blank"
|
|
href="https://open-icc.dahuatech.com/iccdoc/enterprisebase/5.0.15/wiki/admin/realtimestreaming.html#rtsp%E5%AE%9E%E6%97%B6%E9%A2%84%E8%A7%88">点击跳转</a>,
|
|
注意要拼接接口返回的token</div>
|
|
</div>
|
|
<div class="has-success">
|
|
<label class="form-label mt-4" for="talk-rtsp">请输入对讲 rtsp 地址: <span
|
|
style="color:red" id="is-support-talk"></span></label>
|
|
<input id="talk-rtsp" placeholder="rtsp://10.10.10.10/talk/pu/1?token=1"
|
|
type="text" class="form-control">
|
|
<div class="valid-feedback">获取对讲rtsp地址 <a target="_blank"
|
|
href="https://open-icc.dahuatech.com/iccdoc/enterprisebase/5.0.15/wiki/admin/realtimestreaming.html#%E5%BC%80%E5%A7%8B%E8%AF%AD%E9%9F%B3%E5%AF%B9%E8%AE%B2">点击跳转</a>,注意要拼接接口返回的token,
|
|
预览成功后才能进行对讲</div>
|
|
</div>
|
|
<div class="has-success">
|
|
<label class="form-label mt-4" for="audioType">请输入audioType(音频类型): </label>
|
|
<input id="audioType" placeholder="只能填 2 或 4, 根据接口返回" type="text"
|
|
class="form-control">
|
|
<div class="valid-feedback">请求时audioType传2对讲, 如果返回2 或 4, 则rtsp有效;
|
|
具体详见对接文档(修订版).word 查看 </div>
|
|
</div>
|
|
<div class="has-success">
|
|
<label class="form-label mt-4" for="gbDevice">对讲模式</label>
|
|
<select class="form-select" id="gbDevice">
|
|
<option value="1">对讲</option>
|
|
<option value="2">广播</option>
|
|
</select>
|
|
<div class="valid-feedback">国标级联下,需采用广播方案,国标接入也采用广播方案</div>
|
|
</div>
|
|
<div>
|
|
<fieldset>
|
|
<label class="form-label mt-4" for="real-channelId">请输入 通道ID:</label>
|
|
<input id="real-channelId" class="form-control" type="text"
|
|
placeholder="1000000$1$0$0">
|
|
</fieldset>
|
|
</div>
|
|
<div>
|
|
<label for="stream-type" class="form-label mt-4">请选择 码流类型: </label>
|
|
<select class="form-select" id="stream-type">
|
|
<option value="1">主码流</option>
|
|
<option value="2">辅码流1</option>
|
|
<option value="3">辅码流2</option>
|
|
</select>
|
|
</div>
|
|
<div style="margin-top: 20px;">
|
|
<button type="button" class="btn btn-outline-primary"
|
|
id="real-btn">实时预览</button>
|
|
<button type="button" class="btn btn-outline-primary"
|
|
id="talk-btn">开始对讲</button>
|
|
</div>
|
|
</div>
|
|
<!-- 录像回放 -->
|
|
<div class="record-container" style="display: none;">
|
|
<div class="has-success">
|
|
<label class="form-label mt-4" for="record-ws">请输入websocket地址(必传,非接口返回,需自行拼接)</label>
|
|
<input id="record-ws" placeholder="wss://10.10.10.10:9320" type="text"
|
|
class="form-control">
|
|
<div class="valid-feedback">wsUrl, 需要前端根据平台信息拼接, demo会根据填写的平台信息自动拼接: </div>
|
|
</div>
|
|
<div class="has-success">
|
|
<label class="form-label mt-4" for="record-rtsp">请输入 rtsp:</label>
|
|
<input id="record-rtsp"
|
|
placeholder="rtsp://10.10.10.10:9322/playback/pu/1?token=1" type="text"
|
|
class="form-control">
|
|
<div class="valid-feedback">获取rtsp地址<a
|
|
href="https://open-icc.dahuatech.com/iccdoc/enterprisebase/5.0.15/wiki/admin/replay.html#rtsp%E4%BB%A5%E6%97%B6%E9%97%B4%E5%BD%A2%E5%BC%8F%E5%9B%9E%E6%94%BE%E5%BD%95%E5%83%8F">点击跳转</a>,先查询录像文件records,
|
|
在查询rtsp9(推荐时间形式回放), 注意流地址要拼接接口返回的token</div>
|
|
</div>
|
|
<div>
|
|
<fieldset>
|
|
<label class="form-label mt-4" for="record-channelId">请输入 通道ID:</label>
|
|
<input id="record-channelId" class="form-control" type="text"
|
|
placeholder="1000000$1$0$0">
|
|
</fieldset>
|
|
</div>
|
|
<div class="has-success">
|
|
<label for="record-records" class="form-label mt-4">请输入录像文件</label>
|
|
<textarea placeholder="默认传: []" class="form-control" id="record-records"
|
|
rows="3">[]</textarea>
|
|
<div class="valid-feedback">records,获取录像文件接口<a target="_blank"
|
|
href="https://open-icc.dahuatech.com/iccdoc/enterprisebase/5.0.15/wiki/admin/replay.html#%E6%9F%A5%E8%AF%A2%E6%99%AE%E9%80%9A%E5%BD%95%E5%83%8F%E4%BF%A1%E6%81%AF%E5%88%97%E8%A1%A8">点击跳转</a>,
|
|
有录像文件才能支持拖拽,传入接口返回的records数组</div>
|
|
</div>
|
|
<div style="margin-top: 20px;">
|
|
<button type="button" class="btn btn-outline-primary"
|
|
id="record-btn">录像回放</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header" id="headingTwo">
|
|
<button class="accordion-button" type="button" data-bs-toggle="collapse"
|
|
data-bs-target="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo">
|
|
API-demo
|
|
</button>
|
|
</h2>
|
|
<div id="collapseTwo" class="accordion-collapse collapse show" aria-labelledby="headingTwo"
|
|
data-bs-parent="#accordionExample">
|
|
<div class="accordion-body">
|
|
<!-- 内容2 -->
|
|
<h3>播放器功能</h3>
|
|
<div class="form-floating mb-3">
|
|
<input class="form-control" id="setPlayerNum"
|
|
placeholder="支持1,2,3,4,6,8,9,16,25和json格式自定义布局,自定义窗口布局需要根据我们的回调获取后保存">
|
|
<label id="text" for="setPlayerNum">设置播放器布局数量</label>
|
|
</div>
|
|
<button id="setFullScreen" type="button" class="btn btn-outline-primary">全屏</button>
|
|
<button id="setExitFullScreen" type="button"
|
|
class="btn btn-outline-primary">退出全屏</button>
|
|
<button id="setPlayerAdapter-selfAdaption" type="button"
|
|
class="btn btn-outline-primary">窗口自适应</button>
|
|
<button id="setPlayerAdapter-stretching" type="button"
|
|
class="btn btn-outline-primary">窗口拉伸</button>
|
|
<h3>播放器窗口功能</h3>
|
|
<div class="form-floating mb-3" style="width: 60%;">
|
|
<input type="number" class="form-control" id="setSelectIndex" placeholder="">
|
|
<label id="text" for="setSelectIndex">设置选中的窗口索引</label>
|
|
</div>
|
|
<div class="form-floating mb-3">
|
|
<input type="text" class="form-control" id="showMsgInWindow" placeholder="">
|
|
<label id="text" for="showMsgInWindow">窗口显示自定义文字</label>
|
|
</div>
|
|
<button id="setIvs-show" type="button" class="btn btn-outline-primary">显示智能帧</button>
|
|
<button id="setIvs-hide" type="button" class="btn btn-outline-primary">隐藏智能帧</button>
|
|
<button id="openVolume" type="button" class="btn btn-outline-primary">开启音量</button>
|
|
<button id="closeVolume" type="button" class="btn btn-outline-primary">关闭音量</button>
|
|
<button id="close" type="button" class="btn btn-outline-primary">关闭视频</button>
|
|
<button id="startLocalRecord" type="button"
|
|
class="btn btn-outline-primary">开始录制视频</button>
|
|
<button id="stopLocalRecord" type="button"
|
|
class="btn btn-outline-primary">停止录制视频</button>
|
|
<button id="picCap" type="button" class="btn btn-outline-primary">抓图</button>
|
|
<div class="record-option-container" style="display: none;">
|
|
<h3>录像扩充功能</h3>
|
|
<div class="form-floating mb-3" style="width: 60%;">
|
|
<input type="number" class="form-control" id="playSpeed" placeholder="">
|
|
<label id="text" for="playSpeed">设置倍速播放</label>
|
|
</div>
|
|
<button id="pause" type="button" class="btn btn-outline-primary">暂停播放</button>
|
|
<button id="play" type="button" class="btn btn-outline-primary">继续播放</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- 播放器 -->
|
|
<div class="right-player-container">
|
|
<!-- 播放dom容器 -->
|
|
<div id="ws-real-player" style="height: 600px;"></div>
|
|
<div id="ws-record-player" style="visibility: hidden;"></div>
|
|
<div class="api-ipt">
|
|
<div class="card border-secondary mb-3">
|
|
<div class="card-header" id="api-name">API调用</div>
|
|
<div class="card-body">
|
|
<h4 class="card-title" id="api-api"></h4>
|
|
<label for="exampleTextarea" class="form-label mt-4"></label>
|
|
<textarea class="form-control" id="api-msg" rows="3"></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="card border-secondary mb-3">
|
|
<div class="card-header" id="callback-msg">回调方法</div>
|
|
<div class="card-body">
|
|
<h4 id="callback-name" class="card-title"></h4>
|
|
<label for="exampleTextarea" class="form-label mt-4"></label>
|
|
<textarea class="form-control" rows="3" id="callback-view"></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
|
|
<script type="text/javascript" src="./lib/WSPlayer/PlaySDKInterface.js"></script>
|
|
<script type="text/javascript" src="./lib/WSPlayer/WSPlayer.js"></script>
|
|
<script type="module">
|
|
function getDom(selector) {
|
|
return document.querySelector(selector)
|
|
}
|
|
let player = {
|
|
realPlayer: null, // 实时预览播放器
|
|
recordPlayer: null // 录像回放播放器
|
|
}
|
|
let playerType = 'realPlayer' // 播放器类型 real-实时预览播放器 record-录像回放播放器
|
|
|
|
let ipDom = getDom('#ip')
|
|
let platformDom = getDom('#platform_port')
|
|
let realPortDom = getDom('#real_port')
|
|
let recordPortDom = getDom('#record_port')
|
|
let isHttp = window.location.protocol === 'http:'
|
|
realPortDom.value = isHttp ? '9100' : '9102'
|
|
recordPortDom.value = isHttp ? '9320' : '9322'
|
|
|
|
let wsplayerParam = JSON.parse(localStorage.getItem('wsplayerParam')) || {
|
|
ip: '',
|
|
platform: '',
|
|
realPort: isHttp ? '9100' : '9102',
|
|
recordPort: isHttp ? '9320' : '9322',
|
|
real_wsUrl: '',
|
|
record_wsUrl: '',
|
|
}
|
|
ipDom.value = wsplayerParam.ip
|
|
platformDom.value = wsplayerParam.platform
|
|
realPortDom.value = wsplayerParam.realPort
|
|
recordPortDom.value = wsplayerParam.recordPort
|
|
renderDom()
|
|
|
|
let selectIndex = 0
|
|
let cbMsg = ''
|
|
// 初始化
|
|
import PlayerManager from './icc/PlayerManager.js'
|
|
|
|
|
|
// 初始化播放器
|
|
// 注意实时预览和录像回放必须要用不同的id,不能复用同一个
|
|
function initPlayer(el) {
|
|
player[playerType] = new PlayerManager({
|
|
el: el, /** 实时预览容器id,创建多个播放器,传入不同的容器id即可 **/
|
|
type: playerType.replace('Player', ''), /** real - 实时预览 record - 录像回放 **/
|
|
maxNum: 25, /** 一个播放器上限能播放的路数,可根据实际情况设置,支持 1 4 9 16 25 **/
|
|
num: 1, /** 初始化,页面显示的路数 **/
|
|
showControl: true, /** 是否显示工具栏,默认显示 **/
|
|
prefixUrl: 'lib', /** 解码库所在位置的前缀 **/
|
|
useH265MSE: false, // 软解
|
|
receiveMessageFromWSPlayer: (methods, data, err) => { /* 回调函数,可以在以下回调函数里面做监听 */
|
|
switch (methods) {
|
|
// 一下是播放器的通用回调
|
|
case 'initializationCompleted':
|
|
console.log('初始化完成')
|
|
cbMsg = '初始化完成'
|
|
// 初始化完成,可调用播放方法(适用于动态加载解码库)
|
|
// 若回调未触发时就使用实时预览/录像回放,则无法播放。
|
|
// 此时我们可以调用一个
|
|
break;
|
|
case 'selectWindowChanged': // 选中的窗口发生改变
|
|
console.log(data, "改变选中的窗口")
|
|
selectIndex = data.playIndex
|
|
getDom('#setSelectIndex').value = data.playIndex
|
|
cbMsg = '改变选中的窗口'
|
|
break;
|
|
case 'windowNumChanged': // 播放器显示的路数发生改变
|
|
console.log(data, "返回显示的窗口数量")
|
|
getDom('#setPlayerNum').value = data
|
|
cbMsg = '当前播放器窗口数量'
|
|
break;
|
|
case 'getVideoFrameInfo':
|
|
// console.log("此处接收视频帧信息");
|
|
break;
|
|
case 'getAudioFrameInfo':
|
|
// console.log("此处接收音频帧信息");
|
|
break;
|
|
case 'closeVideo': // 视频关闭回调
|
|
// 点击关闭按钮引发的视频关闭进行提示
|
|
// 切换视频引发的视频关闭不进行提示
|
|
if (!data.changeVideoFlag) {
|
|
console.log(`窗口${data.selectIndex}的视频已关闭`)
|
|
}
|
|
cbMsg = '关闭视频'
|
|
break;
|
|
case 'statusChanged': // 视频状态发生改变
|
|
break;
|
|
case 'errorInfo': // 错误信息汇总
|
|
console.log(data, "可打印查看错误消息");
|
|
break;
|
|
// 以下是实时预览扩充的回调
|
|
case "changeStreamType": // 主/辅码流切换回调
|
|
console.log("主/辅码流切换回调")
|
|
cbMsg = '主/辅码流切换'
|
|
break;
|
|
case "realSuccess": // 实时预览成功
|
|
console.log("实时预览成功")
|
|
cbMsg = '实时预览成功'
|
|
break;
|
|
case "realError": // 实时预览失败
|
|
console.log("实时预览失败", err)
|
|
cbMsg = '实时预览失败'
|
|
break;
|
|
case "talkError": // 对讲失败
|
|
console.log("对讲失败");
|
|
cbMsg = '对讲失败'
|
|
break;
|
|
// 以下是录像回放扩充的回调
|
|
case 'recordSuccess': // 录像回放成功
|
|
console.log("录像回放成功")
|
|
cbMsg = '录像回放成功'
|
|
break;
|
|
case 'recordError': // 录像回放失败
|
|
console.log("录像回放失败", err)
|
|
cbMsg = '录像回放失败'
|
|
break;
|
|
case 'recordFinish': // 录像回放完成
|
|
console.log("录像回放完成")
|
|
cbMsg = '录像回放完成'
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
// 音视频的回调不打印
|
|
if (!['getVideoFrameInfo', 'getAudioFrameInfo'].includes(methods)) {
|
|
getDom('#callback-msg').innerHTML = '回调-' + cbMsg
|
|
getDom('#callback-name').innerHTML = methods
|
|
getDom('#callback-view').value = typeof data === 'object' ? JSON.stringify(data) : data
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
initPlayer("ws-real-player")
|
|
|
|
|
|
|
|
|
|
function playReal() {
|
|
let wsURL = getDom('#real-ws').value
|
|
let rtspURL = getDom('#real-rtsp').value
|
|
let streamType = getDom('#stream-type').value - 0
|
|
let channelId = getDom('#real-channelId').value
|
|
player[playerType].realByUrl({
|
|
rtspURL, // 必传
|
|
wsURL, // 必传
|
|
selectIndex, // 播放窗口号
|
|
channelId, // 必传, 通道id
|
|
streamType, // 必传, 码流类型,
|
|
playerAdapter: 'stretching', // 选传, selfAdaption 自适应 | stretching 拉伸
|
|
channelData: { // 建议传, 通道树信息
|
|
// id: channelCode, // {String} 通道编码
|
|
// deviceCode: deviceCode, // {String} 设备编码
|
|
// deviceType: deviceType, // {String} 设备类型
|
|
// channelSeq: channelSeq, // {String|Number} 通道序号
|
|
},
|
|
})
|
|
}
|
|
|
|
// 流地址方式对讲
|
|
function startTalk() {
|
|
let wsURL = getDom('#real-ws').value
|
|
let rtspURL = getDom('#talk-rtsp').value
|
|
let channelId = getDom('#real-channelId').value
|
|
let audioType = getDom('#audioType').value
|
|
let gbDevice = getDom('#gbDevice').value
|
|
player[playerType].talkByUrl({
|
|
selectIndex,
|
|
rtspURL,
|
|
wsURL,
|
|
audioType,
|
|
channelId,
|
|
gbDevice: Boolean(Number(gbDevice))
|
|
})
|
|
}
|
|
|
|
// 停止对讲
|
|
function stopTalk() {
|
|
// 此处调用停止对讲接口
|
|
}
|
|
|
|
|
|
// 流地址方式播放录像回放
|
|
const playRecord = () => {
|
|
let wsURL = getDom('#record-ws').value
|
|
let rtspURL = getDom('#record-rtsp').value
|
|
let channelId = getDom('#record-channelId').value
|
|
let records = JSON.parse(getDom('#record-records').value)
|
|
player[playerType].recordByUrl({
|
|
wsURL,
|
|
rtspURL,
|
|
channelId: channelId, // 必传, 通道id
|
|
records: records || [], // 录像列表
|
|
selectIndex: 0, // 必传
|
|
playRecordByTime: true, // 默认不传,拖拽异常时请传入false
|
|
// startTime, // 建议传,不传则会通过records数组中截取, 格式 // new Date().getTime() / 1000 【到秒时间戳】
|
|
// endTime, // 建议传,不传则会通过records数组中截取, 格式 // new Date().getTime() / 1000 【到秒时间戳】
|
|
// playerAdapter: opt.playerAdapter, // 选传, , selfAdaption 自适应 | stretching 拉伸
|
|
// channelData: opt.channelData || {}, // 选传, 通道信息
|
|
})
|
|
}
|
|
|
|
getDom('#real-btn').addEventListener('click', () => {
|
|
playReal()
|
|
})
|
|
getDom('#talk-btn').addEventListener('click', () => {
|
|
startTalk()
|
|
})
|
|
getDom('#record-btn').addEventListener('click', () => {
|
|
playRecord()
|
|
})
|
|
// 切换播放
|
|
getDom('#btnradio1').addEventListener('click', function () {
|
|
if (playerType === 'realPlayer') return
|
|
playerType = 'realPlayer'
|
|
getDom("#ws-record-player").style.visibility = 'hidden'
|
|
getDom("#ws-record-player").style.height = 0
|
|
getDom("#ws-real-player").style.display = 'block'
|
|
initPlayer('ws-real-player')
|
|
getDom('.record-container').style.display = 'none'
|
|
getDom('.real-container').style.display = 'block'
|
|
getDom('.record-option-container').style.display = 'none'
|
|
// 在这里添加你的处理逻辑
|
|
});
|
|
|
|
// 切换播放
|
|
getDom('#btnradio2').addEventListener('click', function () {
|
|
if (playerType === 'recordPlayer') return
|
|
getDom("#ws-real-player").style.display = 'none'
|
|
getDom("#ws-record-player").style.visibility = 'visible'
|
|
getDom("#ws-record-player").style.height = '600px'
|
|
playerType = 'recordPlayer'
|
|
initPlayer('ws-record-player')
|
|
getDom('.real-container').style.display = 'none'
|
|
getDom('.record-container').style.display = 'block'
|
|
getDom('.record-option-container').style.display = 'block'
|
|
// 在这里添加你的处理逻辑
|
|
});
|
|
|
|
["setPlayerNum", "setSelectIndex", "showMsgInWindow", 'playSpeed'].forEach(id => {
|
|
getDom(`#${id}`).addEventListener('change', function (e) {
|
|
switch (id) {
|
|
case "setPlayerNum":
|
|
if (this.value > 25) {
|
|
this.value = 25
|
|
}
|
|
setAPiMsg(id, `${playerType}.${id}(${this.value})`, `支持数字传入,也支持自定义格式,需要通过windowNumChanged回调监听到json字符串传入,即可自定义窗口`)
|
|
player[playerType][id](Number(this.value))
|
|
break;
|
|
case "setSelectIndex":
|
|
setAPiMsg(id, `${playerType}.${id}(${selectIndex})`, `选中窗口, 只能小于等于初始化时配置的maxNum的大小,`)
|
|
selectIndex = Number(this.value)
|
|
player[playerType][id](Number(this.value))
|
|
break;
|
|
case "showMsgInWindow":
|
|
setAPiMsg(id, `${playerType}.${id}(${selectIndex}, "${this.value}")`, `在当前选中窗口上显示自定义文字。接收两个参数,\n第一个表示当前的窗口索引, \n第二个表示自定义的文字信息`)
|
|
player[playerType][id](selectIndex, this.value)
|
|
break;
|
|
case "playSpeed":
|
|
setAPiMsg(id, `${playerType}.${id}(${this.value}, ${selectIndex})`, `播放速度,支持数字传入, 接收两个参数, \n 第一个表示倍速数字, 只支持 0.125 0.25 0.5 1 1.25 1.5 2 4 8 共7种速率传入 \n 第二个参数表示当前的窗口索引`)
|
|
player[playerType][id](Number(this.value), selectIndex)
|
|
}
|
|
})
|
|
})
|
|
|
|
let apiMsg = ''
|
|
let arr = [
|
|
'setFullScreen',
|
|
'setExitFullScreen',
|
|
'setIvs-show',
|
|
'setIvs-hide',
|
|
'openVolume',
|
|
'closeVolume',
|
|
'close',
|
|
'setPlayerAdapter-selfAdaption',
|
|
'setPlayerAdapter-stretching',
|
|
'picCap',
|
|
'startLocalRecord',
|
|
'stopLocalRecord',
|
|
"pause",
|
|
"play"
|
|
]
|
|
arr.forEach(id => {
|
|
getDom(`#${id}`).addEventListener('click', e => {
|
|
switch (id) {
|
|
case 'setFullScreen':
|
|
player[playerType] && setAPiMsg(id, `${playerType}.${id}()`, `窗口全屏`)
|
|
player[playerType] && player[playerType][id]()
|
|
break;
|
|
case 'setExitFullScreen':
|
|
player[playerType] && setAPiMsg(id, `${playerType}.${id}()`, `退出窗口全屏`)
|
|
player[playerType] && player[playerType][id]()
|
|
break;
|
|
case 'setSelectIndex':
|
|
player[playerType] && player[playerType][id](selectIndex)
|
|
setAPiMsg(id, `${playerType}.${id}(${selectIndex})`, `选中窗口, 只能小于等于初始化时配置的maxNum的大小,`)
|
|
break;
|
|
case 'setIvs-show':
|
|
setAPiMsg('setIvs', `${playerType}.setIvs(true, ${selectIndex}), [1, 2]`, `接收三个参数,\n第一个表示开启ivs, \n第二个表示窗口号,\n第三个表示ivs类型数组, [1] 表示只显示规则线 [2] 表示只显示目标框, \n`)
|
|
// API调用
|
|
player[playerType] && player[playerType].setIvs(true, selectIndex, [1, 2])
|
|
break;
|
|
case 'setIvs-hide':
|
|
setAPiMsg('setIvs', `${playerType}.setIvs(false, ${selectIndex}), [1, 2]`, `接收三个参数,\n第一个表示关闭ivs, \n第二个表示窗口号,\n第三个默认可不传,表示ivs类型数组, [1] 表示只显示规则线 [2] 表示只显示目标框, \n`)
|
|
// API调用
|
|
player[playerType] && player[playerType].setIvs(false, selectIndex, [1, 2])
|
|
break;
|
|
case 'openVolume':
|
|
setAPiMsg(id, `${playerType}.${id}(${selectIndex})`, '开启音量, 接收一个参数,表示窗口号')
|
|
player[playerType] && player[playerType][`${id}`](selectIndex)
|
|
break;
|
|
case 'closeVolume':
|
|
setAPiMsg(id, `${playerType}.${id}(${selectIndex})`, '关闭音量, 接收一个参数,表示窗口号')
|
|
player[playerType] && player[playerType][`${id}`](selectIndex)
|
|
break;
|
|
case 'close':
|
|
setAPiMsg(id, `${playerType}.${id}(${selectIndex})`, '关闭视频, 接收一个参数,表示窗口号, 如果不传参数则关闭所有窗口')
|
|
// API调用
|
|
player[playerType] && player[playerType][`${id}`](selectIndex)
|
|
break;
|
|
case 'setPlayerAdapter-selfAdaption':
|
|
setAPiMsg('setPlayerAdapter', `${playerType}.setPlayerAdapter("selfAdaption")`, '设置当前窗口为自适应窗口')
|
|
player[playerType] && player[playerType][id.split('-')[0]](id.split('-')[1])
|
|
break;
|
|
case 'setPlayerAdapter-stretching':
|
|
setAPiMsg('setPlayerAdapter', `${playerType}.setPlayerAdapter("stretching")`, '设置当前窗口为拉伸窗口')
|
|
// API调用
|
|
player[playerType] && player[playerType][id.split('-')[0]](id.split('-')[1])
|
|
break;
|
|
case 'picCap':
|
|
apiMsg = '截图: 该方法接收两个参数,第一个表示窗口号,第二个表示截图名称, 会自动拼接.png后缀'
|
|
setAPiMsg(id, `${playerType}.${id}(${selectIndex}, "抓图名称")`, apiMsg)
|
|
player[playerType] && player[playerType][id](selectIndex, '抓图名称')
|
|
break;
|
|
case 'startLocalRecord':
|
|
apiMsg = '开始本地录制:该方法接收四个参数\n第一个表示窗口号,\n第二个表示录制名称(不加后缀), \n第三个表示录制大小, 单位M, \n第四个表示是否下载mp4文件 true-下载mp4, false-下载dav, \n'
|
|
setAPiMsg(id, `${playerType}.${id}(${selectIndex}, "录制名称", 100, true)`, apiMsg)
|
|
player[playerType] && player[playerType][id](selectIndex, '录制名称', 100, true)
|
|
break;
|
|
case 'stopLocalRecord':
|
|
apiMsg = '停止本地录制:该方法接收一个参数,表示窗口号'
|
|
setAPiMsg(id, `${playerType}.${id}(${selectIndex}`, apiMsg)
|
|
player[playerType] && player[playerType][id](selectIndex)
|
|
break;
|
|
case "pause":
|
|
setAPiMsg(id, `${playerType}.${id}(${selectIndex}`, '暂停播放, 接收一个参数,表示窗口号')
|
|
player[playerType] && player[playerType][id](selectIndex)
|
|
case "play":
|
|
setAPiMsg(id, `${playerType}.${id}(${selectIndex}`, '继续播放, 接收一个参数,表示窗口号')
|
|
player[playerType] && player[playerType][id](selectIndex)
|
|
default:
|
|
break;
|
|
}
|
|
})
|
|
});
|
|
|
|
function setAPiMsg(name, api, msg) {
|
|
getDom('#api-name').innerHTML = "API-" + name
|
|
getDom('#api-api').innerHTML = api
|
|
getDom('#api-msg').value = msg
|
|
}
|
|
let dom = document.querySelectorAll('.accordion-button')
|
|
for (var i = 0; i < dom.length; i++) {
|
|
dom[i].addEventListener('click', function (e) {
|
|
let dom = getDom(e.target.dataset.bsTarget)
|
|
dom.classList.toggle('show')
|
|
this.classList.toggle('collapsed')
|
|
})
|
|
}
|
|
|
|
// 一键生成icc联调环境信息
|
|
getDom('#open-icc-info').addEventListener('click', (e) => {
|
|
wsplayerParam = {
|
|
ip: '124.160.33.135',
|
|
platform: '4077',
|
|
realPort: isHttp ? '4079' : '4081',
|
|
recordPort: isHttp ? '4080' : '4082',
|
|
real_wsUrl: `${isHttp ? 'ws': 'wss'}://124.160.33.135:${isHttp ? '4079' : '4081'}`, // 实时预览ws地址
|
|
record_wsUrl: `${isHttp ? 'ws': 'wss'}://124.160.33.135:${isHttp ? '4080' : '4082'}`
|
|
}
|
|
ipDom.value = wsplayerParam.ip
|
|
platformDom.value = wsplayerParam.platform
|
|
realPortDom.value = wsplayerParam.realPort
|
|
recordPortDom.value = wsplayerParam.recordPort
|
|
localStorage.wsplayerParam = JSON.stringify(wsplayerParam)
|
|
renderDom()
|
|
})
|
|
// 生成拉流socket信息
|
|
getDom('#submit-platform').addEventListener('click', (e) => {
|
|
wsplayerParam = {
|
|
ip: ipDom.value,
|
|
platform: platformDom.value,
|
|
realPort: realPortDom.value,
|
|
recordPort: recordPortDom.value,
|
|
real_wsUrl: `${isHttp ? 'ws://': 'wss://'}${ipDom.value}:${realPortDom.value}`, // 实时预览ws地址
|
|
record_wsUrl: `${isHttp ? 'ws://': 'wss://'}${ipDom.value}:${recordPortDom.value}`
|
|
}
|
|
localStorage.wsplayerParam = JSON.stringify(wsplayerParam)
|
|
renderDom()
|
|
})
|
|
function renderDom() {
|
|
getDom('#real-ws').value = wsplayerParam.real_wsUrl
|
|
getDom('#record-ws').value = wsplayerParam.record_wsUrl
|
|
!isHttp && (getDom('#certificate-message').innerHTML = `如果平台未配置证书,请先临时访问 <a target="_blank" href="${window.location.protocol}//${ipDom.value}:${realPortDom.value}" >${window.location.protocol}//${ipDom.value}:${realPortDom.value}</a> 浏览器安全访问该地址,否则无法拉流`)
|
|
}
|
|
|
|
getDom('#notify').innerHTML = window.location.protocol === 'http:' ? `注:当前是${window.location.protocol}服务, 如果你是集成在 https 项目中,请 启动 node https.cjs 进行查看` : `注:当前是${window.location.protocol}服务, 如果你是集成在 http 项目中,请 启动 node http.cjs 进行查看。 https服务,需要在大华的平台上配置https证书,否则无法拉流<a href="https://open-icc.dahuatech.com/iccdoc/openfaq/wiki/iccfaq/question/admin.html#WSPlayer%E6%8B%89%E6%B5%81wss%E9%85%8D%E7%BD%AE%EF%BC%9B%E8%A7%86%E9%A2%91%E5%BA%94%E7%94%A8"" target="_blank">跳转到证书说明</a>`
|
|
// getDom('.btn-close').addEventListener('click', () => {
|
|
// getDom('.alert-dismissible').style.display = 'none'
|
|
// })
|
|
getDom('#real_port_label').innerHTML = window.location.protocol + '实时预览拉流端口:'
|
|
getDom('#record_port_label').innerHTML = window.location.protocol + '录像回放拉流端口:'
|
|
if(isHttp) {
|
|
getDom('#talk-rtsp').disabled = true
|
|
getDom('#audioType').disabled = true
|
|
getDom('#gbDevice').disabled = true
|
|
}
|
|
</script>
|
|
|
|
</html> |