fix:播放器使用ezuikit.js、报警逻辑处理
This commit is contained in:
371
src/static/html/1ezviz-iframe.html
Normal file
371
src/static/html/1ezviz-iframe.html
Normal file
@ -0,0 +1,371 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<title>萤石云播放器</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
/* background: #1a1a1a; */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#player-iframe {
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
border: none;
|
||||
display: block;
|
||||
object-fit: contain; /* 保持视频比例,不变形 */
|
||||
}
|
||||
|
||||
/* 简化的控制按钮样式 */
|
||||
.control-buttons {
|
||||
position: fixed;
|
||||
bottom: 30px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
z-index: 999;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.control-btn {
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
border-radius: 25px;
|
||||
padding: 12px 20px;
|
||||
min-width: 100px;
|
||||
min-height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.control-btn:active {
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.play-btn {
|
||||
background: rgba(76, 175, 80, 0.8);
|
||||
border-color: rgba(76, 175, 80, 0.9);
|
||||
}
|
||||
|
||||
.play-btn:active {
|
||||
background: rgba(76, 175, 80, 0.9);
|
||||
}
|
||||
|
||||
.refresh-btn {
|
||||
background: rgba(33, 150, 243, 0.8);
|
||||
border-color: rgba(33, 150, 243, 0.9);
|
||||
}
|
||||
|
||||
.refresh-btn:active {
|
||||
background: rgba(33, 150, 243, 0.9);
|
||||
}
|
||||
|
||||
/* 按钮图标样式 */
|
||||
.btn-icon {
|
||||
margin-right: 6px;
|
||||
font-size: 16px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.loading {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
padding: 15px 30px;
|
||||
border-radius: 8px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.loading::after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 10px auto 0;
|
||||
border: 3px solid rgba(255, 255, 255, 0.3);
|
||||
border-top-color: white;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* 简化的暂停占位符样式 */
|
||||
.pause-placeholder {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
background: #000000;
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.pause-content {
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.pause-title {
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="loading" id="loading">正在加载播放器...</div>
|
||||
<iframe id="player-iframe" allow="autoplay; fullscreen"></iframe>
|
||||
|
||||
<!-- 暂停时的占位符 -->
|
||||
<div class="pause-placeholder" id="pause-placeholder">
|
||||
<div class="pause-content">
|
||||
<div class="pause-title">监控已暂停</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 控制按钮 -->
|
||||
<div class="control-buttons" id="control-buttons" style="display: none;">
|
||||
<div class="control-btn play-btn" id="play-btn">
|
||||
<span class="btn-icon" id="play-icon">▶️</span>
|
||||
<span class="btn-text" id="play-text">播放</span>
|
||||
</div>
|
||||
<div class="control-btn refresh-btn" id="refresh-btn">
|
||||
<span class="btn-icon">🔄</span>
|
||||
<span class="btn-text">刷新</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function log(message) {
|
||||
console.log('[iframe播放器] ' + message);
|
||||
}
|
||||
|
||||
// 从URL参数获取配置
|
||||
function getConfig() {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
return {
|
||||
accessToken: params.get('accessToken'),
|
||||
playUrl: params.get('playUrl')
|
||||
};
|
||||
}
|
||||
|
||||
// 初始化播放器
|
||||
function init() {
|
||||
log('初始化开始');
|
||||
|
||||
const configData = getConfig();
|
||||
|
||||
if (!configData.accessToken || !configData.playUrl) {
|
||||
log('配置参数不完整');
|
||||
document.getElementById('loading').textContent = '配置参数错误';
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存配置到全局变量
|
||||
config = {
|
||||
accessToken: configData.accessToken,
|
||||
playUrl: configData.playUrl
|
||||
};
|
||||
|
||||
log('AccessToken: ' + config.accessToken.substring(0, 20) + '...');
|
||||
log('PlayUrl: ' + config.playUrl);
|
||||
|
||||
try {
|
||||
// 使用萤石云官方iframe播放器(内存占用小)
|
||||
const iframeUrl = 'https://open.ys7.com/ezopen/h5/iframe?' +
|
||||
'url=' + encodeURIComponent(config.playUrl) +
|
||||
'&accessToken=' + encodeURIComponent(config.accessToken) +
|
||||
'&width=100%' +
|
||||
'&height=100%' +
|
||||
'&autoplay=1' +
|
||||
'&audio=1' +
|
||||
'&controls=1';
|
||||
|
||||
log('iframe URL: ' + iframeUrl);
|
||||
|
||||
const iframe = document.getElementById('player-iframe');
|
||||
iframe.src = iframeUrl;
|
||||
|
||||
// 设置初始播放状态
|
||||
isPlaying = true;
|
||||
document.getElementById('play-text').textContent = '暂停';
|
||||
document.getElementById('play-icon').textContent = '⏸️';
|
||||
|
||||
// 隐藏loading,显示控制按钮
|
||||
setTimeout(() => {
|
||||
document.getElementById('loading').style.display = 'none';
|
||||
document.getElementById('control-buttons').style.display = 'flex';
|
||||
log('播放器加载完成,显示控制按钮');
|
||||
}, 2000);
|
||||
|
||||
} catch (error) {
|
||||
log('初始化失败: ' + error.message);
|
||||
document.getElementById('loading').textContent = '初始化失败';
|
||||
}
|
||||
}
|
||||
|
||||
// 全局状态
|
||||
let isPlaying = true;
|
||||
let config = null;
|
||||
|
||||
// 播放/暂停控制
|
||||
function togglePlay() {
|
||||
log('切换播放状态: ' + (isPlaying ? '暂停' : '播放'));
|
||||
|
||||
const iframe = document.getElementById('player-iframe');
|
||||
const playText = document.getElementById('play-text');
|
||||
const playIcon = document.getElementById('play-icon');
|
||||
const pausePlaceholder = document.getElementById('pause-placeholder');
|
||||
|
||||
if (isPlaying) {
|
||||
// 暂停:清空iframe,显示占位符
|
||||
iframe.src = 'about:blank';
|
||||
pausePlaceholder.style.display = 'flex';
|
||||
playText.textContent = '播放';
|
||||
playIcon.textContent = '▶️';
|
||||
isPlaying = false;
|
||||
log('已暂停播放,显示占位符');
|
||||
} else {
|
||||
// 播放:重新设置iframe URL,隐藏占位符
|
||||
if (config) {
|
||||
const iframeUrl = 'https://open.ys7.com/ezopen/h5/iframe?' +
|
||||
'url=' + encodeURIComponent(config.playUrl) +
|
||||
'&accessToken=' + encodeURIComponent(config.accessToken) +
|
||||
'&width=100%' +
|
||||
'&height=100%' +
|
||||
'&autoplay=1' +
|
||||
'&audio=1' +
|
||||
'&controls=1';
|
||||
|
||||
iframe.src = iframeUrl;
|
||||
pausePlaceholder.style.display = 'none';
|
||||
playText.textContent = '暂停';
|
||||
playIcon.textContent = '⏸️';
|
||||
isPlaying = true;
|
||||
log('已开始播放,隐藏占位符');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 刷新播放器
|
||||
function refreshPlayer() {
|
||||
log('刷新播放器');
|
||||
|
||||
const iframe = document.getElementById('player-iframe');
|
||||
const playText = document.getElementById('play-text');
|
||||
const playIcon = document.getElementById('play-icon');
|
||||
const pausePlaceholder = document.getElementById('pause-placeholder');
|
||||
|
||||
// 先清空,显示加载状态
|
||||
iframe.src = 'about:blank';
|
||||
pausePlaceholder.style.display = 'none';
|
||||
|
||||
// 延迟重新加载
|
||||
setTimeout(() => {
|
||||
if (config) {
|
||||
const iframeUrl = 'https://open.ys7.com/ezopen/h5/iframe?' +
|
||||
'url=' + encodeURIComponent(config.playUrl) +
|
||||
'&accessToken=' + encodeURIComponent(config.accessToken) +
|
||||
'&width=100%' +
|
||||
'&height=100%' +
|
||||
'&autoplay=1' +
|
||||
'&audio=1' +
|
||||
'&controls=1';
|
||||
|
||||
iframe.src = iframeUrl;
|
||||
playText.textContent = '暂停';
|
||||
playIcon.textContent = '⏸️';
|
||||
isPlaying = true;
|
||||
log('刷新完成');
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// 页面加载完成后初始化
|
||||
window.onload = function() {
|
||||
log('页面加载完成');
|
||||
|
||||
// 绑定按钮事件
|
||||
document.getElementById('play-btn').addEventListener('click', togglePlay);
|
||||
document.getElementById('refresh-btn').addEventListener('click', refreshPlayer);
|
||||
|
||||
init();
|
||||
};
|
||||
|
||||
// 页面卸载时清理资源
|
||||
window.onbeforeunload = function() {
|
||||
log('页面即将卸载,清理播放器资源');
|
||||
try {
|
||||
const iframe = document.getElementById('player-iframe');
|
||||
if (iframe) {
|
||||
iframe.src = 'about:blank'; // 清空iframe源
|
||||
log('播放器资源已清理');
|
||||
}
|
||||
} catch (error) {
|
||||
log('清理播放器资源失败: ' + error.message);
|
||||
}
|
||||
};
|
||||
|
||||
// 页面隐藏时暂停播放
|
||||
document.addEventListener('visibilitychange', function() {
|
||||
if (document.hidden) {
|
||||
log('页面隐藏,暂停播放');
|
||||
try {
|
||||
const iframe = document.getElementById('player-iframe');
|
||||
if (iframe) {
|
||||
iframe.style.display = 'none';
|
||||
}
|
||||
} catch (error) {
|
||||
log('暂停播放失败: ' + error.message);
|
||||
}
|
||||
} else {
|
||||
log('页面显示,恢复播放');
|
||||
try {
|
||||
const iframe = document.getElementById('player-iframe');
|
||||
if (iframe) {
|
||||
iframe.style.display = 'block';
|
||||
}
|
||||
} catch (error) {
|
||||
log('恢复播放失败: ' + error.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
143
src/static/html/ezuikit.js
Normal file
143
src/static/html/ezuikit.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -0,0 +1 @@
|
||||
"use strict";var Module={};var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason??e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}JSPlayerModule(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -0,0 +1 @@
|
||||
"use strict";var Module={};var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason??e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}JSPlayerModule(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage;
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
1257
src/static/html/ezuikit_static/css/component.css
Normal file
1257
src/static/html/ezuikit_static/css/component.css
Normal file
File diff suppressed because it is too large
Load Diff
354
src/static/html/ezuikit_static/css/inspectTheme.css
Normal file
354
src/static/html/ezuikit_static/css/inspectTheme.css
Normal file
@ -0,0 +1,354 @@
|
||||
.BMap_noprint button[title="倾斜"] {
|
||||
display: none;
|
||||
}
|
||||
.BMap_noprint button[title="恢复"] {
|
||||
display: none;
|
||||
}
|
||||
/* .anchorBL{
|
||||
display:none;
|
||||
} */
|
||||
.BMap_cpyCtrl {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.inspect-event-item {
|
||||
padding-left: 12.5px;
|
||||
position: relative;
|
||||
border-left: 1px solid #d9d9d9;
|
||||
margin-left: 20.5px;
|
||||
padding-bottom: 16px;
|
||||
color: #595959;
|
||||
}
|
||||
|
||||
.inspect-event-item:last-child {
|
||||
border-left: 1px solid transparent;
|
||||
}
|
||||
|
||||
.inspect-event-item-header-wrap {
|
||||
margin-top: -4px;
|
||||
}
|
||||
.inspect-event-item:first-child .inspect-event-item-header-wrap{
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.inspect-event-item-header {
|
||||
width: 240px;
|
||||
height: 32px;
|
||||
background: #F5F5F5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.inspect-event-item-header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 9px;
|
||||
}
|
||||
|
||||
.inspect-event-item-header-right, .inspect-event-item-body-info-opr {
|
||||
padding-right: 8px;
|
||||
}
|
||||
.inspect-event-item-body-info-opr-icon{
|
||||
color: #595959;
|
||||
cursor: pointer;
|
||||
}
|
||||
.inspect-event-item-body-info-opr-icon:hover{
|
||||
color: #407AFF;
|
||||
}
|
||||
.inspect-event-item-header-toggle {
|
||||
width: 16px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
padding: 8px 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.inspect-event-item-time {
|
||||
padding-left: 9px;
|
||||
}
|
||||
|
||||
.inspect-event-item-status-wrap {
|
||||
position: absolute;
|
||||
height: 28px;
|
||||
background: #fff;
|
||||
top: 4px;
|
||||
left: -5.5px;
|
||||
}
|
||||
.inspect-event-item:first-child .inspect-event-item-status-wrap {
|
||||
top: 0;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.inspect-event-item-status {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: #407AFF;
|
||||
border-radius: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.storage .inspect-event-item-status {
|
||||
background: #FAAD14;
|
||||
}
|
||||
|
||||
.storage-error .inspect-event-item-status{
|
||||
background: #FF4D4F;
|
||||
}
|
||||
.storage-error .inspect-event-item-header-left,
|
||||
.storage-error .inspect-event-item-time {
|
||||
color: #FF4D4F;
|
||||
}
|
||||
|
||||
.inspect-event-item-time {
|
||||
font-size: 12px;
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
.inspect-event-item-body {
|
||||
width: 240px;
|
||||
background: #FAFAFA;
|
||||
padding-top: 8px;
|
||||
|
||||
}
|
||||
.inspect-event-item-img {
|
||||
width: 224px;
|
||||
height: 126px;
|
||||
margin: 0 8px;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.inspect-event-item-body-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.inspect-event-item-body-info-tag {
|
||||
max-width: 140px;
|
||||
background: #FFF1F0;
|
||||
border-radius: 2px;
|
||||
text-align: center;
|
||||
margin: 8px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
padding: 0 8px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.inspect-event-item-body-info-tag-label{
|
||||
font-size: 12px;
|
||||
color: #FF4D4F;
|
||||
}
|
||||
|
||||
|
||||
.inspect-event-detail-wrap {
|
||||
width: 0;
|
||||
overflow: auto;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 9;
|
||||
background: #ffffff;
|
||||
transition: width 0.15s ease 0s;
|
||||
}
|
||||
|
||||
.inspect-event-detail-wrap.show {
|
||||
width: 290px;
|
||||
}
|
||||
|
||||
.inspectEventDetail-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16px 16px;
|
||||
}
|
||||
|
||||
.inspectEventDetail-back {
|
||||
fill: #595959;
|
||||
cursor: pointer;
|
||||
margin-right: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.inspectEventDetail-type {
|
||||
height: 22px;
|
||||
font-size: 14px;
|
||||
color: #262626;
|
||||
line-height: 22px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.inspectEventDetail-content {
|
||||
padding: 0 16px 24px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.inspectEventDetail-content-info {
|
||||
font-size: 14px;
|
||||
color: #262626;
|
||||
line-height: 22px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.inspectEventDetail-content-info-item-title {
|
||||
margin: 24px 0 4px;
|
||||
}
|
||||
|
||||
.inspectEventDetail-content-info-item-value {
|
||||
color: #595959;
|
||||
}
|
||||
|
||||
.inspectEventDetail-content-info-item-title-required:before {
|
||||
display: inline-block;
|
||||
margin-right: 4px;
|
||||
color: #ff4d4f;
|
||||
font-size: 14px;
|
||||
font-family: SimSun,sans-serif;
|
||||
line-height: 1;
|
||||
content: "*";
|
||||
}
|
||||
|
||||
.inspectEventDetail-footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: #fff;
|
||||
padding: 16px 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.inspectEventDetail-footer-btn {
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.inspectEventDetail-content-img-tips,
|
||||
.inspectEventDetail-content-video-tips {
|
||||
font-size: 14px;
|
||||
color: #407AFF;
|
||||
line-height: 22px;
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
.inspectEventDetail-content-img-detail,
|
||||
.inspectEventDetail-content-video-detail {
|
||||
display: block;
|
||||
width: 224px;
|
||||
height: 126px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.video-stroage-exceptional-status-tips-wrap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.video-stroage-exceptional-status-icon {
|
||||
font-size: 16px;
|
||||
padding: 40px 0 0px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.video-stroage-exceptional-status-tips-error .video-stroage-exceptional-status-icon{
|
||||
padding: 40px 0 8px;
|
||||
}
|
||||
|
||||
.video-stroage-exceptional-status-tips {
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.inspectEventDetail-content-video-timer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.video-recording-time-wrap {
|
||||
height: 24px;
|
||||
background: #FF5C5C;
|
||||
border-radius: 12px;
|
||||
padding: 0 24px;
|
||||
line-height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.video-recording-time {
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: 0;
|
||||
font-weight: 400;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.inspectEventDetail-stop-btn {
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.inspectEventDetail-delete-confirm,
|
||||
.inspectEventDetail-back-confirm {
|
||||
width: 288px;
|
||||
padding: 12px 8px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.inspectEventDetail-delete-confirm-title,
|
||||
.inspectEventDetail-back-confirm-title {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.inspectEventDetail-delete-confirm-title-label,
|
||||
.inspectEventDetail-back-confirm-title-label {
|
||||
font-size: 16px;
|
||||
color: #262626;
|
||||
line-height: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.inspectEventDetail-delete-confirm-title svg,
|
||||
.inspectEventDetail-back-confirm-title svg {
|
||||
color: #FAAD14 ;
|
||||
margin-right: 16px;
|
||||
}
|
||||
.inspectEventDetail-delete-confirm-btns,
|
||||
.inspectEventDetail-back-confirm-btns {
|
||||
margin: 24px 0 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.inspectEventDetail-delete-confirm-btns .ezuikit-btn,
|
||||
.inspectEventDetail-back-confirm-btns .ezuikit-btn {
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
/* .inspect-event-box及其子元素滚动条效果设置 */
|
||||
|
||||
|
||||
.inspect-event-box::-webkit-scrollbar,
|
||||
.inspect-event-box *::-webkit-scrollbar {
|
||||
width: 10px
|
||||
}
|
||||
|
||||
.inspect-event-box::-webkit-scrollbar-thumb,
|
||||
.inspect-event-box *::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px!important;
|
||||
-webkit-box-shadow: inset 0 0 5px #8C8C8C!important;
|
||||
background: #8C8C8C!important;
|
||||
border: 3px solid #fff!important
|
||||
}
|
||||
|
||||
.inspect-event-box::-webkit-scrollbar-track,
|
||||
.inspect-event-box *::-webkit-scrollbar-track {
|
||||
border-radius: 0
|
||||
}
|
||||
167
src/static/html/ezuikit_static/css/theme.css
Normal file
167
src/static/html/ezuikit_static/css/theme.css
Normal file
@ -0,0 +1,167 @@
|
||||
.footer-controls .theme-icon-item {
|
||||
margin: 0 1%;
|
||||
}
|
||||
|
||||
.footer-controls.themeEditing .theme-icon-item {
|
||||
position: relative;
|
||||
/* margin: 0 8px; */
|
||||
}
|
||||
|
||||
.footer-controls .footer-controls-left {
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.footer-controls.themeEditing .footer-controls-left .theme-icon-item {
|
||||
/* margin-left: 12px; */
|
||||
}
|
||||
|
||||
.footer-controls.themeEditing .footer-controls-right .theme-icon-item {
|
||||
/* margin-right: 12px; */
|
||||
}
|
||||
|
||||
.footer-controls .theme-icon-item .icon-move {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.footer-controls.themeEditing .theme-icon-item:hover .icon-move {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.footer-controls.themeEditing
|
||||
.footer-controls-left
|
||||
.theme-icon-item:first-child
|
||||
.icon-move.left {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.footer-controls.themeEditing
|
||||
.footer-controls-left
|
||||
.theme-icon-item:nth-last-child(1)
|
||||
.icon-move.right {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.footer-controls .footer-controls-right {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.footer-controls.themeEditing
|
||||
.footer-controls-right
|
||||
.theme-icon-item:first-child
|
||||
.icon-move.left {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.footer-controls.themeEditing
|
||||
.footer-controls-right
|
||||
.theme-icon-item:nth-last-child(1)
|
||||
.icon-move.right {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.footer-controls .theme-icon-item-icon {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header-controls .theme-icon-item {
|
||||
margin: 0 1%;
|
||||
}
|
||||
|
||||
.header-controls.themeEditing .theme-icon-item {
|
||||
position: relative;
|
||||
/* margin: 0 8px; */
|
||||
}
|
||||
|
||||
.header-controls.themeEditing .header-controls-left {
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.header-controls.themeEditing .header-controls-right {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.header-controls .theme-icon-item .icon-move {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.header-controls.themeEditing .theme-icon-item:hover .icon-move {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.header-controls.themeEditing
|
||||
.header-controls-left
|
||||
.theme-icon-item:first-child
|
||||
.icon-move.left {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.header-controls.themeEditing
|
||||
.header-controls-left
|
||||
.theme-icon-item:nth-last-child(1)
|
||||
.icon-move.right {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.header-controls.themeEditing
|
||||
.header-controls-right
|
||||
.theme-icon-item:first-child
|
||||
.icon-move.left {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.header-controls.themeEditing
|
||||
.header-controls-right
|
||||
.theme-icon-item:nth-last-child(1)
|
||||
.icon-move.right {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.time-area {
|
||||
position: absolute;
|
||||
color: #ffffff;
|
||||
width: 68px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-radius: 12px;
|
||||
display: none;
|
||||
align-content: center;
|
||||
left: calc(50% - 34px);
|
||||
top: -30px;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
padding-left: 4px;
|
||||
padding-right: 6px;
|
||||
z-index: 9999999;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.time-area .dot {
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: red;
|
||||
border-radius: 100%;
|
||||
margin: 0 4px 1px 4px;
|
||||
}
|
||||
|
||||
/* .footer-controls.themeEditing .theme-icon-item {
|
||||
position: relative;
|
||||
margin: 0 8px;
|
||||
}
|
||||
.footer-controls.themeEditing .footer-controls-left .theme-icon-item:nth-child(1) .ezuikit-theme-icon >span:first-child{
|
||||
display: none!important;
|
||||
}
|
||||
.footer-controls.themeEditing .footer-controls-left .theme-icon-item:nth-last-child(2) .ezuikit-theme-icon >span:nth-child(3){
|
||||
display: none!important;
|
||||
}
|
||||
|
||||
.footer-controls.themeEditing .theme-icon-item:hover .ezuikit-theme-icon {
|
||||
display: block!important;
|
||||
}
|
||||
.footer-controls.themeEditing .footer-controls-right .theme-icon-item:nth-child(1) .ezuikit-theme-icon >span:first-child{
|
||||
display: none!important;
|
||||
}
|
||||
.footer-controls.themeEditing .footer-controls-right .theme-icon-item:nth-last-child(1) .ezuikit-theme-icon >span:nth-child(3){
|
||||
display: none!important;
|
||||
} */
|
||||
BIN
src/static/html/ezuikit_static/imgs/bg.png
Normal file
BIN
src/static/html/ezuikit_static/imgs/bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
33
src/static/html/ezuikit_static/imgs/bg.svg
Normal file
33
src/static/html/ezuikit_static/imgs/bg.svg
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="1920px" height="1080px" viewBox="0 0 1920 1080" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>视频背景图</title>
|
||||
<defs>
|
||||
<rect id="path-1" x="0" y="0" width="1920" height="1080"></rect>
|
||||
<filter x="0.0%" y="0.0%" width="100.0%" height="100.0%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feGaussianBlur stdDeviation="0" in="SourceGraphic"></feGaussianBlur>
|
||||
</filter>
|
||||
<linearGradient x1="6.42733681%" y1="61.4046072%" x2="84.9937231%" y2="19.1492851%" id="linearGradient-4">
|
||||
<stop stop-color="#9DC2FE" stop-opacity="0" offset="0%"></stop>
|
||||
<stop stop-color="#648FFC" stop-opacity="0.129889642" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="91.8908498%" y1="82.8715916%" x2="45.1536245%" y2="-4.31442764%" id="linearGradient-5">
|
||||
<stop stop-color="#9DC2FE" stop-opacity="0" offset="0%"></stop>
|
||||
<stop stop-color="#648FFC" stop-opacity="0.129889642" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="94.5535203%" y1="72.2238976%" x2="-8.96417241%" y2="9.01768502%" id="linearGradient-6">
|
||||
<stop stop-color="#9DC2FE" stop-opacity="0" offset="0%"></stop>
|
||||
<stop stop-color="#648FFC" stop-opacity="0.129889642" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Cam-Thumbnail">
|
||||
<mask id="mask-3" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<use id="Cam-Mask" fill="#18191C" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<circle id="椭圆形" fill="url(#linearGradient-4)" mask="url(#mask-3)" cx="1868.8" cy="870.4" r="394.24"></circle>
|
||||
<circle id="椭圆形备份-2" fill="url(#linearGradient-5)" mask="url(#mask-3)" cx="0" cy="143.36" r="394.24"></circle>
|
||||
<ellipse id="椭圆形备份-3" fill-opacity="0.45" fill="url(#linearGradient-6)" mask="url(#mask-3)" cx="427.52" cy="350.72" rx="161.28" ry="158.72"></ellipse>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
BIN
src/static/html/ezuikit_static/imgs/empty.png
Normal file
BIN
src/static/html/ezuikit_static/imgs/empty.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
BIN
src/static/html/ezuikit_static/imgs/end.png
Normal file
BIN
src/static/html/ezuikit_static/imgs/end.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
52
src/static/html/ezuikit_static/imgs/fallback.svg
Normal file
52
src/static/html/ezuikit_static/imgs/fallback.svg
Normal file
@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 225 126" style="enable-background:new 0 0 225 126;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#F5F5F5;}
|
||||
.st1{filter:url(#Adobe_OpacityMaskFilter);}
|
||||
.st2{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
|
||||
.st3{mask:url(#mask-2_1_);}
|
||||
.st4{fill:#BFBFBF;}
|
||||
.st5{filter:url(#Adobe_OpacityMaskFilter_1_);}
|
||||
.st6{mask:url(#mask-2_2_);}
|
||||
</style>
|
||||
<title>加载失败@3x</title>
|
||||
<rect x="0.7" class="st0" width="224" height="126"/>
|
||||
<defs>
|
||||
<filter id="Adobe_OpacityMaskFilter" filterUnits="userSpaceOnUse" x="95.1" y="48.4" width="18.7" height="29.2">
|
||||
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<mask maskUnits="userSpaceOnUse" x="95.1" y="48.4" width="18.7" height="29.2" id="mask-2_1_">
|
||||
<g class="st1">
|
||||
<rect id="path-1_1_" x="0.7" class="st2" width="224" height="126"/>
|
||||
</g>
|
||||
</mask>
|
||||
<g class="st3">
|
||||
<g id="形状结合" transform="translate(94.326510, 48.000000)">
|
||||
<path class="st4" d="M16.7,0.4c0.1,0,0.2,0,0.2,0l-0.6,2.5L5,2.9c-0.9,0-1.7,0.7-1.7,1.6l0,0.1v12.5l6.4-4.5c1-0.7,2.3-0.7,3.3,0
|
||||
l0.2,0.1l6.4,5l-0.8,2.6l-7.1-5.6c-0.1-0.1-0.3-0.1-0.4-0.1l-0.1,0l-7.8,5.5v5.2c0,0.9,0.7,1.6,1.6,1.7l0.2,0l11.7,0l-0.7,2.5
|
||||
L5,29.6c-2.3,0-4.1-1.8-4.2-4l0-0.2V4.6c0-2.3,1.8-4.1,4-4.2l0.2,0H16.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="Adobe_OpacityMaskFilter_1_" filterUnits="userSpaceOnUse" x="112.8" y="48.4" width="17.3" height="29.2">
|
||||
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<mask maskUnits="userSpaceOnUse" x="112.8" y="48.4" width="17.3" height="29.2" id="mask-2_2_">
|
||||
<g class="st5">
|
||||
<rect id="path-1_2_" x="0.7" class="st2" width="224" height="126"/>
|
||||
</g>
|
||||
</mask>
|
||||
<g class="st6">
|
||||
|
||||
<g transform="translate(121.479530, 63.000000) rotate(-360.000000) translate(-121.479530, -63.000000) translate(111.979530, 48.000000)">
|
||||
<path class="st4" d="M13.9,0.4c2.3,0,4.1,1.8,4.2,4l0,0.2v20.7c0,2.3-1.8,4.1-4,4.2l-0.2,0l-13.1,0l0.7-2.5l12.3,0
|
||||
c0.9,0,1.7-0.7,1.7-1.6l0-0.1V4.6c0-0.9-0.8-1.7-1.8-1.7l-12.6,0l0.6-2.5L13.9,0.4z M4.4,17.7l6.8,5.3c0.5,0.4,0.6,1.2,0.2,1.8
|
||||
c-0.4,0.5-1.1,0.6-1.6,0.3L9.6,25l-6-4.7L4.4,17.7z M8.6,5.4c2.5,0,4.6,2.1,4.6,4.6s-2.1,4.6-4.6,4.6S4,12.5,4,10S6,5.4,8.6,5.4z
|
||||
M8.6,7.9c-1.2,0-2.1,0.9-2.1,2.1s0.9,2.1,2.1,2.1c1.2,0,2.1-0.9,2.1-2.1S9.7,7.9,8.6,7.9z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
BIN
src/static/html/ezuikit_static/imgs/start.png
Normal file
BIN
src/static/html/ezuikit_static/imgs/start.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
19
src/static/html/ezuikit_static/rec/datepicker.en-US.js
Normal file
19
src/static/html/ezuikit_static/rec/datepicker.en-US.js
Normal file
@ -0,0 +1,19 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) :
|
||||
typeof define === 'function' && define.amd ? define(['jquery'], factory) :
|
||||
(factory(global.jQuery));
|
||||
}(this, (function ($) {
|
||||
'use strict';
|
||||
|
||||
$.fn.datepicker.languages['en-US'] = {
|
||||
format: 'yyyy-mm-dd',
|
||||
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
|
||||
daysShort: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
|
||||
daysMin: ['Su', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
||||
months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||||
monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||||
weekStart: 1,
|
||||
yearFirst: true,
|
||||
yearSuffix: ''
|
||||
};
|
||||
})));
|
||||
1523
src/static/html/ezuikit_static/rec/datepicker.js
Normal file
1523
src/static/html/ezuikit_static/rec/datepicker.js
Normal file
File diff suppressed because it is too large
Load Diff
36
src/static/html/ezuikit_static/rec/datepicker.min.css
vendored
Normal file
36
src/static/html/ezuikit_static/rec/datepicker.min.css
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/*!
|
||||
* Datepicker v1.0.10
|
||||
* https://fengyuanchen.github.io/datepicker
|
||||
*
|
||||
* Copyright 2014-present Chen Fengyuan
|
||||
* Released under the MIT license
|
||||
*
|
||||
* Date: 2020-09-29T14:46:09.037Z
|
||||
*/
|
||||
.datepicker-container{background-color:#fff;direction:ltr;font-size:12px;left:0;line-height:30px;position:fixed;-webkit-tap-highlight-color:transparent;top:0;-ms-touch-action:none;touch-action:none;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:210px;z-index:-1}.datepicker-container:after,.datepicker-container:before{border:5px solid transparent;content:" ";display:block;height:0;position:absolute;width:0}.datepicker-dropdown{border:1px solid #ccc;-webkit-box-shadow:0 3px 6px #ccc;box-shadow:0 3px 6px #ccc;-webkit-box-sizing:content-box;box-sizing:content-box;position:absolute;z-index:1}.datepicker-inline{position:static}.datepicker-top-left,.datepicker-top-right{border-top-color:#39f}.datepicker-top-left:after,.datepicker-top-left:before,.datepicker-top-right:after,.datepicker-top-right:before{border-top:0;left:10px;top:-5px}.datepicker-top-left:before,.datepicker-top-right:before{border-bottom-color:#39f}.datepicker-top-left:after,.datepicker-top-right:after{border-bottom-color:#fff;top:-4px}.datepicker-bottom-left,.datepicker-bottom-right{border-bottom-color:#39f}.datepicker-bottom-left:after,.datepicker-bottom-left:before,.datepicker-bottom-right:after,.datepicker-bottom-right:before{border-bottom:0;bottom:-5px;left:10px}.datepicker-bottom-left:before,.datepicker-bottom-right:before{border-top-color:#39f}.datepicker-bottom-left:after,.datepicker-bottom-right:after{border-top-color:#fff;bottom:-4px}.datepicker-bottom-right:after,.datepicker-bottom-right:before,.datepicker-top-right:after,.datepicker-top-right:before{left:auto;right:10px}.datepicker-panel>ul{margin:0;padding:0;width:102%}.datepicker-panel>ul:after,.datepicker-panel>ul:before{content:" ";display:table}.datepicker-panel>ul:after{clear:both}.datepicker-panel>ul>li{background-color:#fff;cursor:pointer;float:left;height:30px;list-style:none;margin:0;padding:0;text-align:center;width:30px}.datepicker-panel>ul>li:hover{background-color:#e5f2ff}.datepicker-panel>ul>li.muted,.datepicker-panel>ul>li.muted:hover{color:#999}.datepicker-panel>ul>li.highlighted{background-color:#e5f2ff}.datepicker-panel>ul>li.highlighted:hover{background-color:#cce5ff}.datepicker-panel>ul>li.picked,.datepicker-panel>ul>li.picked:hover{color:#39f}.datepicker-panel>ul>li.disabled,.datepicker-panel>ul>li.disabled:hover{background-color:#fff;color:#ccc;cursor:default}.datepicker-panel>ul>li.disabled.highlighted,.datepicker-panel>ul>li.disabled:hover.highlighted{background-color:#e5f2ff}.datepicker-panel>ul>li[data-view="month next"],.datepicker-panel>ul>li[data-view="month prev"],.datepicker-panel>ul>li[data-view="year next"],.datepicker-panel>ul>li[data-view="year prev"],.datepicker-panel>ul>li[data-view="years next"],.datepicker-panel>ul>li[data-view="years prev"],.datepicker-panel>ul>li[data-view=next]{font-size:18px}.datepicker-panel>ul>li[data-view="month current"],.datepicker-panel>ul>li[data-view="year current"],.datepicker-panel>ul>li[data-view="years current"]{width:150px}.datepicker-panel>ul[data-view=months]>li,.datepicker-panel>ul[data-view=years]>li{height:52.5px;line-height:52.5px;width:52.5px}.datepicker-panel>ul[data-view=week]>li,.datepicker-panel>ul[data-view=week]>li:hover{background-color:#fff;cursor:default}.datepicker-hide{display:none}
|
||||
.datepicker-container {
|
||||
border-radius: 4px;
|
||||
}
|
||||
.datepicker-panel>ul>li {
|
||||
border-radius: 100%;
|
||||
color: rgba(0,0,0,0.65);
|
||||
}
|
||||
.datepicker-panel>ul>li.picked, .datepicker-panel>ul>li.picked:hover {
|
||||
color: #39f;
|
||||
}
|
||||
.datepicker-inline {
|
||||
position: absolute;
|
||||
z-index: 999999;
|
||||
bottom: 48px;
|
||||
right: 24px;
|
||||
height: 250px;
|
||||
top: auto;
|
||||
left: auto;
|
||||
}
|
||||
.datepicker-panel>ul>li.picked {
|
||||
background: #1890ff;
|
||||
color: #fff;
|
||||
}
|
||||
.datepicker-dropdown {
|
||||
box-shadow: none;
|
||||
}
|
||||
19
src/static/html/ezuikit_static/rec/datepicker.zh-CN.js
Normal file
19
src/static/html/ezuikit_static/rec/datepicker.zh-CN.js
Normal file
@ -0,0 +1,19 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery')) :
|
||||
typeof define === 'function' && define.amd ? define(['jquery'], factory) :
|
||||
(factory(global.jQuery));
|
||||
}(this, (function ($) {
|
||||
'use strict';
|
||||
|
||||
$.fn.datepicker.languages['zh-CN'] = {
|
||||
format: 'yyyy年mm月dd日',
|
||||
days: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
|
||||
daysShort: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
|
||||
daysMin: ['日', '一', '二', '三', '四', '五', '六'],
|
||||
months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
|
||||
monthsShort: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
|
||||
weekStart: 1,
|
||||
yearFirst: true,
|
||||
yearSuffix: '年'
|
||||
};
|
||||
})));
|
||||
2
src/static/html/ezuikit_static/rec/jquery.min.js
vendored
Normal file
2
src/static/html/ezuikit_static/rec/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
170
src/static/html/ezuikit_static/speed/speed.css
Normal file
170
src/static/html/ezuikit_static/speed/speed.css
Normal file
@ -0,0 +1,170 @@
|
||||
.speed-select {
|
||||
text-align: center;
|
||||
display: block;
|
||||
background: rgb(255, 255, 255);
|
||||
box-shadow: rgb(0 0 0 / 10%) 0px 3px 20px 0px;
|
||||
border-radius: 2px;
|
||||
padding: 0px;
|
||||
width: 100px;
|
||||
position: absolute;
|
||||
bottom: 48px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
.speed-select > li {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
white-space: nowrap;
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.speed-select li:hover {
|
||||
background: #1890ff1a;
|
||||
}
|
||||
|
||||
.speed-select ::after {
|
||||
position: absolute;
|
||||
bottom: -16px;
|
||||
left: 40%;
|
||||
content: " ";
|
||||
border: 8px solid transparent;
|
||||
border-top: 8px solid #ffffff;
|
||||
}
|
||||
|
||||
/*避免触发onmouseleave事件*/
|
||||
.speed-select ::before {
|
||||
position: absolute;
|
||||
bottom: -16px;
|
||||
left: 0;
|
||||
content: " ";
|
||||
border: 8px solid transparent;
|
||||
border-top: 8px solid transparent;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.speed-select.mobile {
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 2;
|
||||
left: 0;
|
||||
transform: translateX(0);
|
||||
width: 90%;
|
||||
margin: auto;
|
||||
margin: 0px 5% 50px;
|
||||
border-radius: 10px;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.hd.speed-select.mobile {
|
||||
height: 90px;
|
||||
}
|
||||
|
||||
.speed.speed-select.mobile {
|
||||
height: 180px;
|
||||
}
|
||||
|
||||
.speed-select.mobile .selectOption.active {
|
||||
color: #648ffc;
|
||||
}
|
||||
|
||||
.speed-select .selectOption.active {
|
||||
color: #648ffc;
|
||||
}
|
||||
|
||||
.speed-select.mobile .selectOption.cancel {
|
||||
position: absolute;
|
||||
background: #ffff;
|
||||
width: 100%;
|
||||
margin-top: 30px;
|
||||
height: 45px;
|
||||
text-align: center;
|
||||
line-height: 45px;
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.speed-select.mobile ::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.speed-select-mask {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
/* height: 100vh; */
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.speed-select.mobile.expend {
|
||||
bottom: 0;
|
||||
top: auto;
|
||||
width: 240px;
|
||||
right: 0;
|
||||
left: auto;
|
||||
height: 100vw;
|
||||
margin: 0;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
color: #ffffff;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.speed-select.mobile.expend li {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.speed-select.mobile.expend li:first-child {
|
||||
margin-top: 40%;
|
||||
}
|
||||
|
||||
.speed-select.mobile.expend .selectOption.cancel {
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 40px;
|
||||
font-size: 0;
|
||||
background: none;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.speed-select.mobile.expend .selectOption.cancel::before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 16px;
|
||||
height: 1px;
|
||||
background: #ffffff;
|
||||
border: none;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%) rotate(45deg);
|
||||
}
|
||||
|
||||
.speed-select.mobile.expend .selectOption.cancel::after {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 1px;
|
||||
height: 16px;
|
||||
background: #ffffff;
|
||||
border: none;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%) rotate(45deg);
|
||||
}
|
||||
5497
src/static/html/ezuikit_static/talk/adapeter.js
Normal file
5497
src/static/html/ezuikit_static/talk/adapeter.js
Normal file
File diff suppressed because it is too large
Load Diff
3505
src/static/html/ezuikit_static/talk/janus.js
Normal file
3505
src/static/html/ezuikit_static/talk/janus.js
Normal file
File diff suppressed because it is too large
Load Diff
343
src/static/html/ezuikit_static/talk/tts-v4.js
Normal file
343
src/static/html/ezuikit_static/talk/tts-v4.js
Normal file
@ -0,0 +1,343 @@
|
||||
// We make use of this 'server' variable to provide the address of the
|
||||
// REST Janus API. By default, in this example we assume that Janus is
|
||||
// co-located with the web server hosting the HTML pages but listening
|
||||
// on a different port (8088, the default for HTTP in Janus), which is
|
||||
// why we make use of the 'window.location.hostname' base address. Since
|
||||
// Janus can also do HTTPS, and considering we don't really want to make
|
||||
// use of HTTP for Janus if your demos are served on HTTPS, we also rely
|
||||
// on the 'window.location.protocol' prefix to build the variable, in
|
||||
// particular to also change the port used to contact Janus (8088 for
|
||||
// HTTP and 8089 for HTTPS, if enabled).
|
||||
// In case you place Janus behind an Apache frontend (as we did on the
|
||||
// online demos at http://janus.conf.meetecho.com) you can just use a
|
||||
// relative path for the variable, e.g.:
|
||||
//
|
||||
// var server = "/janus";
|
||||
//
|
||||
// which will take care of this on its own.
|
||||
//
|
||||
//
|
||||
// If you want to use the WebSockets frontend to Janus, instead, you'll
|
||||
// have to pass a different kind of address, e.g.:
|
||||
//
|
||||
// var server = "ws://" + window.location.hostname + ":8188";
|
||||
//
|
||||
// Of course this assumes that support for WebSockets has been built in
|
||||
// when compiling the server. WebSockets support has not been tested
|
||||
// as much as the REST API, so handle with care!
|
||||
//
|
||||
//
|
||||
// If you have multiple options available, and want to let the library
|
||||
// autodetect the best way to contact your server (or pool of servers),
|
||||
// you can also pass an array of servers, e.g., to provide alternative
|
||||
// means of access (e.g., try WebSockets first and, if that fails, fall
|
||||
// back to plain HTTP) or just have failover servers:
|
||||
//
|
||||
// var server = [
|
||||
// "ws://" + window.location.hostname + ":8188",
|
||||
// "/janus"
|
||||
// ];
|
||||
//
|
||||
// This will tell the library to try connecting to each of the servers
|
||||
// in the presented order. The first working server will be used for
|
||||
// the whole session.
|
||||
//
|
||||
var server = null;
|
||||
if(window.location.protocol === 'http:')
|
||||
//server = "http://" + window.location.hostname + ":9020/janus";
|
||||
// yujianbo
|
||||
server = "https://" + "10.80.21.211" + ":9022/janus";
|
||||
else
|
||||
//server = "https://" + window.location.hostname + ":9022/janus";
|
||||
// -yujianbo
|
||||
server = "https://" + "10.80.21.211" + ":9022/janus";
|
||||
|
||||
var janus = null;
|
||||
var tts = null;
|
||||
var opaqueId = "tts-"+Janus.randomString(12);
|
||||
|
||||
var spinner = null;
|
||||
|
||||
// Initialize the library (all console debuggers enabled)
|
||||
Janus.init({debug: "all", callback: function() {
|
||||
window.stopTalk = function (){
|
||||
janus.destroy();
|
||||
}
|
||||
// debugger;
|
||||
window.startTalk = function() {
|
||||
// Make sure the browser supports WebRTC
|
||||
if(!Janus.isWebrtcSupported()) {
|
||||
bootbox.alert("No WebRTC support... ");
|
||||
return;
|
||||
}
|
||||
|
||||
// if($('#tts_url').val().length == 0){
|
||||
// bootbox.alert("Please input tts url... ");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// $(this).attr('disabled', true).unbind('click');
|
||||
|
||||
// Create session
|
||||
janus = new Janus(
|
||||
{
|
||||
server: window.EZUIKit.opt.rtcUrl,
|
||||
// No "iceServers" is provided, meaning janus.js will use a default STUN server
|
||||
// Here are some examples of how an iceServers field may look like to support TURN
|
||||
// iceServers: [{urls: "turn:yourturnserver.com:3478", username: "janususer", credential: "januspwd"}],
|
||||
// iceServers: [{urls: "turn:yourturnserver.com:443?transport=tcp", username: "janususer", credential: "januspwd"}],
|
||||
// iceServers: [{urls: "turns:yourturnserver.com:443?transport=tcp", username: "janususer", credential: "januspwd"}],
|
||||
// Should the Janus API require authentication, you can specify either the API secret or user token here too
|
||||
// token: "mytoken",
|
||||
// or
|
||||
// apisecret: "serversecret",
|
||||
success: function() {
|
||||
// Attach to tts plugin
|
||||
janus.attach(
|
||||
{
|
||||
plugin: "rtcgw.plugin.tts",
|
||||
opaqueId: opaqueId,
|
||||
success: function(pluginHandle) {
|
||||
// $('#details').remove();
|
||||
tts = pluginHandle;
|
||||
Janus.log("Plugin attached! (" + tts.getPlugin() + ", id=" + tts.getId() + ")");
|
||||
// Negotiate WebRTC
|
||||
//var url = "tts://61.130.6.23:8664/talk://D13781761:0:1:cas.ys7.com:6500?97fbd2a75fa94b7682c994d3d1fac8ca:ut.5porslgu79e9r7ca48z32k8abgl3rp58-77bhb6i7xr-1kmumtg-jkhy7pvfr:0:3"
|
||||
|
||||
|
||||
//var url = "tts://10.86.15.209:8664/talk://D13781761:0:1:cas.ys7.com:6500?32db2578ba7c4a84be22ecc0bcd0f8db:ut.5lqpkhim5m7cdk2y5w60g7hm9vd7i3v0-3d2pwhxe2t-11wx2ge-sh4yazbll:0:3"
|
||||
//var url = "tts://10.86.15.209:8664/talk://D13781761:0:1:cas.ys7.com:6500"
|
||||
//test12.ys.com
|
||||
//var url = "tts://10.86.15.209:8664/talk://D08197169:0:1:cas.ys7.com:6500"
|
||||
//test10.ys.com
|
||||
//var url = "tts://10.86.29.210:8664/talk://D08197169:0:1:cas.ys7.com:6500"
|
||||
var url = window.EZUIKit.opt.talkLink;
|
||||
console.log("ttsUlr",url);
|
||||
var body = { "request": "start", "url": url, "codec": "opus", "dir": "sendrecv", "audio_debug": 1};
|
||||
//tts.send({"message": body});
|
||||
Janus.debug("Trying a createOffer too (audio/video sendrecv)");
|
||||
tts.createOffer(
|
||||
{
|
||||
// No media provided: by default, it's sendrecv for audio and video
|
||||
media: { audio: true, video: false, data: false }, // Audio only
|
||||
// If you want to test simulcasting (Chrome and Firefox only), then
|
||||
// pass a ?simulcast=true when opening this demo page: it will turn
|
||||
// the following 'simulcast' property to pass to janus.js to true
|
||||
simulcast: false,
|
||||
simulcast2: false,
|
||||
success: function(jsep) {
|
||||
Janus.debug("Got SDP!");
|
||||
Janus.debug(jsep);
|
||||
tts.send({"message": body, "jsep": jsep});
|
||||
if(typeof window.EZUIKit.handleTalkSuccess !== 'undefined'){
|
||||
window.EZUIKit.handleTalkSuccess();
|
||||
}
|
||||
},
|
||||
error: function(error) {
|
||||
Janus.error("WebRTC error:", error);
|
||||
// bootbox.alert("WebRTC error... " + JSON.stringify(error));
|
||||
if(typeof window.EZUIKit['handleTalkError']?.[window.__CURRENT_PLAYER_TALK_ID] !== 'undefined'){
|
||||
window.EZUIKit['handleTalkError']?.[window.__CURRENT_PLAYER_TALK_ID](error);
|
||||
}
|
||||
}
|
||||
});
|
||||
// $('#start').removeAttr('disabled').html("Stop")
|
||||
// .click(function() {
|
||||
// $(this).attr('disabled', true);
|
||||
// janus.destroy();
|
||||
// });
|
||||
},
|
||||
error: function(error) {
|
||||
console.error(" -- Error attaching plugin...", error);
|
||||
bootbox.alert("Error attaching plugin... " + error);
|
||||
if(window.EZUIKit['handleTalkError']?.[window.__CURRENT_PLAYER_TALK_ID] !== 'undefined'){
|
||||
window.EZUIKit['handleTalkError']?.[window.__CURRENT_PLAYER_TALK_ID](error);
|
||||
}
|
||||
},
|
||||
consentDialog: function(on) {
|
||||
Janus.debug("Consent dialog should be " + (on ? "on" : "off") + " now");
|
||||
if(on) {
|
||||
// Darken screen and show hint
|
||||
// $.blockUI({
|
||||
// message: '<div><img src="up_arrow.png"/></div>',
|
||||
// css: {
|
||||
// border: 'none',
|
||||
// padding: '15px',
|
||||
// backgroundColor: 'transparent',
|
||||
// color: '#aaa',
|
||||
// top: '10px',
|
||||
// left: (navigator.mozGetUserMedia ? '-100px' : '300px')
|
||||
// } });
|
||||
} else {
|
||||
// Restore screen
|
||||
// $.unblockUI();
|
||||
}
|
||||
},
|
||||
iceState: function(state) {
|
||||
Janus.log("ICE state changed to " + state);
|
||||
},
|
||||
mediaState: function(medium, on) {
|
||||
Janus.log("Janus " + (on ? "started" : "stopped") + " receiving our " + medium);
|
||||
},
|
||||
webrtcState: function(on) {
|
||||
Janus.log("Janus says our WebRTC PeerConnection is " + (on ? "up" : "down") + " now");
|
||||
// $("#audioleft").parent().unblock();
|
||||
},
|
||||
slowLink: function(uplink, lost) {
|
||||
Janus.warn("Janus reports problems " + (uplink ? "sending" : "receiving") +
|
||||
" packets on this PeerConnection (" + lost + " lost packets)");
|
||||
},
|
||||
onmessage: function(msg, jsep) {
|
||||
Janus.debug(" ::: Got a message :::");
|
||||
Janus.debug(msg);
|
||||
if(jsep !== undefined && jsep !== null) {
|
||||
Janus.debug("Handling SDP as well...");
|
||||
Janus.debug(jsep);
|
||||
tts.handleRemoteJsep({jsep: jsep});
|
||||
}
|
||||
var result = msg["result"];
|
||||
if(result !== null && result !== undefined) {
|
||||
if(result === "done") {
|
||||
// The plugin closed
|
||||
bootbox.alert("The TTS Test is over");
|
||||
if(spinner !== null && spinner !== undefined)
|
||||
spinner.stop();
|
||||
spinner = null;
|
||||
// $('#myaudio').remove();
|
||||
//$('#waitingvideo').remove();
|
||||
// $('#peeraudio').remove();
|
||||
return;
|
||||
}
|
||||
|
||||
if(result === "msg"){
|
||||
if(typeof window.EZUIKit.handleTalkMessage !== 'undefined'){
|
||||
window.EZUIKit.handleTalkMessage(msg);
|
||||
}
|
||||
}
|
||||
// Any loss?
|
||||
var status = result["status"];
|
||||
if(status === "slow_link") {
|
||||
//~ var bitrate = result["bitrate"];
|
||||
//~ toastr.warning("The bitrate has been cut to " + (bitrate/1000) + "kbps", "Packet loss?", {timeOut: 2000});
|
||||
toastr.warning("Janus apparently missed many packets we sent, maybe we should reduce the bitrate", "Packet loss?", {timeOut: 2000});
|
||||
}
|
||||
}
|
||||
},
|
||||
onlocalstream: function(stream) {
|
||||
Janus.debug(" ::: Got a local stream :::");
|
||||
Janus.debug(stream);
|
||||
|
||||
// if($('#myaudio').length === 0) {
|
||||
// $('#audios').removeClass('hide').show();
|
||||
// $('#audioleft').append('<audio id="myaudio" autoplay controls muted>Your browser does not support audio tag</audio>');
|
||||
// }
|
||||
// Janus.attachMediaStream(document.getElementById("myaudio"), stream);
|
||||
//$("#myaudio").get(0).muted = "muted";
|
||||
if(tts.webrtcStuff.pc.iceConnectionState !== "completed" &&
|
||||
tts.webrtcStuff.pc.iceConnectionState !== "connected") {
|
||||
// $("#audioleft").parent().block({
|
||||
// message: '<b>Publishing...</b>',
|
||||
// css: {
|
||||
// border: 'none',
|
||||
// backgroundColor: 'transparent',
|
||||
// color: 'white'
|
||||
// }
|
||||
// });
|
||||
// No remote video yet
|
||||
//$('#audioright').append('<video class="rounded centered" id="waitingvideo" width=320 height=240 />');
|
||||
if(spinner == null) {
|
||||
var target = document.getElementById('audioright');
|
||||
//spinner = new Spinner({top:100}).spin(target);
|
||||
} else {
|
||||
spinner.spin();
|
||||
}
|
||||
}
|
||||
var audioTracks = stream.getAudioTracks();
|
||||
if(audioTracks === null || audioTracks === undefined || audioTracks.length === 0) {
|
||||
// $('#myaudio').hide();
|
||||
} else {
|
||||
// $('#myaudio').removeClass('hide').show();
|
||||
// document.getElementById('myaudio').play();
|
||||
}
|
||||
},
|
||||
onremotestream: function(stream) {
|
||||
Janus.debug(" ::: Got a remote stream :::");
|
||||
Janus.debug(stream);
|
||||
// if($('#peeraudio').length === 0) {
|
||||
// $('#audios').removeClass('hide').show();
|
||||
// // $('#audioright').append('<audio id="peeraudio" autoplay controls>Your browser does not support audio tag</audio>');
|
||||
// // Show the video, hide the spinner and show the resolution when we get a playing event
|
||||
// var audio = $('<audio id="peeraudio" autoplay controls playsinline preload="preload" loop="true"></audio>');
|
||||
// audio = audio.get(0);
|
||||
// audio.setAttribute("id", 'peeraudio');
|
||||
// audio.setAttribute("preload","preload");
|
||||
// // 自动播放解决苹果不兼容autoplay属性
|
||||
// audio.setAttribute("loop",true);
|
||||
// $('#audioright').append(audio);
|
||||
// $("#peeraudio").bind("playing", function () {
|
||||
// //$('#waitingvideo').remove();
|
||||
// $('#peeraudio').removeClass('hide').show();
|
||||
// if(spinner !== null && spinner !== undefined)
|
||||
// spinner.stop();
|
||||
// spinner = null;
|
||||
// });
|
||||
// }
|
||||
Janus.attachMediaStream(document.getElementById("peeraudio"), stream);
|
||||
var audioTracks = stream.getAudioTracks();
|
||||
if(audioTracks === null || audioTracks === undefined || audioTracks.length === 0) {
|
||||
// $('#peeraudio').hide();
|
||||
} else {
|
||||
// $('#peeraudio').removeClass('hide').show();
|
||||
document.getElementById('peeraudio').play();
|
||||
}
|
||||
},
|
||||
ondataopen: function(data) {
|
||||
Janus.log("The DataChannel is available!");
|
||||
},
|
||||
ondata: function(data) {
|
||||
Janus.debug("We got data from the DataChannel! " + data);
|
||||
},
|
||||
oncleanup: function() {
|
||||
Janus.log(" ::: Got a cleanup notification :::");
|
||||
if(spinner !== null && spinner !== undefined)
|
||||
spinner.stop();
|
||||
spinner = null;
|
||||
// $('#myaudio').remove();
|
||||
// //$('#waitingvideo').remove();
|
||||
// $("#audioleft").parent().unblock();
|
||||
// $('#peeraudio').remove();
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(error) {
|
||||
Janus.error(error);
|
||||
if(window.EZUIKit['handleTalkError']?.[window.__CURRENT_PLAYER_TALK_ID] !== 'undefined'){
|
||||
window.EZUIKit['handleTalkError']?.[window.__CURRENT_PLAYER_TALK_ID](error);
|
||||
}
|
||||
},
|
||||
destroyed: function() {
|
||||
// window.location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}});
|
||||
|
||||
function checkEnter(event) {
|
||||
var theCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
|
||||
if(theCode == 13) {
|
||||
sendData();
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to parse query string
|
||||
function getQueryStringValue(name) {
|
||||
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
|
||||
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
|
||||
results = regex.exec(location.search);
|
||||
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
|
||||
}
|
||||
|
||||
@ -1,371 +1,185 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<title>萤石云播放器</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
/* background: #1a1a1a; */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#player-iframe {
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
border: none;
|
||||
display: block;
|
||||
object-fit: contain; /* 保持视频比例,不变形 */
|
||||
}
|
||||
|
||||
/* 简化的控制按钮样式 */
|
||||
.control-buttons {
|
||||
position: fixed;
|
||||
bottom: 30px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
z-index: 999;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.control-btn {
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
border-radius: 25px;
|
||||
padding: 12px 20px;
|
||||
min-width: 100px;
|
||||
min-height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.control-btn:active {
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.play-btn {
|
||||
background: rgba(76, 175, 80, 0.8);
|
||||
border-color: rgba(76, 175, 80, 0.9);
|
||||
}
|
||||
|
||||
.play-btn:active {
|
||||
background: rgba(76, 175, 80, 0.9);
|
||||
}
|
||||
|
||||
.refresh-btn {
|
||||
background: rgba(33, 150, 243, 0.8);
|
||||
border-color: rgba(33, 150, 243, 0.9);
|
||||
}
|
||||
|
||||
.refresh-btn:active {
|
||||
background: rgba(33, 150, 243, 0.9);
|
||||
}
|
||||
|
||||
/* 按钮图标样式 */
|
||||
.btn-icon {
|
||||
margin-right: 6px;
|
||||
font-size: 16px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.loading {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
padding: 15px 30px;
|
||||
border-radius: 8px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.loading::after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 10px auto 0;
|
||||
border: 3px solid rgba(255, 255, 255, 0.3);
|
||||
border-top-color: white;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* 简化的暂停占位符样式 */
|
||||
.pause-placeholder {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
background: #000000;
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.pause-content {
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.pause-title {
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="loading" id="loading">正在加载播放器...</div>
|
||||
<iframe id="player-iframe" allow="autoplay; fullscreen"></iframe>
|
||||
|
||||
<!-- 暂停时的占位符 -->
|
||||
<div class="pause-placeholder" id="pause-placeholder">
|
||||
<div class="pause-content">
|
||||
<div class="pause-title">监控已暂停</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 控制按钮 -->
|
||||
<div class="control-buttons" id="control-buttons" style="display: none;">
|
||||
<div class="control-btn play-btn" id="play-btn">
|
||||
<span class="btn-icon" id="play-icon">▶️</span>
|
||||
<span class="btn-text" id="play-text">播放</span>
|
||||
</div>
|
||||
<div class="control-btn refresh-btn" id="refresh-btn">
|
||||
<span class="btn-icon">🔄</span>
|
||||
<span class="btn-text">刷新</span>
|
||||
</div>
|
||||
</div>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
|
||||
/>
|
||||
<title>移动式检修车间</title>
|
||||
<script src="./ezuikit.js"></script>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
#video-container {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<script>
|
||||
function log(message) {
|
||||
console.log('[iframe播放器] ' + message);
|
||||
}
|
||||
|
||||
// 从URL参数获取配置
|
||||
function getConfig() {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
return {
|
||||
accessToken: params.get('accessToken'),
|
||||
playUrl: params.get('playUrl')
|
||||
};
|
||||
}
|
||||
|
||||
// 初始化播放器
|
||||
function init() {
|
||||
log('初始化开始');
|
||||
|
||||
const configData = getConfig();
|
||||
|
||||
if (!configData.accessToken || !configData.playUrl) {
|
||||
log('配置参数不完整');
|
||||
document.getElementById('loading').textContent = '配置参数错误';
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存配置到全局变量
|
||||
config = {
|
||||
accessToken: configData.accessToken,
|
||||
playUrl: configData.playUrl
|
||||
};
|
||||
|
||||
log('AccessToken: ' + config.accessToken.substring(0, 20) + '...');
|
||||
log('PlayUrl: ' + config.playUrl);
|
||||
|
||||
try {
|
||||
// 使用萤石云官方iframe播放器(内存占用小)
|
||||
const iframeUrl = 'https://open.ys7.com/ezopen/h5/iframe?' +
|
||||
'url=' + encodeURIComponent(config.playUrl) +
|
||||
'&accessToken=' + encodeURIComponent(config.accessToken) +
|
||||
'&width=100%' +
|
||||
'&height=100%' +
|
||||
'&autoplay=1' +
|
||||
'&audio=1' +
|
||||
'&controls=1';
|
||||
|
||||
log('iframe URL: ' + iframeUrl);
|
||||
|
||||
const iframe = document.getElementById('player-iframe');
|
||||
iframe.src = iframeUrl;
|
||||
|
||||
// 设置初始播放状态
|
||||
isPlaying = true;
|
||||
document.getElementById('play-text').textContent = '暂停';
|
||||
document.getElementById('play-icon').textContent = '⏸️';
|
||||
|
||||
// 隐藏loading,显示控制按钮
|
||||
setTimeout(() => {
|
||||
document.getElementById('loading').style.display = 'none';
|
||||
document.getElementById('control-buttons').style.display = 'flex';
|
||||
log('播放器加载完成,显示控制按钮');
|
||||
}, 2000);
|
||||
|
||||
} catch (error) {
|
||||
log('初始化失败: ' + error.message);
|
||||
document.getElementById('loading').textContent = '初始化失败';
|
||||
}
|
||||
}
|
||||
|
||||
// 全局状态
|
||||
let isPlaying = true;
|
||||
let config = null;
|
||||
|
||||
// 播放/暂停控制
|
||||
function togglePlay() {
|
||||
log('切换播放状态: ' + (isPlaying ? '暂停' : '播放'));
|
||||
|
||||
const iframe = document.getElementById('player-iframe');
|
||||
const playText = document.getElementById('play-text');
|
||||
const playIcon = document.getElementById('play-icon');
|
||||
const pausePlaceholder = document.getElementById('pause-placeholder');
|
||||
|
||||
if (isPlaying) {
|
||||
// 暂停:清空iframe,显示占位符
|
||||
iframe.src = 'about:blank';
|
||||
pausePlaceholder.style.display = 'flex';
|
||||
playText.textContent = '播放';
|
||||
playIcon.textContent = '▶️';
|
||||
isPlaying = false;
|
||||
log('已暂停播放,显示占位符');
|
||||
} else {
|
||||
// 播放:重新设置iframe URL,隐藏占位符
|
||||
if (config) {
|
||||
const iframeUrl = 'https://open.ys7.com/ezopen/h5/iframe?' +
|
||||
'url=' + encodeURIComponent(config.playUrl) +
|
||||
'&accessToken=' + encodeURIComponent(config.accessToken) +
|
||||
'&width=100%' +
|
||||
'&height=100%' +
|
||||
'&autoplay=1' +
|
||||
'&audio=1' +
|
||||
'&controls=1';
|
||||
|
||||
iframe.src = iframeUrl;
|
||||
pausePlaceholder.style.display = 'none';
|
||||
playText.textContent = '暂停';
|
||||
playIcon.textContent = '⏸️';
|
||||
isPlaying = true;
|
||||
log('已开始播放,隐藏占位符');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 刷新播放器
|
||||
function refreshPlayer() {
|
||||
log('刷新播放器');
|
||||
|
||||
const iframe = document.getElementById('player-iframe');
|
||||
const playText = document.getElementById('play-text');
|
||||
const playIcon = document.getElementById('play-icon');
|
||||
const pausePlaceholder = document.getElementById('pause-placeholder');
|
||||
|
||||
// 先清空,显示加载状态
|
||||
iframe.src = 'about:blank';
|
||||
pausePlaceholder.style.display = 'none';
|
||||
|
||||
// 延迟重新加载
|
||||
setTimeout(() => {
|
||||
if (config) {
|
||||
const iframeUrl = 'https://open.ys7.com/ezopen/h5/iframe?' +
|
||||
'url=' + encodeURIComponent(config.playUrl) +
|
||||
'&accessToken=' + encodeURIComponent(config.accessToken) +
|
||||
'&width=100%' +
|
||||
'&height=100%' +
|
||||
'&autoplay=1' +
|
||||
'&audio=1' +
|
||||
'&controls=1';
|
||||
|
||||
iframe.src = iframeUrl;
|
||||
playText.textContent = '暂停';
|
||||
playIcon.textContent = '⏸️';
|
||||
isPlaying = true;
|
||||
log('刷新完成');
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// 页面加载完成后初始化
|
||||
window.onload = function() {
|
||||
log('页面加载完成');
|
||||
|
||||
// 绑定按钮事件
|
||||
document.getElementById('play-btn').addEventListener('click', togglePlay);
|
||||
document.getElementById('refresh-btn').addEventListener('click', refreshPlayer);
|
||||
|
||||
init();
|
||||
};
|
||||
|
||||
// 页面卸载时清理资源
|
||||
window.onbeforeunload = function() {
|
||||
log('页面即将卸载,清理播放器资源');
|
||||
try {
|
||||
const iframe = document.getElementById('player-iframe');
|
||||
if (iframe) {
|
||||
iframe.src = 'about:blank'; // 清空iframe源
|
||||
log('播放器资源已清理');
|
||||
}
|
||||
} catch (error) {
|
||||
log('清理播放器资源失败: ' + error.message);
|
||||
}
|
||||
};
|
||||
|
||||
// 页面隐藏时暂停播放
|
||||
document.addEventListener('visibilitychange', function() {
|
||||
if (document.hidden) {
|
||||
log('页面隐藏,暂停播放');
|
||||
try {
|
||||
const iframe = document.getElementById('player-iframe');
|
||||
if (iframe) {
|
||||
iframe.style.display = 'none';
|
||||
}
|
||||
} catch (error) {
|
||||
log('暂停播放失败: ' + error.message);
|
||||
}
|
||||
} else {
|
||||
log('页面显示,恢复播放');
|
||||
try {
|
||||
const iframe = document.getElementById('player-iframe');
|
||||
if (iframe) {
|
||||
iframe.style.display = 'block';
|
||||
}
|
||||
} catch (error) {
|
||||
log('恢复播放失败: ' + error.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<body>
|
||||
<div className="demo">
|
||||
<div id="video-container"></div>
|
||||
</div>
|
||||
<script>
|
||||
var player;
|
||||
const width = document.body.clientWidth || 375;
|
||||
|
||||
// 从URL参数获取配置
|
||||
function getConfig() {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const config = {
|
||||
accessToken: params.get('accessToken'),
|
||||
playUrl: params.get('playUrl')
|
||||
};
|
||||
|
||||
console.log('📡 获取URL参数:', {
|
||||
accessToken: config.accessToken ? config.accessToken.substring(0, 20) + '...' : '未提供',
|
||||
playUrl: config.playUrl || '未提供'
|
||||
});
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
// 获取配置
|
||||
const config = getConfig();
|
||||
|
||||
// 验证参数
|
||||
if (!config.accessToken || !config.playUrl) {
|
||||
console.error('❌ 缺少必要参数!请在URL中提供 accessToken 和 playUrl');
|
||||
alert('缺少必要参数!\n需要: ?accessToken=xxx&playUrl=ezopen://...');
|
||||
} else {
|
||||
console.log('✅ 参数验证通过,开始创建播放器');
|
||||
|
||||
// 使用URL参数创建播放器
|
||||
player = new EZUIKit.EZUIKitPlayer({
|
||||
id: "video-container", // 视频容器ID
|
||||
url: config.playUrl,
|
||||
accessToken: config.accessToken,
|
||||
template: "voice", // simple: 极简版; pcLive: 预览; pcRec: 回放; security: 安防版; voice: 语音版;
|
||||
|
||||
// 官方demo token
|
||||
// template: "voice",
|
||||
// url: "ezopen://open.ys7.com/BC7900686/1.live",
|
||||
// accessToken: "ra.84wglyar4c3r6hozd6u92ser0r854lbi-5c1dgl7mi6-1q2swlg-b0hpmwcqg",
|
||||
|
||||
width: width,
|
||||
height: (width * 9) / 16,
|
||||
language: "zh", // zh | en
|
||||
env: {
|
||||
// https://open.ys7.com/help/1772?h=domain
|
||||
// domain默认是 https://open.ys7.com, 如果是私有化部署或海外的环境,请配置对应的domain
|
||||
domain: "https://open.ys7.com",
|
||||
},
|
||||
// 日志打印设置
|
||||
loggerOptions: {
|
||||
level: "INFO", // INFO LOG WARN ERROR
|
||||
name: "ezuikit",
|
||||
showTime: true,
|
||||
},
|
||||
// 视频流的信息回调类型
|
||||
streamInfoCBType: 1,
|
||||
staticPath: "./ezuikit_static", // 使用本地静态资源
|
||||
// 错误处理
|
||||
handleError: (error) => {
|
||||
console.error('❌ 播放器错误:', error);
|
||||
}
|
||||
});
|
||||
|
||||
// 监听视频信息
|
||||
player.eventEmitter.on(
|
||||
EZUIKit.EZUIKitPlayer.EVENTS.videoInfo,
|
||||
(info) => {
|
||||
console.log("📹 videoinfo", info);
|
||||
},
|
||||
);
|
||||
|
||||
// 监听音频信息
|
||||
player.eventEmitter.on(
|
||||
EZUIKit.EZUIKitPlayer.EVENTS.audioInfo,
|
||||
(info) => {
|
||||
console.log("🔊 audioInfo", info);
|
||||
},
|
||||
);
|
||||
|
||||
// 首帧渲染成功
|
||||
player.eventEmitter.on(
|
||||
EZUIKit.EZUIKitPlayer.EVENTS.firstFrameDisplay,
|
||||
() => {
|
||||
console.log("✅ firstFrameDisplay - 首帧渲染成功");
|
||||
},
|
||||
);
|
||||
|
||||
// 流信息回调
|
||||
player.eventEmitter.on(
|
||||
EZUIKit.EZUIKitPlayer.EVENTS.streamInfoCB,
|
||||
(info) => {
|
||||
console.log("📡 streamInfoCB ", info);
|
||||
},
|
||||
);
|
||||
|
||||
console.log('🎬 播放器初始化完成');
|
||||
}
|
||||
|
||||
// 控制函数
|
||||
function fullScreen() {
|
||||
if (player) {
|
||||
player.fullScreen();
|
||||
}
|
||||
}
|
||||
|
||||
function play() {
|
||||
if (player) {
|
||||
var playPromise = player.play();
|
||||
playPromise.then((data) => {
|
||||
console.log("播放成功", data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function stop() {
|
||||
if (player) {
|
||||
var stopPromise = player.stop();
|
||||
stopPromise.then((data) => {
|
||||
console.log("停止成功", data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function openSound() {
|
||||
if (player) {
|
||||
var openSoundPromise = player.openSound();
|
||||
openSoundPromise.then((data) => {
|
||||
console.log("打开声音成功", data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function closeSound() {
|
||||
if (player) {
|
||||
var closeSoundPromise = player.closeSound();
|
||||
closeSoundPromise.then((data) => {
|
||||
console.log("关闭声音成功", data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
if (player) {
|
||||
player.destroy();
|
||||
console.log('🗑️ 播放器已销毁');
|
||||
}
|
||||
player = null;
|
||||
}
|
||||
|
||||
// 页面卸载时清理
|
||||
window.onbeforeunload = function() {
|
||||
destroy();
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user