Compare commits
53 Commits
1.0-releas
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
960ca2c322 | 2 years ago |
|
|
7c8cb04802 | 3 years ago |
|
|
06d7eb0bff | 3 years ago |
|
|
2550475eb0 | 3 years ago |
|
|
46dba190f2 | 3 years ago |
|
|
a2e5281780 | 3 years ago |
|
|
1de3950a23 | 4 years ago |
|
|
c0f69dde93 | 4 years ago |
|
|
65d123c406 | 4 years ago |
|
|
ba5ce7492a | 4 years ago |
|
|
738882cd08 | 4 years ago |
|
|
fd57ca6dd5 | 4 years ago |
|
|
1cc53e254d | 4 years ago |
|
|
4113c831d7 | 4 years ago |
|
|
f2791d53db | 4 years ago |
|
|
8245eb379f | 4 years ago |
|
|
c44fa4ea64 | 4 years ago |
|
|
5c9c2b57fb | 4 years ago |
|
|
576e9d0cda | 4 years ago |
|
|
b96a17149c | 4 years ago |
|
|
270521f552 | 4 years ago |
|
|
7408c87193 | 4 years ago |
|
|
8e7773b222 | 4 years ago |
|
|
0048c3d1e2 | 4 years ago |
|
|
4c04774d5d | 4 years ago |
|
|
36f5c24e00 | 4 years ago |
|
|
bfb09d1a6e | 4 years ago |
|
|
cb38466400 | 4 years ago |
|
|
18cabf2ebd | 4 years ago |
|
|
dd0f85c81c | 4 years ago |
|
|
c1d3065ba0 | 4 years ago |
|
|
4fd6b21329 | 4 years ago |
|
|
0af7ffa8e8 | 4 years ago |
|
|
934a3a35ae | 4 years ago |
|
|
35840fc12e | 4 years ago |
|
|
3797af24da | 4 years ago |
|
|
19e7291eb1 | 4 years ago |
|
|
b741bcd3de | 4 years ago |
|
|
6b3cf9fa77 | 4 years ago |
|
|
4f09b64b4c | 4 years ago |
|
|
575d95545d | 4 years ago |
|
|
9bef504cb7 | 4 years ago |
|
|
660de42bdc | 4 years ago |
|
|
23f9c4e514 | 4 years ago |
|
|
6dc6e3d7d4 | 4 years ago |
|
|
14a5bd738c | 4 years ago |
|
|
a5072f4d6a | 4 years ago |
|
|
573c303157 | 4 years ago |
|
|
2d7e36eef6 | 4 years ago |
|
|
2c89634ad4 | 4 years ago |
|
|
a98d220aec | 4 years ago |
|
|
d878bf6dc7 | 4 years ago |
|
|
03beee4a1d | 4 years ago |
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
@ -0,0 +1,120 @@
|
||||
class WebRtcPlayer {
|
||||
|
||||
webrtc = null;
|
||||
video = null;
|
||||
server = null;
|
||||
codecLink = null;
|
||||
rsdpLink = null;
|
||||
stream = new MediaStream();
|
||||
uuid = null;
|
||||
options={
|
||||
onStatusChange:null
|
||||
};
|
||||
|
||||
constructor(server,video1, uuid, options={}) {
|
||||
console.log("new uuid:"+uuid)
|
||||
this.server = server;
|
||||
//this.video = document.getElementById(id);
|
||||
this.video = video1
|
||||
this.uuid = uuid;
|
||||
Object.assign(this.options, options);
|
||||
this.createLinks();
|
||||
this.play();
|
||||
}
|
||||
|
||||
createLinks() {
|
||||
this.codecLink = "//" + this.server + "/stream/codec/" + this.uuid
|
||||
this.rsdpLink = "//" + this.server + "/stream/receiver/" + this.uuid
|
||||
}
|
||||
|
||||
play() {
|
||||
this.webrtc = new RTCPeerConnection({
|
||||
iceServers: [{
|
||||
urls: ["stun:stun.l.google.com:19302"]
|
||||
}]
|
||||
});
|
||||
if(this.webrtc){
|
||||
|
||||
}else{
|
||||
console.log("no")
|
||||
}
|
||||
this.webrtc.onnegotiationneeded = this.handleNegotiationNeeded.bind(this);
|
||||
this.webrtc.ontrack = this.onTrack.bind(this);
|
||||
fetch(this.codecLink)
|
||||
.then((response) => {
|
||||
response.json().then((data) => {
|
||||
data.forEach((item, i) => {
|
||||
this.webrtc.addTransceiver(item.Type, {
|
||||
'direction': 'sendrecv'
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
|
||||
this.webrtc.onconnectionstatechange = () => {
|
||||
if(this.webrtc.connectionState == 'connected' || this.webrtc.connectionState == 'connecting'){
|
||||
console.log("uuid:"+this.uuid+" status:" + this.webrtc.connectionState)
|
||||
}else{
|
||||
console.log(this.webrtc.connectionState)
|
||||
this.load(this.uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async handleNegotiationNeeded() {
|
||||
let offer = await this.webrtc.createOffer();
|
||||
await this.webrtc.setLocalDescription(offer);
|
||||
let formData = new FormData();
|
||||
formData.append('suuid', this.uuid);
|
||||
formData.append('data', btoa(this.webrtc.localDescription.sdp));
|
||||
fetch(this.rsdpLink, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then((response) => {
|
||||
response.text().then((data) => {
|
||||
this.webrtc.setRemoteDescription(new RTCSessionDescription({
|
||||
type: 'answer',
|
||||
sdp: atob(data)
|
||||
}))
|
||||
});
|
||||
})
|
||||
.catch((err) => {})
|
||||
}
|
||||
|
||||
onTrack(event) {
|
||||
this.stream.addTrack(event.track);
|
||||
this.video.srcObject = this.stream;
|
||||
this.video.play();
|
||||
}
|
||||
|
||||
load(uuid) {
|
||||
this.destroy();
|
||||
this.uuid = uuid;
|
||||
this.createLinks();
|
||||
this.play();
|
||||
}
|
||||
|
||||
destroy() {
|
||||
console.log("destroy uuid:"+this.uuid)
|
||||
this.webrtc.close();
|
||||
this.webrtc = null;
|
||||
this.video.srcObject = null;
|
||||
this.stream = new MediaStream();
|
||||
}
|
||||
|
||||
getImageUrl() {
|
||||
let canvas = document.createElement("canvas");
|
||||
canvas.width = this.video.videoWidth;
|
||||
canvas.height = this.video.videoHeight;
|
||||
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
let dataURL = canvas.toDataURL();
|
||||
canvas.remove();
|
||||
return dataURL;
|
||||
}
|
||||
|
||||
}
|
||||
export default WebRtcPlayer;
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 34 KiB |
@ -1,12 +0,0 @@
|
||||
{
|
||||
"program": {
|
||||
"portable": {
|
||||
"pnacl-translate": {
|
||||
"url": "media_player.pexe"
|
||||
},
|
||||
"pnacl-debug": {
|
||||
"url": "media_player_unstripped.bc"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
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 it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -0,0 +1,336 @@
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<head>
|
||||
<title>ZLM RTC demo</title>
|
||||
<script src="./ZLMRTCClient.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div style="text-align: center;">
|
||||
<div>
|
||||
<video id='video' controls autoplay style="text-align:left;">
|
||||
Your browser is too old which doesn't support HTML5 video.
|
||||
</video>
|
||||
|
||||
<video id='selfVideo' controls autoplay style="text-align:right;">
|
||||
Your browser is too old which doesn't support HTML5 video.
|
||||
</video>
|
||||
</div>
|
||||
|
||||
<div style="float: left; width:30%;">
|
||||
<span>已存在的流列表,点击自动播放:</span>
|
||||
<ol id="olstreamlist">
|
||||
<li>初始演示</li>
|
||||
<li>每秒自动刷新</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div style="float: right; width: 70%">
|
||||
|
||||
<p>
|
||||
<label for="streamUrl">url:</label>
|
||||
<input type="text" style="co; width:70%" id='streamUrl' value="http://192.168.1.101/index/api/webrtc?app=live&stream=xiong&type=play">
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="simulcast">simulcast:</label>
|
||||
<input type="checkbox" id='simulcast'>
|
||||
</p>
|
||||
<p>
|
||||
<label for="useCamera">useCamera:</label>
|
||||
<input type="checkbox" id='useCamera' checked="checked">
|
||||
</p>
|
||||
|
||||
|
||||
<p>
|
||||
<label for="audioEnable">audioEnable:</label>
|
||||
<input type="checkbox" id='audioEnable' checked="checked">
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="videoEnable">videoEnable:</label>
|
||||
<input type="checkbox" id='videoEnable' checked="checked">
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="method">method(play or push or echo):</label>
|
||||
<input type="radio" name="method" value="echo" >echo
|
||||
<input type="radio" name="method" value="push" >push
|
||||
<input type="radio" name="method" value="play" checked = true>play
|
||||
</p>
|
||||
<p>
|
||||
<label for="resolution">resolution:</label>
|
||||
<select id="resolution">
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="datachannel">datachannel:</label>
|
||||
<input id='datachannel' name="datachannel" type="checkbox" value="0">
|
||||
</p>
|
||||
<button onclick="start()">开始(start)</button>
|
||||
<button onclick="stop()">停止(stop)</button>
|
||||
|
||||
<p>
|
||||
<label for="msgsend">msgsend:</label>
|
||||
<input type="text" id='msgsend' value="hello word !">
|
||||
</p>
|
||||
<p>
|
||||
<label for="msgrecv">msgrecv:</label>
|
||||
<input type="text" id='msgrecv' disabled>
|
||||
</p>
|
||||
<button onclick="send()">发送(send by datachannel)</button>
|
||||
<button onclick="close()">关闭(close datachannel)</button>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var player = null;
|
||||
var recvOnly = true;
|
||||
var resArr = [];
|
||||
|
||||
var ishttps = 'https:' == document.location.protocol ? true : false;
|
||||
var isLocal = "file:" == document.location.protocol ? true : false;
|
||||
|
||||
const searchParams = new URL(document.location.href).searchParams;
|
||||
let type = searchParams.get('type');
|
||||
if (!['echo','push','play'].includes(type)) {
|
||||
type = 'play';
|
||||
}
|
||||
recvOnly = type === 'play';
|
||||
const apiPath = `/index/api/webrtc?app=${searchParams.get('app') ?? 'live'}&stream=${searchParams.get('stream') ?? 'test'}&type=${type}`;
|
||||
|
||||
if(!ishttps && !isLocal){
|
||||
alert('本demo需要在https的网站访问 ,如果你要推流的话(this demo must access in site of https if you want push stream)');
|
||||
}
|
||||
|
||||
const apiHost = isLocal ? "http://127.0.0.1" : `${document.location.protocol}//${window.location.host}`;
|
||||
var url = apiHost + apiPath;
|
||||
|
||||
document.getElementById('streamUrl').value = url;
|
||||
document.getElementsByName("method").forEach((el,idx) => {
|
||||
el.checked = el.value === type;
|
||||
el.onclick = function(e) {
|
||||
let url = new URL(document.getElementById('streamUrl').value);
|
||||
url.searchParams.set("type",el.value);
|
||||
document.getElementById('streamUrl').value = url.toString();
|
||||
|
||||
if(el.value == "play"){
|
||||
recvOnly = true;
|
||||
}else if(el.value == "echo"){
|
||||
recvOnly = false;
|
||||
}else{
|
||||
recvOnly = false;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
ZLMRTCClient.GetAllScanResolution().forEach((r,i) => {
|
||||
opt = document.createElement('option');
|
||||
opt.text = `${r.label}(${r.width}x${r.height})`;
|
||||
opt.value = r;
|
||||
if (1080*720 <= r.width * r.height && r.width * r.height <= 1280*720) {
|
||||
opt.selected = true;
|
||||
}
|
||||
document.getElementById("resolution").add(opt,null);
|
||||
});
|
||||
|
||||
function start_play(){
|
||||
let elr = document.getElementById("resolution");
|
||||
let res = elr.options[elr.selectedIndex].text.match(/\d+/g);
|
||||
let h = parseInt(res.pop());
|
||||
let w = parseInt(res.pop());
|
||||
|
||||
player = new ZLMRTCClient.Endpoint(
|
||||
{
|
||||
element: document.getElementById('video'),// video 标签
|
||||
debug: true,// 是否打印日志
|
||||
zlmsdpUrl:document.getElementById('streamUrl').value,//流地址
|
||||
simulcast:document.getElementById('simulcast').checked,
|
||||
useCamera:document.getElementById('useCamera').checked,
|
||||
audioEnable:document.getElementById('audioEnable').checked,
|
||||
videoEnable:document.getElementById('videoEnable').checked,
|
||||
recvOnly:recvOnly,
|
||||
resolution:{w:w,h:h},
|
||||
usedatachannel:document.getElementById('datachannel').checked,
|
||||
}
|
||||
);
|
||||
|
||||
player.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,function(e)
|
||||
{// ICE 协商出错
|
||||
console.log('ICE 协商出错');
|
||||
});
|
||||
|
||||
player.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,function(e)
|
||||
{//获取到了远端流,可以播放
|
||||
console.log('播放成功',e.streams);
|
||||
});
|
||||
|
||||
player.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED,function(e)
|
||||
{// offer anwser 交换失败
|
||||
console.log('offer anwser 交换失败',e);
|
||||
stop();
|
||||
});
|
||||
|
||||
player.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,function(s)
|
||||
{// 获取到了本地流
|
||||
|
||||
document.getElementById('selfVideo').srcObject=s;
|
||||
document.getElementById('selfVideo').muted = true;
|
||||
|
||||
//console.log('offer anwser 交换失败',e)
|
||||
});
|
||||
|
||||
player.on(ZLMRTCClient.Events.CAPTURE_STREAM_FAILED,function(s)
|
||||
{// 获取本地流失败
|
||||
|
||||
console.log('获取本地流失败');
|
||||
});
|
||||
|
||||
player.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE,function(state)
|
||||
{// RTC 状态变化 ,详情参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState
|
||||
console.log('当前状态==>',state);
|
||||
});
|
||||
|
||||
player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_OPEN,function(event)
|
||||
{
|
||||
console.log('rtc datachannel 打开 :',event);
|
||||
});
|
||||
|
||||
player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_MSG,function(event)
|
||||
{
|
||||
console.log('rtc datachannel 消息 :',event.data);
|
||||
document.getElementById('msgrecv').value = event.data;
|
||||
});
|
||||
player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_ERR,function(event)
|
||||
{
|
||||
console.log('rtc datachannel 错误 :',event);
|
||||
});
|
||||
player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_CLOSE,function(event)
|
||||
{
|
||||
console.log('rtc datachannel 关闭 :',event);
|
||||
});
|
||||
}
|
||||
|
||||
function start()
|
||||
{
|
||||
stop();
|
||||
let elr = document.getElementById("resolution");
|
||||
let res = elr.options[elr.selectedIndex].text.match(/\d+/g);
|
||||
let h = parseInt(res.pop());
|
||||
let w = parseInt(res.pop());
|
||||
|
||||
if(document.getElementById('useCamera').checked && !recvOnly)
|
||||
{
|
||||
ZLMRTCClient.isSupportResolution(w,h).then(e=>{
|
||||
start_play();
|
||||
}).catch(e=>{
|
||||
alert("not support resolution");
|
||||
});
|
||||
}else{
|
||||
start_play();
|
||||
}
|
||||
}
|
||||
|
||||
function stop()
|
||||
{
|
||||
if(player)
|
||||
{
|
||||
player.close();
|
||||
player = null;
|
||||
var remote = document.getElementById('video');
|
||||
if(remote)
|
||||
{
|
||||
remote.srcObject = null;
|
||||
remote.load();
|
||||
}
|
||||
var local = document.getElementById('selfVideo');
|
||||
local.srcObject = null;
|
||||
local.load();
|
||||
}
|
||||
}
|
||||
|
||||
function send(){
|
||||
if(player){
|
||||
//send msg refernece https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/send
|
||||
player.sendMsg(document.getElementById('msgsend').value);
|
||||
}
|
||||
}
|
||||
|
||||
function close(){
|
||||
if(player){
|
||||
player.closeDataChannel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function on_click_to_play(app, stream) {
|
||||
console.log(`on_click_to_play: ${app}/${stream}`);
|
||||
var url = `${document.location.protocol}//${window.location.host}/index/api/webrtc?app=${app}&stream=${stream}&type=play`;
|
||||
document.getElementById('streamUrl').value = url;
|
||||
start();
|
||||
}
|
||||
function clearStreamList() {
|
||||
let content = document.getElementById("olstreamlist");
|
||||
while (content.hasChildNodes()) {
|
||||
content.removeChild(content.firstChild);
|
||||
}
|
||||
}
|
||||
function fillStreamList(json) {
|
||||
clearStreamList();
|
||||
if (json.code != 0 || !json.data) {
|
||||
return;
|
||||
}
|
||||
let ss = {};
|
||||
for (let o of json.data) {
|
||||
if (ss[o.app]) {
|
||||
ss[o.app].add(o.stream);
|
||||
} else {
|
||||
let set = new Set();
|
||||
set.add(o.stream);
|
||||
ss[o.app] = set;
|
||||
}
|
||||
}
|
||||
|
||||
for (let o in ss) {
|
||||
let app = o;
|
||||
for (let s of ss[o]) {
|
||||
if (s) {
|
||||
//console.log(app, s);
|
||||
let content = document.getElementById("olstreamlist");
|
||||
let child = `<li app="${app}" stream="${s}" onmouseover="this.style.color='blue';" onclick="on_click_to_play('${app}', '${s}')">${app}/${s}</li>`;
|
||||
content.insertAdjacentHTML("beforeend", child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
async function getData(url) {
|
||||
const response = await fetch(url, {
|
||||
method: 'GET'
|
||||
});
|
||||
const data = await response.json();
|
||||
//console.log(data);
|
||||
return data;
|
||||
}
|
||||
function get_media_list() {
|
||||
let url = document.location.protocol+"//"+window.location.host+"/index/api/getMediaList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc";
|
||||
let json = getData(url);
|
||||
json.then((json)=> fillStreamList(json));
|
||||
}
|
||||
setInterval(() => {
|
||||
// get_media_list();
|
||||
}, 5000);
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
@ -1,123 +0,0 @@
|
||||
class WebRtcPlayer {
|
||||
static server = '127.0.0.1:8083';
|
||||
webrtc = null;
|
||||
video = null;
|
||||
server = null;
|
||||
codecLink = null;
|
||||
rsdpLink = null;
|
||||
stream = new MediaStream();
|
||||
uuid = null;
|
||||
options={
|
||||
onStatusChange:null
|
||||
};
|
||||
|
||||
constructor(video1, uuid, options={}) {
|
||||
console.log("new uuid:"+uuid)
|
||||
this.server = WebRtcPlayer.server;
|
||||
//this.video = document.getElementById(id);
|
||||
this.video = video1
|
||||
this.uuid = uuid;
|
||||
Object.assign(this.options, options);
|
||||
this.createLinks();
|
||||
this.play();
|
||||
}
|
||||
|
||||
createLinks() {
|
||||
this.codecLink = "//" + this.server + "/stream/codec/" + this.uuid
|
||||
this.rsdpLink = "//" + this.server + "/stream/receiver/" + this.uuid
|
||||
}
|
||||
|
||||
play() {
|
||||
this.webrtc = new RTCPeerConnection({
|
||||
iceServers: [{
|
||||
urls: ["stun:stun.l.google.com:19302"]
|
||||
}]
|
||||
});
|
||||
if(this.webrtc){
|
||||
|
||||
}else{
|
||||
console.log("no")
|
||||
}
|
||||
this.webrtc.onnegotiationneeded = this.handleNegotiationNeeded.bind(this);
|
||||
this.webrtc.ontrack = this.onTrack.bind(this);
|
||||
fetch(this.codecLink)
|
||||
.then((response) => {
|
||||
response.json().then((data) => {
|
||||
data.forEach((item, i) => {
|
||||
this.webrtc.addTransceiver(item.Type, {
|
||||
'direction': 'sendrecv'
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
|
||||
this.webrtc.onconnectionstatechange = () => {
|
||||
if(this.webrtc.connectionState == 'connected' || this.webrtc.connectionState == 'connecting'){
|
||||
console.log("uuid:"+this.uuid+" status:" + this.webrtc.connectionState)
|
||||
}else{
|
||||
console.log(this.webrtc.connectionState)
|
||||
this.load(this.uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async handleNegotiationNeeded() {
|
||||
let offer = await this.webrtc.createOffer();
|
||||
await this.webrtc.setLocalDescription(offer);
|
||||
let formData = new FormData();
|
||||
formData.append('suuid', this.uuid);
|
||||
formData.append('data', btoa(this.webrtc.localDescription.sdp));
|
||||
fetch(this.rsdpLink, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then((response) => {
|
||||
response.text().then((data) => {
|
||||
this.webrtc.setRemoteDescription(new RTCSessionDescription({
|
||||
type: 'answer',
|
||||
sdp: atob(data)
|
||||
}))
|
||||
});
|
||||
})
|
||||
.catch((err) => {})
|
||||
}
|
||||
|
||||
onTrack(event) {
|
||||
this.stream.addTrack(event.track);
|
||||
this.video.srcObject = this.stream;
|
||||
this.video.play();
|
||||
}
|
||||
|
||||
load(uuid) {
|
||||
this.destroy();
|
||||
this.uuid = uuid;
|
||||
this.createLinks();
|
||||
this.play();
|
||||
}
|
||||
|
||||
destroy() {
|
||||
console.log("destroy uuid:"+this.uuid)
|
||||
this.webrtc.close();
|
||||
this.webrtc = null;
|
||||
this.video.srcObject = null;
|
||||
this.stream = new MediaStream();
|
||||
}
|
||||
|
||||
getImageUrl() {
|
||||
let canvas = document.createElement("canvas");
|
||||
canvas.width = this.video.videoWidth;
|
||||
canvas.height = this.video.videoHeight;
|
||||
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
let dataURL = canvas.toDataURL();
|
||||
canvas.remove();
|
||||
return dataURL;
|
||||
}
|
||||
|
||||
static setServer(serv) {
|
||||
this.server = serv;
|
||||
}
|
||||
}
|
||||
export default WebRtcPlayer;
|
||||
@ -0,0 +1,318 @@
|
||||
<template>
|
||||
<div class="history bg-white">
|
||||
<div class="ant-advanced-search-form">
|
||||
<a-form layout="inline" :form="queryParam">
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="4">
|
||||
<a-form-item label="巷道">
|
||||
<a-select @change="handleChange" v-model="select" style="width:100px">
|
||||
<a-select-option v-for="i in listData" :key="i.name" :value="i.id">
|
||||
{{i.name}}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
</a-col>
|
||||
<a-col :span="2">
|
||||
<a-form-item label="左右">
|
||||
<a-select v-model="queryParam.leftRight" @change="leftRightChange" >
|
||||
<a-select-option :value=0>
|
||||
未选择
|
||||
</a-select-option>
|
||||
<a-select-option :value=1>
|
||||
左侧
|
||||
</a-select-option>
|
||||
<a-select-option :value=2>
|
||||
右侧
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
</a-col>
|
||||
<a-col :span="2">
|
||||
<a-form-item label="深浅" v-if="queryParam.side >= 0">
|
||||
<a-select style="width: 50px" :key="queryParam.side" >
|
||||
<a-select-option :key=0>
|
||||
未选择
|
||||
</a-select-option>
|
||||
<a-select-option :key=1>
|
||||
浅
|
||||
</a-select-option>
|
||||
<a-select-option :key=2>
|
||||
深
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="2" style="text-align: left">
|
||||
<a-form-item label="行号">
|
||||
<a-input v-model="queryParam.row" placeholder="请输入" style="width:50px;" type="number"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="2" style="text-align: left">
|
||||
<a-form-item label="列号">
|
||||
<a-input v-model="queryParam.column" placeholder="请输入" style="width:50px;" type="number"/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="4" style="text-align: left">
|
||||
<a-form-item label="盘点号">
|
||||
<a-input v-model="queryParam.lotnum" placeholder="请输入" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="4">
|
||||
<a-form-item label="时间">
|
||||
<a-range-picker
|
||||
@change="onTimeChange"
|
||||
v-model="time"
|
||||
format="YYYY-MM-DD HH:mm"
|
||||
:show-time="{
|
||||
defaultValue: [moment('00:00', 'HH:mm'), moment('23:59', 'HH:mm')],
|
||||
//defaultValue: [moment('00:00', 'YYYY-MM-DD HH:mm'), moment('23:59', 'YYYY-MM-DD HH:mm')],
|
||||
}">
|
||||
<a-icon slot="suffixIcon" type="calendar"/>
|
||||
</a-range-picker>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="4" style="text-align: right">
|
||||
<a-button type="primary" @click="handleSearch">搜索</a-button>
|
||||
<a-button style="margin-left: 15px" @click="reset">重置</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:row-key="record => record.id"
|
||||
:data-source="data"
|
||||
:pagination="pagination"
|
||||
@change="handleGetHistoryList"
|
||||
>
|
||||
<span slot="checkNum" slot-scope="text">
|
||||
{{ text }}
|
||||
</span>
|
||||
<span slot="goodsLocation" slot-scope="text">
|
||||
{{ text.direction == 1 ?"左":"右"}}-{{ text.side == 1 ?"浅":"深"}}-{{ text.row}}-{{ text.column}}
|
||||
</span>
|
||||
<span slot="status" slot-scope="text">
|
||||
{{ statusMap[text.status] }}
|
||||
</span>
|
||||
<span slot="pic" slot-scope="text" style="width:auto">
|
||||
|
||||
<template>
|
||||
<span style="height:100%;">
|
||||
<happy-scroll color="rgba(100,100,100,0.5)" size="8" class="scroll-box" style="width:320px;height:90px;">
|
||||
<viewer><img class="historyImg" :src="imgUrl+text.pic"/></viewer>
|
||||
</happy-scroll>
|
||||
</span>
|
||||
|
||||
</template>
|
||||
|
||||
</span>
|
||||
</a-table>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {imgUrl} from "@/api/importExcel";
|
||||
import moment from 'moment';
|
||||
export default {
|
||||
name: "historyCheck",
|
||||
data() {
|
||||
return {
|
||||
statusMap: {0:"未盘点",1:"盘点异常",2:"核对正确",3:"人工核对正确"},
|
||||
queryParam: {
|
||||
lotnum: '',
|
||||
side : '',
|
||||
leftRight : ''
|
||||
},
|
||||
listData:[],
|
||||
time:[],
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
data: [],
|
||||
|
||||
select: '',
|
||||
pagination:{
|
||||
total: 0,
|
||||
defaultPageSize: 10, // 默认每页显示数量
|
||||
showTotal: total => `共 ${total} 条数据`,// 显示总数
|
||||
showSizeChanger: true, // 显示可改变每页数量
|
||||
pageSizeOptions: ['10', '20', '30'],
|
||||
onShowSizeChange: (current, pageSize) => this.pageSize = pageSize // 改变每页数量时更新显示
|
||||
},
|
||||
imgUrl: imgUrl,
|
||||
columns: [
|
||||
{
|
||||
title: "盘点批次号",
|
||||
dataIndex: "lotnum",
|
||||
},
|
||||
{
|
||||
title: "巷道名称",
|
||||
dataIndex: "streetName",
|
||||
},
|
||||
{
|
||||
title: "货位({左右}-{深浅}-{行}-{列})",
|
||||
scopedSlots: {customRender: 'goodsLocation'},
|
||||
},
|
||||
|
||||
{
|
||||
title: "盘点状态",
|
||||
scopedSlots: {customRender: 'status'},
|
||||
},
|
||||
{
|
||||
title: "照片",
|
||||
scopedSlots: {customRender: 'pic'},
|
||||
width:320,
|
||||
},
|
||||
{
|
||||
title: "更新时间",
|
||||
dataIndex: "createTime",
|
||||
},
|
||||
|
||||
],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getStreetList();
|
||||
this.handleSearch();
|
||||
},
|
||||
methods: {
|
||||
moment,
|
||||
//获取巷道列表
|
||||
getStreetList() {
|
||||
this.$api.httpApi.getAllStreet({
|
||||
}).then(res => {
|
||||
this.listData = res.data;
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
},
|
||||
//获取巷道详情
|
||||
getStreetDetail(id) {
|
||||
this.$axios.get('/street/' + id, {
|
||||
data: {}
|
||||
}).then(res => {
|
||||
this.streetDetail = res.data
|
||||
this.select = this.streetDetail.name;
|
||||
this.queryParam.streetId = this.streetDetail.id;
|
||||
}).catch(err => {
|
||||
|
||||
})
|
||||
},
|
||||
handleChange(value) {
|
||||
this.getStreetDetail(value)
|
||||
this.queryParam.leftRight = ''
|
||||
this.queryParam.side = ''
|
||||
|
||||
},
|
||||
// 左右货架切换
|
||||
leftRightChange(value) {
|
||||
if (value == 1) {
|
||||
//单伸
|
||||
if(this.streetDetail.leftType == 0){
|
||||
this.queryParam.side = ''
|
||||
}else{
|
||||
this.queryParam.side = 0
|
||||
}
|
||||
} else if (value == 2) {
|
||||
if(this.streetDetail.rightType == 0){
|
||||
this.queryParam.side = ''
|
||||
}else{
|
||||
this.queryParam.side = 0
|
||||
|
||||
}
|
||||
} else{
|
||||
this.queryParam.side = ''
|
||||
}
|
||||
},
|
||||
handleSearch() {
|
||||
console.log(this.queryParam)
|
||||
this.pageNum = 1
|
||||
this.request()
|
||||
},
|
||||
handleGetHistoryList(pagination) {
|
||||
console.log(pagination)
|
||||
if(pagination){
|
||||
this.pagination.current = pagination.current;
|
||||
this.pagination.pageSize = pagination.pageSize;
|
||||
this.pageNum = pagination.current;
|
||||
this.pageSize = pagination.pageSize;
|
||||
}
|
||||
this.request();
|
||||
},
|
||||
request() {
|
||||
this.$api.httpApi.checkLog({
|
||||
data: {
|
||||
pageNum: this.pageNum,
|
||||
pageSize: this.pageSize,
|
||||
...this.queryParam
|
||||
}
|
||||
}).then(res => {
|
||||
console.log(res.data)
|
||||
const pagination = {...this.pagination};
|
||||
pagination.total = res.data.total;
|
||||
this.pagination = pagination;
|
||||
this.data = res.data.list
|
||||
}).catch(err => {
|
||||
|
||||
});
|
||||
},
|
||||
onTimeChange(date, dateString) {
|
||||
this.handleReset()
|
||||
console.log(date)
|
||||
console.log(dateString)
|
||||
console.log(date[0].format('YYYY-MM-DD HH:mm'))
|
||||
this.pageNum = 1
|
||||
|
||||
this.queryParam.startTimestamp = date[0].format('YYYY-MM-DD HH:mm:ss')
|
||||
this.queryParam.endTimestamp = date[1].format('YYYY-MM-DD HH:mm:ss')
|
||||
},
|
||||
handleReset() {
|
||||
this.queryParam.startTimestamp = ""
|
||||
this.queryParam.endTimestamp = ""
|
||||
this.pageNum = 1
|
||||
|
||||
},
|
||||
reset() {
|
||||
this.queryParam.startTimestamp = ""
|
||||
this.queryParam.endTimestamp = ""
|
||||
this.queryParam.lotnum = ""
|
||||
this.queryParam.side = ''
|
||||
this.queryParam.leftRight = ''
|
||||
this.queryParam.streetId = 0
|
||||
this.select = null;
|
||||
this.time = []
|
||||
this.pageNum = 1
|
||||
this.pageSize = 10
|
||||
this.queryParam.row = null
|
||||
this.queryParam.column = null
|
||||
this.request()
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.history {
|
||||
padding: 24px;
|
||||
}
|
||||
.ant-drawer-content-wrapper {
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.ant-drawer-body {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ant-advanced-search-form .ant-form-item {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.historyImg {
|
||||
width: 80px;
|
||||
height:auto;
|
||||
margin: 5px;
|
||||
}
|
||||
</style>
|
||||
@ -1,123 +0,0 @@
|
||||
class WebRtcPlayer {
|
||||
static server = '127.0.0.1:8083';
|
||||
webrtc = null;
|
||||
video = null;
|
||||
server = null;
|
||||
codecLink = null;
|
||||
rsdpLink = null;
|
||||
stream = new MediaStream();
|
||||
uuid = null;
|
||||
options={
|
||||
onStatusChange:null
|
||||
};
|
||||
|
||||
constructor(video1, uuid, options={}) {
|
||||
console.log("new uuid:"+uuid)
|
||||
this.server = WebRtcPlayer.server;
|
||||
//this.video = document.getElementById(id);
|
||||
this.video = video1
|
||||
this.uuid = uuid;
|
||||
Object.assign(this.options, options);
|
||||
this.createLinks();
|
||||
this.play();
|
||||
}
|
||||
|
||||
createLinks() {
|
||||
this.codecLink = "//" + this.server + "/stream/codec/" + this.uuid
|
||||
this.rsdpLink = "//" + this.server + "/stream/receiver/" + this.uuid
|
||||
}
|
||||
|
||||
play() {
|
||||
this.webrtc = new RTCPeerConnection({
|
||||
iceServers: [{
|
||||
urls: ["stun:stun.l.google.com:19302"]
|
||||
}]
|
||||
});
|
||||
if(this.webrtc){
|
||||
|
||||
}else{
|
||||
console.log("no")
|
||||
}
|
||||
this.webrtc.onnegotiationneeded = this.handleNegotiationNeeded.bind(this);
|
||||
this.webrtc.ontrack = this.onTrack.bind(this);
|
||||
fetch(this.codecLink)
|
||||
.then((response) => {
|
||||
response.json().then((data) => {
|
||||
data.forEach((item, i) => {
|
||||
this.webrtc.addTransceiver(item.Type, {
|
||||
'direction': 'sendrecv'
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
|
||||
this.webrtc.onconnectionstatechange = () => {
|
||||
if(this.webrtc.connectionState == 'connected' || this.webrtc.connectionState == 'connecting'){
|
||||
console.log("uuid:"+this.uuid+" status:" + this.webrtc.connectionState)
|
||||
}else{
|
||||
console.log(this.webrtc.connectionState)
|
||||
this.load(this.uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async handleNegotiationNeeded() {
|
||||
let offer = await this.webrtc.createOffer();
|
||||
await this.webrtc.setLocalDescription(offer);
|
||||
let formData = new FormData();
|
||||
formData.append('suuid', this.uuid);
|
||||
formData.append('data', btoa(this.webrtc.localDescription.sdp));
|
||||
fetch(this.rsdpLink, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then((response) => {
|
||||
response.text().then((data) => {
|
||||
this.webrtc.setRemoteDescription(new RTCSessionDescription({
|
||||
type: 'answer',
|
||||
sdp: atob(data)
|
||||
}))
|
||||
});
|
||||
})
|
||||
.catch((err) => {})
|
||||
}
|
||||
|
||||
onTrack(event) {
|
||||
this.stream.addTrack(event.track);
|
||||
this.video.srcObject = this.stream;
|
||||
this.video.play();
|
||||
}
|
||||
|
||||
load(uuid) {
|
||||
this.destroy();
|
||||
this.uuid = uuid;
|
||||
this.createLinks();
|
||||
this.play();
|
||||
}
|
||||
|
||||
destroy() {
|
||||
console.log("destroy uuid:"+this.uuid)
|
||||
this.webrtc.close();
|
||||
this.webrtc = null;
|
||||
this.video.srcObject = null;
|
||||
this.stream = new MediaStream();
|
||||
}
|
||||
|
||||
getImageUrl() {
|
||||
let canvas = document.createElement("canvas");
|
||||
canvas.width = this.video.videoWidth;
|
||||
canvas.height = this.video.videoHeight;
|
||||
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
let dataURL = canvas.toDataURL();
|
||||
canvas.remove();
|
||||
return dataURL;
|
||||
}
|
||||
|
||||
static setServer(serv) {
|
||||
this.server = serv;
|
||||
}
|
||||
}
|
||||
export default WebRtcPlayer;
|
||||
@ -0,0 +1,276 @@
|
||||
<template>
|
||||
<div class="subsection">
|
||||
<a-layout style="width: 1500px">
|
||||
<a-layout style="width: 100%;height: 310px">
|
||||
<a-layout-sider width="110px">
|
||||
<a-tabs default-active-key="1" tab-position="left" @change="changeTabLeft" v-if="total.row > nums.row">
|
||||
<a-tab-pane
|
||||
v-for="index in latticeRow"
|
||||
:key="index"
|
||||
>
|
||||
<span slot="tab" >
|
||||
{{ getRandom(latticeRow + 1 -index, latticeRow, nums.row, total.row) }}
|
||||
</span>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-layout-sider>
|
||||
<a-layout-content>
|
||||
<!-- <slot :data="{select, nums, random}"></slot> -->
|
||||
<div class="roadway-buttom">
|
||||
<div class="roadway-box">
|
||||
|
||||
<div class="line" v-for="(row,rowIndex) in total.row" :key="rowIndex" v-if="row >= random.row[0] && row <= random.row[1]">
|
||||
<div v-for="(column,index) in total.column" :key="index" class="el" v-if="column >= random.column[0] && column <= random.column[1]">
|
||||
|
||||
<!--渲染默认巷道框架规格 定位浮在 已有巷道上做对应-->
|
||||
<span style="background:#bfbfbf;"
|
||||
class="default"
|
||||
:id="`${direction}-${side}-${random.row[0] + random.row[1] - rowIndex - 1}-${column}`"
|
||||
@click="toStockPage(random.row[0] + random.row[1] - rowIndex - 1,column)">
|
||||
{{ random.row[0] + random.row[1] - rowIndex - 1}}-{{column}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-layout-content>
|
||||
</a-layout>
|
||||
<a-layout-footer>
|
||||
<!-- <a-tabs default-active-key="1" tab-position="bottom" @change="value => select.row = value" v-if="total.row > nums.row"> -->
|
||||
<a-tabs default-active-key="1" tab-position="bottom" @change="changeTab" v-if="total.column > nums.column">
|
||||
<a-tab-pane
|
||||
v-for="index in latticeColumn"
|
||||
:key="index"
|
||||
>
|
||||
<span slot="tab">
|
||||
{{ getRandom(index, latticeColumn, nums.column, total.column) }}
|
||||
</span>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-layout-footer>
|
||||
</a-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Subsection",
|
||||
components: {},
|
||||
props: {
|
||||
// 默认行第一个 列第一个
|
||||
select: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
row: 1,
|
||||
column: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
// 总共数据
|
||||
total:{
|
||||
type: Object,
|
||||
default:()=>{
|
||||
return {}
|
||||
}
|
||||
},
|
||||
nums: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
row: 10,
|
||||
column: 15
|
||||
}
|
||||
}
|
||||
},
|
||||
//左右
|
||||
direction:{
|
||||
type: Number,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
//深浅
|
||||
side:{
|
||||
type: Number,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
streetId: {
|
||||
type: Number,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
streetName: {
|
||||
type: String,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
computed: {
|
||||
// 应有的格子数
|
||||
latticeRow() {
|
||||
return parseInt(this.total.row / this.nums.row) + (this.total.row % this.nums.row > 0 ? 1 : 0);
|
||||
},
|
||||
latticeColumn() {
|
||||
return parseInt(this.total.column / this.nums.column) + (this.total.column % this.nums.column > 0 ? 1 : 0);
|
||||
},
|
||||
random() {
|
||||
|
||||
return {
|
||||
|
||||
row: this.getRandomRow(this.select.row),
|
||||
column: this.getRandomColumn(this.select.column),
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
status: {
|
||||
row: {},
|
||||
column: {}
|
||||
},
|
||||
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
destroyed() {
|
||||
|
||||
},
|
||||
|
||||
methods: {
|
||||
changeTab(value){
|
||||
this.select.column = value
|
||||
|
||||
},
|
||||
changeTabLeft(value){
|
||||
this.select.row = value
|
||||
|
||||
|
||||
},
|
||||
// 获取行或列的范围字符串
|
||||
getRandom(index, lattice, num, total) {
|
||||
if(index !== lattice) {
|
||||
return `${(index - 1) * num + 1} - ${index * num}`;
|
||||
}else {
|
||||
return `${(index - 1) * num + 1} - ${total}`;
|
||||
}
|
||||
},
|
||||
// 获取行和列的范围数组
|
||||
getRandomRow(val) {
|
||||
console.log(this.latticeRow + 1 - val, this.latticeRow, this.nums.row, this.total.row)
|
||||
return this.getRandom(this.latticeRow + 1 - val, this.latticeRow, this.nums.row, this.total.row).split(' - ').map(item => Number(item));
|
||||
},
|
||||
getRandomColumn(val) {
|
||||
return this.getRandom(val, this.latticeColumn, this.nums.column, this.total.column).split(' - ').map(item => Number(item));
|
||||
},
|
||||
|
||||
toStockPage(row,column){
|
||||
this.$router.push({
|
||||
name: 'stockLogDetail',
|
||||
query: {row: row, column: column, direction: this.direction,side:this.side,streetId:this.streetId}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.subsection /deep/{
|
||||
width: 100%;
|
||||
height: 360px;
|
||||
overflow: hidden;
|
||||
.ant-tabs-nav .ant-tabs-tab {
|
||||
// padding: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) {
|
||||
&:hover{
|
||||
background: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
}
|
||||
background: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
box-shadow: -1px 0 0 0 #40a9ff;
|
||||
}
|
||||
.ant-radio-button-wrapper-checked {
|
||||
box-shadow: -1px 0 0 0 #40a9ff;
|
||||
}
|
||||
.radio-button-cell {
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
.ant-layout-sider {
|
||||
height: 100%;
|
||||
.ant-tabs {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.ant-tabs-tab {
|
||||
padding: 8px;
|
||||
margin-bottom: 5px;
|
||||
width: 104px;
|
||||
}
|
||||
}
|
||||
.ant-layout-footer {
|
||||
// width: 500px;
|
||||
padding: 0 0 0 110px;
|
||||
.ant-tabs {
|
||||
// width: 735px;
|
||||
}
|
||||
.ant-tabs-bottom-bar {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
.ant-layout, .ant-layout-sider, .ant-layout-footer {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
roadway-buttom {
|
||||
padding: 5px 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.roadway-box {
|
||||
//transform: rotateX(180deg);
|
||||
padding: 10px 10px 0 0;
|
||||
.line {
|
||||
display: flex;
|
||||
//transform: rotateX(180deg); //两次垂直镜像翻转让原本由上到下排列的div 更改为由下到上
|
||||
|
||||
.el {
|
||||
width: 46px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
margin: 2px;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
.default {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,215 @@
|
||||
<template>
|
||||
<div class="check-page">
|
||||
|
||||
<div style="margin-top: 10px">
|
||||
<a-select @change="handleChange" style="width:200px" v-model="select">
|
||||
<a-select-option v-for="i in data" :key="i.name" :value="i.id">
|
||||
{{i.name}}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
|
||||
|
||||
<!--左货架DOM-->
|
||||
<div class="center-box">
|
||||
<span class="shelf-number">
|
||||
左侧货架
|
||||
</span>
|
||||
|
||||
<a-radio-group v-model="leftSide" style="margin:10px 0"
|
||||
v-if="streetDetail.leftType==1">
|
||||
<a-radio-button :value=1>
|
||||
浅货架
|
||||
</a-radio-button>
|
||||
<a-radio-button :value=2>
|
||||
深货架
|
||||
</a-radio-button>
|
||||
|
||||
</a-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="check-content" v-for="item in data" :key="item.id">
|
||||
<subsection v-if="item.id == select" :total="{row: item.leftRow, column: item.leftColumn}" :direction=1 :side="leftSide" :streetId="item.id" :streetName="item.name">
|
||||
</subsection>
|
||||
</div>
|
||||
|
||||
|
||||
<!--单伸类型右货架DOM-->
|
||||
<div class="center-box">
|
||||
<span class="shelf-number">
|
||||
右侧货架
|
||||
</span>
|
||||
|
||||
<a-radio-group v-model="rightSide" style="margin:10px 0"
|
||||
v-if="streetDetail.rightType==1">
|
||||
<a-radio-button :value=1>
|
||||
浅货架
|
||||
</a-radio-button>
|
||||
<a-radio-button :value=2>
|
||||
深货架
|
||||
</a-radio-button>
|
||||
|
||||
</a-radio-group>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="check-content" v-for="item in data" :key="item.name">
|
||||
<subsection v-if="item.id == select" :total="{row:item.rightRow, column: item.rightColumn}" :direction=2 :side="rightSide" :streetId="item.id" :streetName="item.name" >
|
||||
</subsection>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Subsection from "./Subsection";
|
||||
export default {
|
||||
name:'checkManage',
|
||||
data() {
|
||||
return {
|
||||
leftSide: 1,
|
||||
rightSide: 1,
|
||||
data: [],
|
||||
select: '',
|
||||
streetId: 0,
|
||||
streetDetail: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.request();
|
||||
},
|
||||
created(){
|
||||
|
||||
},
|
||||
activated() {
|
||||
if(!this.$route.meta.isUseCache){
|
||||
console.log("$route.meta.isUseCache false")
|
||||
// 清空原有数据
|
||||
this.request();// 这是我们获取数据的函数
|
||||
}else{
|
||||
console.log("$route.meta.isUseCache true")
|
||||
//this.request();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
//获取巷道列表
|
||||
request() {
|
||||
this.$api.httpApi.getAllStreet({
|
||||
}).then(res => {
|
||||
console.log("update data")
|
||||
for(let i = 0;i<res.data.length;i++){
|
||||
|
||||
this.$set(this.data,i,res.data[i])
|
||||
}
|
||||
this.select = res.data[0].id
|
||||
//this.$set(this.select,res.data.list[0].id,0)
|
||||
this.getStreetDetail(this.select);
|
||||
}).catch(err => {
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
//获取巷道详情
|
||||
getStreetDetail(id) {
|
||||
this.$axios.get('/street/' + id, {
|
||||
data: {}
|
||||
}).then(res => {
|
||||
this.streetDetail = res.data
|
||||
}).catch(err => {
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
handleChange(value) {
|
||||
|
||||
this.select = value
|
||||
|
||||
this.getStreetDetail(value)
|
||||
},
|
||||
|
||||
},
|
||||
components: {Subsection}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.check-page {
|
||||
position: relative;
|
||||
|
||||
.title-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: start;
|
||||
|
||||
.explain {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.info-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-tag {
|
||||
margin-right: 0;
|
||||
display: block;
|
||||
line-height: 25px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.roadway-top, roadway-buttom {
|
||||
padding: 5px 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.roadway-box {
|
||||
transform: rotateX(180deg);
|
||||
padding: 10px 10px 0 0;
|
||||
.line {
|
||||
display: flex;
|
||||
transform: rotateX(180deg); //两次垂直镜像翻转让原本由上到下排列的div 更改为由下到上
|
||||
|
||||
.el {
|
||||
width: 46px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
margin: 2px;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
.default {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.center-box {
|
||||
width: 500px;
|
||||
height: 52px;
|
||||
line-height: 52px;
|
||||
.shelf-number {
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
.export-all {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,272 @@
|
||||
<template>
|
||||
<div >
|
||||
<a-table
|
||||
style="margin-top:40px"
|
||||
:columns="columns"
|
||||
:row-key="record => record.id"
|
||||
:data-source="data"
|
||||
:pagination="pagination"
|
||||
@change="getStockPageInfo"
|
||||
>
|
||||
<span slot="type" slot-scope="record">
|
||||
{{ statusMap[record.type] }}
|
||||
</span>
|
||||
<span slot="pic" slot-scope="text" style="width:auto">
|
||||
|
||||
<template>
|
||||
<span style="height:100%;">
|
||||
<happy-scroll color="rgba(100,100,100,0.5)" size="8" class="scroll-box" style="width:320px;height:90px;">
|
||||
<viewer><img class="historyImg" :src="imgUrl+text.pic"/></viewer>
|
||||
</happy-scroll>
|
||||
</span>
|
||||
|
||||
</template>
|
||||
|
||||
</span>
|
||||
</a-table>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {imgUrl} from "@/api/importExcel";
|
||||
const columns=[
|
||||
{
|
||||
title:'随行工单号',
|
||||
dataIndex: 'orderNum'
|
||||
},
|
||||
{
|
||||
title:'货架号',
|
||||
dataIndex: 'shelveId'
|
||||
},
|
||||
{
|
||||
title:'行',
|
||||
dataIndex: 'row'
|
||||
},
|
||||
{
|
||||
title:'列',
|
||||
dataIndex: 'column'
|
||||
},
|
||||
{
|
||||
title:'类型',
|
||||
|
||||
scopedSlots: {customRender: 'type'},
|
||||
},
|
||||
{
|
||||
title:'图片',
|
||||
scopedSlots: {customRender: 'pic'},
|
||||
},
|
||||
{
|
||||
title:'时间',
|
||||
dataIndex: 'createTime'
|
||||
},
|
||||
]
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pageNum:1,
|
||||
pageSize:10,
|
||||
data: [],
|
||||
pagination:{
|
||||
total:0,
|
||||
defaultPageSize:10, // 默认每页显示数量
|
||||
showTotal: total => `共 ${total} 条数据`, // 显示总数
|
||||
showSizeChanger:true, // 显示可改变每页数量
|
||||
pageSizeOptions: ['10', '20', '30'],
|
||||
onShowSizeChange:(current, pageSize)=>this.pageSize = pageSize // 改变每页数量时更新显示
|
||||
},
|
||||
row: 0,
|
||||
column: 0,
|
||||
direction:0,
|
||||
side:0,
|
||||
columns,
|
||||
statusMap: {0:"未知",1:"取货到位",2:"取货完成",3:"放货到位",4:"放货完成"},
|
||||
|
||||
}
|
||||
},
|
||||
beforeRouteLeave(to ,form, next) {
|
||||
// 修复第二次进入界面不执行created
|
||||
this.$destroy();
|
||||
// if (to.name == 'checkManage') {
|
||||
// to.meta.isUseCache = true;
|
||||
// }else{
|
||||
// to.meta.isUseCache = false;
|
||||
// }
|
||||
next();
|
||||
},
|
||||
created() {
|
||||
this.imgUrl = imgUrl
|
||||
if (this.$route.query.row && this.$route.query.column && this.$route.query.side && this.$route.query.direction && this.$route.query.streetId) {
|
||||
|
||||
this.row = this.$route.query.row
|
||||
this.column = this.$route.query.column
|
||||
this.side = this.$route.query.side
|
||||
this.direction = this.$route.query.direction
|
||||
this.streetId = this.$route.query.streetId
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getStockPageInfo()
|
||||
},
|
||||
destroyed () {
|
||||
|
||||
},
|
||||
|
||||
methods: {
|
||||
getStockPageInfo(pagination) {
|
||||
if(pagination){
|
||||
this.pagination.current = pagination.current;
|
||||
this.pagination.pageSize = pagination.pageSize;
|
||||
this.pageNum = pagination.current;
|
||||
this.pageSize = pagination.pageSize;
|
||||
}
|
||||
|
||||
this.request();
|
||||
},
|
||||
request(){
|
||||
this.$api.httpApi.getStockPage({
|
||||
data: {
|
||||
pageNum:this.pageNum,
|
||||
pageSize:this.pageSize,
|
||||
row:this.row,
|
||||
column:this.column,
|
||||
side:this.side,
|
||||
direction:this.direction,
|
||||
streetId:this.streetId
|
||||
}
|
||||
}).then(res => {
|
||||
const pagination = { ...this.pagination };
|
||||
pagination.total = res.data.total;
|
||||
this.data = res.data.list;
|
||||
this.pagination = pagination;
|
||||
}).catch(err => {
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.ant-carousel .slick-slide {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.checkOperation {
|
||||
.carousel-page {
|
||||
width: 100%;
|
||||
/*border: solid 1px blue;*/
|
||||
&-title {
|
||||
color: #009FE3;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
padding: 15px 0 10px 25px;
|
||||
}
|
||||
|
||||
&-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 25px;
|
||||
|
||||
.img-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
font-size: 17px;
|
||||
height: 400px;
|
||||
margin-right: 10px;
|
||||
img {
|
||||
height: 100%
|
||||
}
|
||||
|
||||
p {
|
||||
height: 25px;
|
||||
}
|
||||
ul {
|
||||
width: 100% / 4;
|
||||
height: 100%;
|
||||
margin-bottom: 0;
|
||||
padding-inline-start: 0;
|
||||
li {
|
||||
background-color: #ffaf11;
|
||||
margin: 10px 0;
|
||||
padding: 5px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #494e52;
|
||||
.img-box-title {
|
||||
width: 130px;
|
||||
display: inline-block;
|
||||
}
|
||||
.img-box-value {
|
||||
display: inline-block;
|
||||
width: calc(100% - 130px);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
top: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-footer {
|
||||
width: calc(100% - 380px);
|
||||
.info-box {
|
||||
color: #000000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
p {
|
||||
padding: 0 20px;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.status {
|
||||
text-align: center;
|
||||
font-size: 21px;
|
||||
}
|
||||
|
||||
.status-btn {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
|
||||
.btn {
|
||||
padding: 50px;
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: 0;
|
||||
margin: 15px 45px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-btn {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: right;
|
||||
justify-content: center;
|
||||
|
||||
p {
|
||||
font-size: 18px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.historyImg {
|
||||
width: 180px;
|
||||
height:auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -0,0 +1,321 @@
|
||||
<template>
|
||||
<div id="videos">
|
||||
<a-tree-select
|
||||
v-model="value"
|
||||
show-search
|
||||
style="width: 80%"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
placeholder="Please select"
|
||||
allow-clear
|
||||
multiple
|
||||
tree-default-expand-all
|
||||
>
|
||||
<a-tree-node key="0-1" value="parent 1" title="parent 1">
|
||||
<a-tree-node key="0-1-1" :selectable="false" value="parent 1-0" title="parent 1-0">
|
||||
<a-tree-node key="random" value="leaf1" title="my leaf" />
|
||||
<a-tree-node key="random1" value="leaf2" title="your leaf" />
|
||||
</a-tree-node>
|
||||
<a-tree-node key="random2" value="parent 1-1" title="parent 1-1">
|
||||
<a-tree-node key="random3" value="sss">
|
||||
<b slot="title" style="color: #08c">sss</b>
|
||||
</a-tree-node>
|
||||
</a-tree-node>
|
||||
</a-tree-node>
|
||||
<a-tree-node key="random2" value="leaqf1" title="my 1leaf" />
|
||||
<a-tree-node key="random13" value="leawf2" title="your2 leaf" />
|
||||
<a-tree-node key="random4" value="leaef1" title="my l3eaf" />
|
||||
<a-tree-node key="random15" value="learf2" title="your4 leaf" />
|
||||
<a-tree-node key="random6" value="leatf1" title="my 6leaf" />
|
||||
<a-tree-node key="random17" value="leayuf2" title="you5r leaf" />
|
||||
<a-tree-node key="random8" value="leauf1" title="my 7leaf" />
|
||||
<a-tree-node key="random19" value="loeaf2" title="yousr leaf" />
|
||||
<a-tree-node key="random0" value="lieaf1" title="myf leaf" />
|
||||
<a-tree-node key="randoma1" value="lexaf2" title="yodur leaf" />
|
||||
<a-tree-node key="randoms" value="leacf1" title="my cleaf" />
|
||||
<a-tree-node key="randoms1" value="leavf2" title="yobur leaf" />
|
||||
<a-tree-node key="randomd" value="lnaf1" title="mvy leaf" />
|
||||
<a-tree-node key="random1f" value="lebaf2" title="y our leaf" />
|
||||
<a-tree-node key="randomg" value="leamf1" title="myx leaf" />
|
||||
<a-tree-node key="random1h" value="leaff2" title="your leaf" />
|
||||
<a-tree-node key="randomz" value="wleaf2" title="your leaf" />
|
||||
<a-tree-node key="randomc" value="wleaf1" title="my cleaf" />
|
||||
<a-tree-node key="random1v" value="eleaf2" title="your levaf" />
|
||||
</a-tree-select>
|
||||
|
||||
<a-button type="primary" @click="full" v-if="!isFullscreen"> 全屏<a-icon type="right" /> </a-button>
|
||||
<a-button type="primary" @click="full" v-if="isFullscreen"><a-icon type="left" /> 退出全屏 </a-button>
|
||||
<!-- @change="tabsChange" v-model="tabKey"-->
|
||||
|
||||
<a-row v-for='rowIndex in row' :key='rowIndex'>
|
||||
<a-col v-for='colIndex in column' :key='colIndex' :span="24/column" :style="{height: videoHeight}" >
|
||||
<WebrtcPlayer
|
||||
v-if=" webrtcPlayers[rowIndex-1] !==undefined && webrtcPlayers[rowIndex-1] != null && webrtcPlayers[rowIndex-1].length > 0 && webrtcPlayers[rowIndex-1][colIndex-1] !==undefined && webrtcPlayers[rowIndex-1][colIndex-1] != null "
|
||||
autoplay class="video-window"
|
||||
:videoSrc="'http://127.0.0.1/index/api/webrtc?app=live&stream='+webrtcPlayers[rowIndex-1][colIndex-1].id+'&type=play'"
|
||||
:videoId="'videoId'+colIndex+'-'+rowIndex"
|
||||
ref="videoWindow"
|
||||
:key="colIndex+'-'+rowIndex"
|
||||
muted
|
||||
:style="{'height': '100%',width:'100%','object-fit':'fill'}">
|
||||
</WebrtcPlayer>
|
||||
<!-- <video class="camera" :id="rowIndex+'-'+colIndex" autoplay muted :style="{'height': '100%',width:'100%','object-fit':'fill'}" ></video> -->
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
//import ATreeSelect from "../../../public/static/webrtcplayer"
|
||||
import { TreeSelect } from 'ant-design-vue';
|
||||
import { defineComponent, ref, watch } from 'vue';
|
||||
|
||||
import WebrtcPlayer from '../../../public/webrtc/webrtcPlayer.vue'
|
||||
export default {
|
||||
name: 'top',
|
||||
components: {
|
||||
WebrtcPlayer,
|
||||
ATreeSelect: TreeSelect
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default () {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
row : 0,
|
||||
column : 0,
|
||||
value: undefined,
|
||||
treeExpandedKeys: [],
|
||||
a: 0,
|
||||
clientHeight: 0,
|
||||
videoH: 0,
|
||||
isFullscreen: false,
|
||||
originHeight: 0,
|
||||
fullHeight: 0,
|
||||
players: [],
|
||||
areas:[],
|
||||
webrtcPlayers: [],
|
||||
activeKey: ''
|
||||
}
|
||||
},
|
||||
//watch: {},
|
||||
computed: {
|
||||
videoHeight() {
|
||||
return( this.clientHeight/ this.row ) + 'px';
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
this.destory()
|
||||
},
|
||||
mounted () {
|
||||
this.getWallStyle();
|
||||
|
||||
this.$nextTick(() => {
|
||||
|
||||
this.getAllCameras()
|
||||
});
|
||||
let isFullscreen =
|
||||
document.fullscreenElement ||
|
||||
document.mozFullScreenElement ||
|
||||
document.webkitFullscreenElement ||
|
||||
document.fullScreen ||
|
||||
document.mozFullScreen ||
|
||||
document.webkitIsFullScreen;
|
||||
this.isFullscreen = !!isFullscreen;
|
||||
|
||||
let that = this;
|
||||
document.addEventListener("fullscreenchange", () => {
|
||||
that.isFullscreen = !that.isFullscreen;
|
||||
});
|
||||
document.addEventListener("mozfullscreenchange", () => {
|
||||
that.isFullscreen = !that.isFullscreen;
|
||||
});
|
||||
document.addEventListener("webkitfullscreenchange", () => {
|
||||
that.isFullscreen = !that.isFullscreen;
|
||||
});
|
||||
document.addEventListener("msfullscreenchange", () => {
|
||||
that.isFullscreen = !that.isFullscreen;
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
|
||||
getWallStyle(){
|
||||
this.$api.httpApi.getWallStyle({
|
||||
data: {}
|
||||
}).then(res => {
|
||||
if(res.code == 200) {
|
||||
this.row = res.data[0];
|
||||
this.column = res.data[1];
|
||||
this.getClientHeight();
|
||||
sessionStorage.setItem('originHeight', this.clientHeight)
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
},
|
||||
getClientHeight() {
|
||||
this.clientHeight = this.$el.clientHeight-40;
|
||||
|
||||
console.log("clientHeight:"+this.clientHeight)
|
||||
},
|
||||
getAllCameras(){
|
||||
this.$api.httpApi.getAllCameras({
|
||||
data: {}
|
||||
}).then(res => {
|
||||
if(res.code == 200) {
|
||||
let cameras = res.data;
|
||||
this.webrtcPlayers = Array.from({ length: this.row }, () => []);
|
||||
for(let i = 1;i<=cameras.length;i++){
|
||||
let rowIndex = Math.floor((i-1) / this.column) + 1;
|
||||
if(rowIndex > this.row){
|
||||
return
|
||||
}
|
||||
let columnIndex = i % this.column;
|
||||
if(columnIndex == 0){
|
||||
columnIndex = this.column;
|
||||
}
|
||||
this.webrtcPlayers[rowIndex-1].push(cameras[i-1]);
|
||||
let idName = rowIndex + "-" + columnIndex;
|
||||
console.log("idName:"+idName);
|
||||
//console.log(this.webrtcPlayers);
|
||||
//let server = cameras[i-1].rtcServer+":"+ cameras[i-1].rtcServerPort
|
||||
//let video = document.getElementById(idName);
|
||||
//let player = new WebRtcPlayer(server,video,"camera"+cameras[i-1].id);
|
||||
//this.players.push(player);
|
||||
}
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
},
|
||||
getAllAreas(){
|
||||
this.$api.httpApi.getAllAreas({
|
||||
data: {}
|
||||
}).then(res => {
|
||||
if(res.code == 200) {
|
||||
this.areas = res.data;
|
||||
|
||||
if(this.areas.length == 0){
|
||||
this.getAllCameras()
|
||||
}else{
|
||||
this.activeKey = this.areas[0]
|
||||
this.tabChange();
|
||||
}
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
},
|
||||
destory(){
|
||||
for(let player of this.players){
|
||||
console.log("stop")
|
||||
player.destroy()
|
||||
}
|
||||
this.players = []
|
||||
},
|
||||
tabChange(){
|
||||
this.destory();
|
||||
this.$api.httpApi.allCamerasByArea({
|
||||
params:{
|
||||
area:this.activeKey
|
||||
}
|
||||
|
||||
}).then(res => {
|
||||
if(res.code == 200) {
|
||||
let cameras = res.data;
|
||||
for(let i = 1;i<=cameras.length;i++){
|
||||
let rowIndex = Math.floor((i-1) / this.column) + 1;
|
||||
if(rowIndex > this.row){
|
||||
return
|
||||
}
|
||||
let columnIndex = i % this.column;
|
||||
if(columnIndex == 0){
|
||||
columnIndex = this.column;
|
||||
}
|
||||
let idName = rowIndex + "-" + columnIndex;
|
||||
console.log("idName:"+idName);
|
||||
let server = cameras[i-1].rtcServer+":"+ cameras[i-1].rtcServerPort
|
||||
let video = document.getElementById(idName);
|
||||
let player = new WebRtcPlayer(server,video,"camera"+cameras[i-1].id);
|
||||
this.players.push(player);
|
||||
}
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
},
|
||||
full () {
|
||||
if(this.isFullscreen){
|
||||
this.exitfullscreen()
|
||||
}else{
|
||||
this.enterfullscreen()
|
||||
}
|
||||
|
||||
},
|
||||
//控制全屏
|
||||
enterfullscreen () { //进入全屏
|
||||
var docElm = document.getElementById('videos') // 指定容器id
|
||||
//W3C
|
||||
if (docElm.requestFullscreen) {
|
||||
docElm.requestFullscreen()
|
||||
}
|
||||
|
||||
//FireFox
|
||||
else if (docElm.mozRequestFullScreen) {
|
||||
docElm.mozRequestFullScreen()
|
||||
}
|
||||
//Chrome等
|
||||
else if (docElm.webkitRequestFullScreen) {
|
||||
docElm.webkitRequestFullScreen()
|
||||
}
|
||||
//IE11
|
||||
else if (elem.msRequestFullscreen) {
|
||||
elem.msRequestFullscreen()
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.clientHeight = document.body.clientHeight;
|
||||
console.log("full:"+document.body.clientHeight)
|
||||
})
|
||||
|
||||
},
|
||||
//退出全屏
|
||||
exitfullscreen () {
|
||||
console.log("tuichu");
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen()
|
||||
} else if (document.mozCancelFullScreen) {
|
||||
document.mozCancelFullScreen()
|
||||
} else if (document.webkitCancelFullScreen) {
|
||||
document.webkitCancelFullScreen()
|
||||
} else if (document.msExitFullscreen) {
|
||||
document.msExitFullscreen()
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
let origin = sessionStorage.getItem('originHeight');
|
||||
if(origin){
|
||||
this.clientHeight = origin;
|
||||
}else{
|
||||
this.getClientHeight();
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style>
|
||||
|
||||
/* #videos > .ant-row {
|
||||
height: calc(100% / 8);
|
||||
}
|
||||
#videos > .ant-row > .ant-col{
|
||||
height: calc(100% / 8);
|
||||
} */
|
||||
|
||||
</style>
|
||||
Loading…
Reference in New Issue