1 |
- var Ce=Object.defineProperty;var ke=(c,t,e)=>t in c?Ce(c,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):c[t]=e;var N=(c,t,e)=>(ke(c,typeof t!="symbol"?t+"":t,e),e);import{d as ge,k as V,r as te,s as q,b as se,o as Ve,x as we,X as O,a6 as Y,t as Q,A as ee,f as k,u as S,a9 as J,a7 as ye,P as Te,e as B,w as W,q as ie,Z as R,E as H,Y as x,aa as X,F as Ee,a2 as _e,a8 as Pe}from"./vue-fae2b924.js";import{K as Se,ba as Ae,bu as Ne,ac as Re,V as be,aJ as Le,s as De,G as ae,aZ as re,a_ as oe,bv as Oe,a0 as K,U as ne,bj as Ge,a3 as le,bk as Me}from"./radical-49beb80b.js";import{W as We,a as ce,A as de,d as ue,V as he,e as Ue,F as ze,D as xe,f as pe,C as Fe,b as Z,g as Be,c as me}from"./canvas-14fb4930.js";import{o as He}from"./index-ac5bf03d.js";import{j as Ke}from"./gb28181-c4bbd148.js";const Je=Se({id:"screen-store",persist:{paths:["customInfo"]},state:()=>({curScreenNum:1,multiPlayRef:{webrtc:!1,streamList:[],updateItem:async(c,t)=>{},delItem:async c=>{},resetStreamList:async c=>{},resizeStreamList:async c=>{},closeAll:()=>{},preConnect:()=>Promise.resolve()},activeInfo:{parentId:"",deviceId:"",parentName:"",name:"",path:"",type:""},customInfo:{collapsed:!1,rowNum:1,screenNum:1,selectNum:0}}),getters:{getActiveInfo(){return this.activeInfo}},actions:{setCurScreenNum(c){this.curScreenNum=c},setMultiPlayRef(c){this.multiPlayRef=c},setActiveInfo(c){this.activeInfo=c},setCustomInfo(c){const t=Object.assign(this.customInfo,c);this.customInfo=t}}}),je={class:"video-container"},qe=["id","srcObject"],Xe=ge({__name:"batch",props:{path:{},format:{},stream:{},videoShadow:{},speed:{},pause:{type:Boolean},startTime:{}},emits:["postion","play"],setup(c,{emit:t}){const e=c;e.path,e.format,e.stream,new Date().toISOString();const o=t;let r,n=0,u=0;const w=V();let T,C;const E=V(),_=typeof VideoDecoder=="function",P=V();let I=null,G=null,$=null;function l(){return typeof WebAssembly>"u"?!1:WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,123,3,2,1,0,10,10,1,8,0,65,0,253,15,253,98,11]))}let i=null,v=null;const p=te(new We(""));let b=!1;q(()=>{w.value&&(w.value.addEventListener("playing",()=>{o("play",!0)}),w.value.addEventListener("pause",()=>{o("play","pause")}),w.value.addEventListener("ended",()=>{o("play","ended")}),w.value.addEventListener("error",()=>{o("play","error")}))});function L(y){const h=new y;return h.on(Z.VideoCodecInfo,m=>{`${m.width}${m.height}`}),h.on(Z.VideoFrame,m=>{C?C.write(m):I&&P.value&&(A.value=!1,I.writeVideo(m),m.close())}),h.on(Z.Error,m=>{console.error(m),b=!1,i instanceof ue&&(i=L(l()?Be:he),i.initialize().then(()=>{$&&i&&i.configure({...$})}))}),h}function F(y){const h=new y;return h.on(me.Error,m=>{console.error(m),h instanceof ce&&(v=F(de),v.initialize().then(()=>{G&&v&&v.configure({...G})}))}),h.on(me.AudioFrame,m=>{T?T.write(m):I&&(A.value=!1,I.writeAudio(m))}),h}function U(){v==null||v.close(),G=null}function z(){i==null||i.close(),$=null}se(()=>{}),q(()=>{p.mediaStream&&(E.value=p.mediaStream)}),q(async()=>{if(e.path,e.format,e.stream,new Date().toISOString(),e.format==="ws-flv"&&e.path&&e.path.trim()!==""){e.path;try{r&&(e.path,U(),z(),await r.close()),e.path,v=F(_?ce:de),i=L(_?ue:he),await i.initialize(),await v.initialize(),r=new Ue(`${He("flv","","ws")}/${e.path}`),j(new ze(r,xe.PUSH)),await r.connect()}catch(y){Ae.error({message:"播放失败",description:y instanceof Event?"连接失败":String(y)}),o("play","connect error")}}else e.format==="webrtc"?(e.stream&&(E.value=e.stream),r&&(U(),z(),await r.close(),r=null)):(e.path,e.format,r&&(U(),z(),await r.close(),r=null),E.value=void 0)});function j(y){if(_&&typeof MediaStreamTrackGenerator=="function"){const h=new MediaStreamTrackGenerator({kind:"audio"});T=h.writable.getWriter(),h.onmute=()=>{o("play","audio mute")};const m=new MediaStreamTrackGenerator({kind:"video"});C=m.writable.getWriter(),m.onmute=()=>{o("play","videomute")},E.value=new MediaStream([h,m])}y.on(pe.VIDEO_ENCODER_CONFIG_CHANGED,h=>{$={...h},delete $.description,i&&i.state==="initialized"&&i.configure($),!_&&P.value&&(I=new Fe(P.value))}),y.on(pe.AUDIO_ENCODER_CONFIG_CHANGED,h=>{G=h;try{v&&v.configure({...h})}catch(m){console.error(m)}}),y.gotVideo=h=>{try{if(!i||i.state!=="configured"){console.warn("Video decoder not configured yet, waiting...");return}if(!b&&h.type!=="key"){console.warn("Waiting for keyframe...");return}h.type==="key"&&(b||(b=!0)),i.decode(h),n=h.timestamp,e.startTime!==void 0&&e.startTime!==null&&o("postion",n-u+e.startTime)}catch(m){console.error(m,h)}},y.gotAudio=h=>{if(!v||v.state!=="configured"){console.warn("Audio decoder not configured yet, waiting...");return}v.decode(h)}}const A=V(!0);return Ve(()=>{var y;if(!_&&w.value){const h=document.createElement("canvas");h.style.width="100%",h.style.objectFit="cover",h.style.borderRadius="6px",e.videoShadow&&(h.style.boxShadow="4px 4px 8px 4px #dedede"),(y=w.value.parentElement)==null||y.replaceChild(h,w.value),P.value=h}Ne(w.value,"canplay",()=>{A.value=!1}),e.path,e.format}),se(()=>{e.path,e.format}),we(()=>{e.path,e.format}),(y,h)=>(O(),Y("div",je,[Q(k(S(Re),{class:"loading",size:"large"},null,512),[[ee,A.value]]),J("video",{ref_key:"videoEle",ref:w,class:ye(["video",{videoShadow:y.videoShadow}]),id:"video-"+y.path,srcObject:E.value,autoplay:"",playsinline:""},null,10,qe),Te(y.$slots,"default",{},void 0,!0)]))}});const Ze=be(Xe,[["__scopeId","data-v-4c62efd2"]]);class Ye{constructor(t){N(this,"ws",null);N(this,"pc",null);N(this,"localStream",null);N(this,"subscribedStreams",new Set);N(this,"videoSenders",new Map);N(this,"streamToTransceiver",new Map);N(this,"eventListeners",new Map);N(this,"wsUrl");N(this,"pingInterval",null);const e=location.protocol==="https:"?"wss:":"ws:";this.wsUrl=t?`${e}//${t}/webrtc/batchv2`:`${e}//${location.host}/webrtc/batchv2`}async connect(){try{return this.log(`正在连接到 ${this.wsUrl}...`),this.ws=new WebSocket(this.wsUrl),new Promise((t,e)=>{if(!this.ws){e(new Error("WebSocket 未初始化"));return}this.ws.onopen=async()=>{this.log("WebSocket 连接已建立","success"),this.startPingInterval();const o={iceTransportPolicy:"all",bundlePolicy:"max-bundle",rtcpMuxPolicy:"require",iceCandidatePoolSize:1};this.pc=new RTCPeerConnection(o);const r=this.pc.addTransceiver("video",{direction:"sendrecv"});this.videoSenders.set("placeholder",r.sender),this.log("已向 PeerConnection 添加占位轨道","info"),this.setupPeerConnectionEventHandlers();const n=await this.pc.createOffer();await this.pc.setLocalDescription(n),this.sendMessage({type:"offer",sdp:this.pc.localDescription.sdp}),this.emit("connected",null),t()},this.ws.onmessage=this.handleWebSocketMessage.bind(this),this.ws.onclose=()=>{this.log("WebSocket 连接已关闭"),this.cleanup(),this.emit("disconnected",null),e(new Error("WebSocket 连接已关闭"))},this.ws.onerror=o=>{this.log(`WebSocket 错误: ${o}`,"error"),this.cleanup(),this.emit("error",{message:"WebSocket 错误"}),e(new Error("WebSocket 错误"))}})}catch(t){throw this.log(`连接错误: ${t.message}`,"error"),this.cleanup(),this.emit("error",{message:t.message}),t}}disconnect(){this.cleanup()}async startPublishing(t){try{if(!t)throw new Error("请输入有效的流路径");if(!this.pc||!this.ws)throw new Error("未连接到服务器");this.localStream=await navigator.mediaDevices.getUserMedia({video:!0,audio:!1});const e=this.localStream.getVideoTracks()[0],o=this.videoSenders.get("placeholder");o&&(await o.replaceTrack(e),this.log("已用真实轨道替换占位视频轨道","success")),this.videoSenders.delete("placeholder"),this.videoSenders.set(t,o);const r=await this.pc.createOffer();return await this.pc.setLocalDescription(r),await this.waitForIceGathering(),this.sendMessage({type:"publish",streamPath:t,offer:this.pc.localDescription.sdp}),this.log(`已开始发布到 ${t}`,"success"),this.emit("publishStarted",{streamPath:t}),Promise.resolve()}catch(e){throw this.log(`发布错误: ${e.message}`,"error"),this.emit("error",{message:e.message}),e}}async stopPublishing(t){try{if(!this.pc||!this.ws)throw new Error("未连接到服务器");const e=this.videoSenders.get(t);e&&(await e.replaceTrack(null),this.log("已移除视频轨道","info"),this.videoSenders.delete(t),this.videoSenders.set("placeholder",e)),this.localStream&&(this.localStream.getTracks().forEach(r=>r.stop()),this.localStream=null);const o=await this.pc.createOffer();return await this.pc.setLocalDescription(o),await this.waitForIceGathering(),this.sendMessage({type:"unpublish",streamPath:t}),this.log(`已停止发布到 ${t}`,"success"),this.emit("publishStopped",{streamPath:t}),Promise.resolve()}catch(e){throw this.log(`停止发布错误: ${e.message}`,"error"),this.emit("error",{message:e.message}),e}}getStreamList(){if(!this.ws){this.log("未连接到服务器","error");return}this.sendMessage({type:"getStreamList"}),this.log("已请求流列表","info")}async subscribeToStreams(t){try{if(!this.pc||!this.ws)throw new Error("未连接到服务器");if(t.length===0)throw new Error("请至少选择一个流");const e=new Set(this.subscribedStreams);this.subscribedStreams.clear(),t.forEach(n=>{n&&this.subscribedStreams.add(n)});const o=[];e.forEach(n=>{if(!this.subscribedStreams.has(n)){const u=this.streamToTransceiver.get(n);u&&(u.direction="inactive",this.log(`已将移除流 ${n} 的转接器设置为 inactive`,"info"),this.streamToTransceiver.delete(n)),o.push(n),this.emit("streamRemoved",{streamPath:n})}}),o.length>0&&await this.sendUnsubscribeSignal(o);const r=Array.from(this.subscribedStreams).filter(n=>!e.has(n));if(this.log(`新流路径: ${r.join(", ")}`,"info"),r.length>0){const n=this.pc.getTransceivers().filter(C=>C.direction==="inactive");this.log(`可用转接器数量: ${n.length}`,"info");const u=[...r];for(;u.length>0&&n.length>0;)u.pop(),n.pop().direction="recvonly";const w=u.length;if(w>0){this.log(`添加 ${w} 个新视频转接器`,"info");for(let C=0;C<w;C++)this.pc.addTransceiver("video",{direction:"recvonly"})}const T=await this.pc.createOffer();await this.pc.setLocalDescription(T),this.sendMessage({type:"subscribe",streamList:r,offer:this.pc.localDescription.sdp}),this.log(`订阅了 ${r.length} 个新流`,"success")}return this.log(`当前播放流总数: ${this.subscribedStreams.size}`,"success"),Promise.resolve()}catch(e){throw this.log(`播放流错误: ${e.message}`,"error"),this.emit("error",{message:e.message}),e}}async sendUnsubscribeSignal(t){if(!this.ws||!this.pc){this.log("未连接到服务器","error");return}if(t.length!==0)try{const e=await this.pc.createOffer();await this.pc.setLocalDescription(e),await this.waitForIceGathering(),this.sendMessage({type:"unsubscribe",streamList:t,offer:this.pc.localDescription.sdp}),this.log(`已为 ${t.length} 个流发送取消订阅信号`,"info")}catch(e){throw this.log(`发送取消订阅信号错误: ${e.message}`,"error"),e}}async unsubscribeFromStream(t){try{if(!this.pc||!this.ws)throw new Error("未连接到服务器");const e=this.streamToTransceiver.get(t);return e&&(e.direction="inactive",this.log(`已将 ${t} 的转接器设置为 inactive`,"info"),this.streamToTransceiver.delete(t),await this.sendUnsubscribeSignal([t])),this.subscribedStreams.delete(t),this.emit("streamRemoved",{streamPath:t}),this.log(`已从订阅列表移除 ${t}`,"info"),Promise.resolve()}catch(e){throw this.log(`取消订阅流错误: ${e.message}`,"error"),this.emit("error",{message:e.message}),e}}getLocalStream(){return this.localStream}getSubscribedStreams(){return Array.from(this.subscribedStreams)}on(t,e){this.eventListeners.has(t)||this.eventListeners.set(t,[]),this.eventListeners.get(t).push(e)}off(t,e){if(!this.eventListeners.has(t))return;const o=this.eventListeners.get(t),r=o.indexOf(e);r!==-1&&o.splice(r,1)}emit(t,e){if(!this.eventListeners.has(t))return;const o=this.eventListeners.get(t);for(const r of o)r(e)}log(t,e="info"){this.emit("log",{message:t,level:e,time:new Date})}setupPeerConnectionEventHandlers(){this.pc&&(this.pc.onicecandidate=t=>{t.candidate?this.log("ICE 候选: "+t.candidate.candidate):this.log("ICE 收集完成")},this.pc.onicegatheringstatechange=()=>{this.log(`ICE 收集状态: ${this.pc.iceGatheringState}`),this.emit("iceStateChange",{state:this.pc.iceGatheringState})},this.pc.oniceconnectionstatechange=()=>{this.log(`ICE 连接状态: ${this.pc.iceConnectionState}`),this.emit("iceStateChange",{state:this.pc.iceConnectionState}),this.pc.iceConnectionState==="failed"&&this.log("ICE 连接失败","error")},this.pc.onconnectionstatechange=()=>{this.log(`连接状态已变更: ${this.pc.connectionState}`),this.emit("connectionStateChange",{state:this.pc.connectionState}),this.pc.connectionState==="connected"&&this.log("PeerConnection 建立成功","success")},this.pc.ontrack=this.handleTrackEvent.bind(this))}handleTrackEvent(t){this.log(`收到轨道: ${t.track.kind}/${t.track.id}`,"success");const e=t.transceiver;e||this.log(`未找到轨道 ${t.track.id} 的转接器`,"warn");const o={};t.track.onunmute=()=>{this.log(`轨道已 unmute: ${t.track.kind}/${t.track.id}`,"success")};const r=setInterval(async()=>{if(!this.pc||this.pc.connectionState!=="connected"){this.log("连接状态变更,停止统计收集","info"),clearInterval(r);return}try{(await this.pc.getStats(t.track)).forEach(u=>{if(u.type==="inbound-rtp"&&u.kind===t.track.kind){const w=u.packetsReceived||0;(o[t.track.id]||0)!==w&&(o[t.track.id]=w)}})}catch(n){this.log(`获取统计信息错误: ${n.message}`,"error")}},5e3);if(t.track.kind==="video"&&t.streams[0]){const n=t.streams[0].id;this.streamToTransceiver.set(n,e),this.emit("streamAdded",{streamId:n,stream:t.streams[0],track:t.track})}}async handleWebSocketMessage(t){const e=JSON.parse(t.data);if(this.log(`收到消息: ${e.type}`),"type"in e)switch(e.type){case"pong":this.log("收到 pong 响应","debug");break;case"answer":const o=new RTCSessionDescription({type:"answer",sdp:e.sdp});await this.pc.setRemoteDescription(o),this.log("远端描述已设置","success");break;case"error":this.log(`错误: ${e.message}`,"error"),this.emit("error",{message:e.message});break;case"streamList":this.log(`收到流列表,共 ${e.streams.length} 个流`,"info"),this.emit("streamList",{streams:e.streams});break}}sendMessage(t){if(!this.ws){this.log("未连接到服务器","error");return}this.ws.send(JSON.stringify(t))}async waitForIceGathering(t=2e3){return this.pc?Promise.race([new Promise(e=>{if(this.pc.iceGatheringState==="complete")e();else{const o=()=>{this.pc.iceGatheringState==="complete"&&(this.pc.removeEventListener("icegatheringstatechange",o),e())};this.pc.addEventListener("icegatheringstatechange",o)}}),new Promise(e=>setTimeout(e,t))]):Promise.reject(new Error("PeerConnection 未初始化"))}startPingInterval(){this.stopPingInterval(),this.pingInterval=setInterval(()=>{this.sendPing()},5e3),this.log("已启动 ping 定时器","debug")}stopPingInterval(){this.pingInterval&&(clearInterval(this.pingInterval),this.pingInterval=null,this.log("已停止 ping 定时器","debug"))}sendPing(){this.ws&&this.ws.readyState===WebSocket.OPEN&&(this.sendMessage({type:"ping"}),this.log("已发送 ping 消息","debug"))}cleanup(){this.stopPingInterval(),this.ws&&(this.ws.close(),this.ws=null),this.pc&&(this.pc.close(),this.pc=null),this.localStream&&(this.localStream.getTracks().forEach(t=>t.stop()),this.localStream=null),this.subscribedStreams.clear(),this.videoSenders.clear(),this.streamToTransceiver.clear(),this.log("连接已清理","info")}}function fe(c=!1,t="webrtc"){const e=te([]),o=V([]);let r=null;const n=()=>e.map(l=>l.path),u=async()=>{if(t!=="ws-flv"&&r)try{await r.subscribeToStreams(n()),`${n().length}`}catch{}},w=async()=>{t!=="ws-flv"&&await C()},T=function(l){let i=String(l.getMilliseconds());return"padStart"in String.prototype&&(i=i.toString().padStart(3,"0")),`${l.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/,"$1")}:${i}`},C=async()=>new Promise(async l=>{if(r)return l();r=new Ye(window.allEnv.media.startsWith("http")?window.allEnv.media.replace("http://","").replace("https://",""):location.host+window.allEnv.media),r.on("log",i=>console[["info","debug","warn","error"].indexOf(i.level)!==-1?i.level:"info"](T(i.time),i.message)),r.on("error",i=>console.log(`客户端错误: ${i.message}`)),r.on("connected",()=>{l()}),r.on("disconnected",()=>{r=null;const i=e.length;e.length=0,e.push(...new Array(i).fill(0).map(()=>({path:"",stream:void 0}))),o.value.length=0}),r.on("publishStarted",i=>{`${i.streamPath}`}),r.on("publishStopped",i=>{`${i.streamPath}`}),r.on("streamList",i=>{`${i.streams.length}`,i.streams.length===0&&(e.length=0)}),r.on("streamAdded",i=>{`${i.streamId}`,e.some(p=>p.path===i.streamId)&&(o.value.push({id:i.streamId,stream:i.stream}),I())}),r.on("streamRemoved",i=>{`${i.streamId}`});try{await r.connect()}catch{r=null}}),E=async({deviceItem:l,streamItem:i,path:v},p)=>{if(t==="ws-flv"){if(p>=0&&p<e.length){const b={path:v};if(c&&l){if(!l.parentId||!l.deviceId){console.error("GB28181设备信息不完整,无法更新流");return}b.deviceItem=l}else i&&(b.streamItem=i);e[p]={...b}}return}if(c&&l){if(!l.parentId||!l.deviceId){console.error("GB28181设备信息不完整,无法更新流");return}e[p].path=v,e[p].deviceItem=l}else i&&(e[p].path=v,e[p].streamItem=i);if(r||await w(),!o.value.some(b=>v===b.id)){await u();return}},_=async l=>{if(t==="ws-flv"){l>=0&&l<e.length&&(e[l]={path:"",deviceItem:c?{}:void 0,streamItem:c?void 0:{},stream:void 0});return}e[l].path="",delete e[l].deviceItem,delete e[l].streamItem,delete e[l].stream,await u()},P=async l=>{e.length,JSON.stringify(e,null,2);const i=e.length;if(l>i){const v=new Array(l-i).fill({}).map((p,b)=>c?{path:"",deviceItem:{},stream:void 0}:{path:"",streamItem:{},stream:void 0});e.push(...v)}else l<i&&e.splice(l).forEach((p,b)=>{p.stream&&p.path,p.path="",p.stream=void 0,c?p.deviceItem={}:p.streamItem={}});JSON.stringify(e,null,2),t==="webrtc"&&await u()},I=()=>{e.forEach(l=>{var i;l.stream=(i=o.value.find(v=>v.id===l.path))==null?void 0:i.stream})};return{webrtc:t==="webrtc",streamList:e,updateItem:E,delItem:_,resetStreamList:async l=>{JSON.stringify(l,null,2),e.length=0,e.push(...l),t==="webrtc"&&(o.value.length=0,await u())},resizeStreamList:P,closeAll:()=>{if(t==="ws-flv"){e.forEach((l,i)=>{e[i]=c?{path:"",deviceItem:{},stream:void 0}:{path:"",streamItem:{},stream:void 0}});return}r&&(r.disconnect(),r=null,e.length=0,o.value.length=0)},preConnect:w}}const Qe=Se({id:"app-group-store",state:()=>({groupTree:[],selectedChannel:[],curPlayGroupId:-2}),actions:{setCurPlayGroupId(c){this.curPlayGroupId=c},setGroupTree(c){this.groupTree=c},setSelChannel(c){this.selectedChannel=c},async fetchGroupTree(){const{data:c}=await Ke(-1),t=Ie(c);this.setGroupTree(t)}}});function Ie(c){return c.map(t=>{const e=Ie(t.children),o=t.channels.map(n=>({...n,key:`${n==null?void 0:n.channelId}_${n==null?void 0:n.deviceId}_${n.id}`,isChannel:!0})),r=[...e.map(n=>({...n})),...o];return{...t,key:`${(t==null?void 0:t.key)||t.id}`,children:r}})}const et={class:"screen-container"},tt={class:"flex items-center gap-2 mb-2"},st={class:"text-center"},it={class:"video-player-placeholder"},ve=16,at=ge({__name:"content",props:{type:{default:"device"}},setup(c){const t=V("ws-flv"),e=V(!1),o=c,r=Qe(),n=Je(),u=B({get:()=>n.curScreenNum,set:d=>n.setCurScreenNum(d)}),w=[{label:"单屏",value:1},{label:"四分屏",value:4},{label:"九分屏",value:9},{label:"十六分屏",value:16}],T=B(()=>{switch(u.value){case 1:return 24;case 4:return 12;case 9:return 8;case 16:return 6;default:return 24}}),C=()=>document.querySelector(".screen-list"),E=V(),{toggle:_,isFullscreen:P}=Le(E),I=V(!1),G=()=>{try{if(I.value=!1,typeof RTCRtpReceiver<"u"&&RTCRtpReceiver.getCapabilities){const d=RTCRtpReceiver.getCapabilities("video");d&&d.codecs&&d.codecs.some(s=>s.mimeType.toLowerCase().includes("h265")||s.mimeType.toLowerCase().includes("hevc"))||(I.value=!0)}else I.value=!0}catch(d){console.warn("检测 H265 支持时发生错误:",d),I.value=!0}},$=V(fe(o.type==="device","webrtc")),l=V(fe(o.type==="device","ws-flv")),i=async d=>{const a=new Array(u.value||1).fill({}).map(()=>o.type==="device"?{path:"",deviceItem:{},stream:void 0}:{path:"",streamItem:{},stream:void 0});await d.resetStreamList(a)};(async()=>{await Promise.all([i($.value),i(l.value)])})();const p=B(()=>n.multiPlayRef),b=B(()=>n.multiPlayRef.streamList);W(b,(d,a)=>{if(t.value,d.length,a==null||a.length,JSON.stringify(d,null,2),a&&(d.forEach((s,f)=>{const g=a[f];g?s.path!==g.path&&`${f}${g.path||"(空)"}${s.path||"(空)"}`:(`${f}`,s.path)}),a.length>d.length))for(let s=d.length;s<a.length;s++)`${s}`,a[s].path},{deep:!0,immediate:!1});const L=V(Array.from({length:ve},(d,a)=>({path:"",deviceItem:{},streamItem:{},stream:void 0,idx:a,isValid:!1,isVisible:!1,slotKey:`fixed-slot-${a}`,colSpanValue:24/1}))),F=()=>{u.value,t.value,JSON.stringify(b.value,null,2);const d=T.value;for(let a=0;a<ve;a++){const s=L.value[a],f=b.value[a],g=a<u.value;f&&"path"in f&&g?(s.path=f.path||"",s.deviceItem=f.deviceItem||{},s.streamItem=f.streamItem||{},s.stream=f.stream,s.isValid=!!(f.path&&f.path.trim().length>0),s.isVisible=!0):(s.path="",s.deviceItem={},s.streamItem={},s.stream=void 0,s.isValid=!1,s.isVisible=g),s.colSpanValue=d}L.value.slice(0,u.value).forEach((a,s)=>{`${s}${a.path||"(空)"}${a.isValid}${a.isVisible}${a.slotKey}`})};W([b,u,t,T],()=>{F()},{immediate:!0,deep:!0}),W(L,(d,a)=>{d.length,a==null||a.length;const s=d.filter(g=>g.isVisible),f=(a==null?void 0:a.filter(g=>g.isVisible))||[];if(s.forEach((g,D)=>{const M=f[D];M?g.path!==M.path?`${D}${M.path||"(空)"}${g.path||"(空)"}`:g.isValid!==M.isValid&&`${D}${M.isValid}${g.isValid}`:(`${D}`,g.path)}),f.length>s.length)for(let g=s.length;g<f.length;g++)`${g}`,f[g].path},{deep:!0,immediate:!1});const U=(d,a)=>(`${t.value}${a}`,p.value.updateItem(d,a)),z=async d=>(`${t.value}`,await p.value.resetStreamList(d)),j=()=>{`${t.value}`,p.value.closeAll()},A=te({selectNum:1});W(u,async(d,a)=>{t.value,e.value=!0,A.selectNum=0;let s=[];if(s=[...p.value.streamList],JSON.stringify(s,null,2),o.type==="device"?(n.setActiveInfo({parentId:"",parentName:"",deviceId:"",name:""}),r.setCurPlayGroupId(-2)):n.setActiveInfo({path:"",type:""}),t.value==="webrtc"){const f=new Array(u.value).fill({}).map(()=>o.type==="device"?{path:"",deviceItem:{},stream:void 0}:{path:"",streamItem:{},stream:void 0});await z(f)}else{s.length>0&&await p.value.resetStreamList(s);const f=p.value.streamList.length;await ie(),await p.value.resizeStreamList(u.value),u.value<f&&await ie()}e.value=!1},{immediate:!0});let y=!1;const h=(d,a)=>{if(A.selectNum=a,o.type!=="stream"&&o.type==="device"&&d.deviceItem&&"deviceId"in d.deviceItem){const s=d.deviceItem;n.setActiveInfo({parentId:s.parentId??"",deviceId:s.deviceId??"",parentName:s.parentName??"",name:s.name??""}),y=!0}};we(()=>j());const{getActiveInfo:m}=De(n);return W([()=>m.value.deviceId,()=>m.value.parentId],([d,a],[s,f])=>{if(e.value)return;const g=`${f}/${s}`,D=`${a}/${d}`;if(o.type==="device"&&D!==g){const M=m.value;if(b.value.some($e=>$e.path===D)&&!y)return ae.warn("当前设备已在分屏中!");U({path:D,deviceItem:M},A.selectNum)}y=!1},{immediate:!0}),W(()=>m.value.path,d=>{if(e.value)return;const a=m.value;if(o.type==="stream"&&d){if(b.value.some(s=>s.path===a.path))return ae.warn("当前设备流已在分屏中!");U({path:a.path,streamItem:a},A.selectNum)}}),W(t,async(d,a)=>{r.setCurPlayGroupId(-2);const s=[...p.value.streamList];JSON.stringify(s,null,2),d==="ws-flv"?(n.setMultiPlayRef(l.value),$.value.closeAll(),I.value=!1,l.value.streamList.length!==u.value&&await l.value.resizeStreamList(u.value),s.length>0&&await l.value.resetStreamList(s)):d==="webrtc"&&(n.setMultiPlayRef($.value),G(),l.value.closeAll(),$.value.streamList.length!==u.value&&await $.value.resizeStreamList(u.value),s.length>0&&await $.value.resetStreamList(s))},{immediate:!0}),(d,a)=>(O(),Y("div",et,[J("div",tt,[k(S(oe),{value:t.value,"onUpdate:value":a[0]||(a[0]=s=>t.value=s),size:"small"},{default:R(()=>[k(S(re),{value:"ws-flv"},{default:R(()=>a[3]||(a[3]=[H("WS-FLV")])),_:1}),k(S(re),{value:"webrtc"},{default:R(()=>a[4]||(a[4]=[H("WebRTC")])),_:1})]),_:1},8,["value"])]),J("div",st,[I.value&&t.value==="webrtc"?(O(),x(S(Oe),{key:0,type:"warning",message:"当前浏览器使用 WebRTC 不支持 H265 解码",description:"如需通过 WebRTC 观看 H265 视频请使用最新版的 Chrome 浏览器,确保显卡驱动已安装最新版本","show-icon":"",closable:"",class:"mb-12px",onClose:a[1]||(a[1]=s=>I.value=!1)})):X("",!0),k(S(oe),{value:u.value,"onUpdate:value":a[2]||(a[2]=s=>u.value=s),buttonStyle:"solid",options:w,optionType:"button"},null,8,["value"]),k(S(ne),{onClick:S(_)},{default:R(()=>[k(S(K),{icon:"ant-design:fullscreen-outlined",class:"v-text-bottom"}),a[5]||(a[5]=H("全屏 "))]),_:1},8,["onClick"]),k(S(Me),{gutter:4,class:"screen-list mt-10px",ref_key:"screenRef",ref:E},{default:R(()=>[S(P)?(O(),x(S(ne),{key:0,onClick:S(_),type:"link",class:"absolute right-2 top-2 z-10 text-white"},{default:R(()=>[k(S(K),{icon:"ant-design:fullscreen-exit-outlined",class:"v-text-bottom"}),a[6]||(a[6]=H(" 退出全屏 "))]),_:1},8,["onClick"])):X("",!0),(O(!0),Y(Ee,null,_e(L.value,s=>Q((O(),x(S(Ge),{key:s.slotKey,span:s.colSpanValue,class:ye(["mt-4px flex-center",{active:u.value>1&&A.selectNum===s.idx&&!S(P),isFullscreen:S(P)}]),onClick:()=>{s.idx,s.path,h({path:s.path,deviceItem:s.deviceItem,streamItem:s.streamItem,stream:s.stream},s.idx)}},{default:R(()=>[(O(),x(Ze,{key:s.slotKey,path:s.isValid?s.path:"",format:t.value,stream:s.stream,style:Pe({display:s.isValid?"block":"none"}),onVnodeBeforeCreate:f=>console.log("🚀 VideoPlayer beforeCreate:",s.path,"key:",s.slotKey,"isValid:",s.isValid),onVnodeCreated:f=>console.log("✅ VideoPlayer created:",s.path,"key:",s.slotKey,"isValid:",s.isValid),onVnodeBeforeUnmount:f=>console.log("💀 VideoPlayer beforeUnmount:",s.path,"key:",s.slotKey,"isValid:",s.isValid),onVnodeUnmounted:f=>console.log("🗑️ VideoPlayer unmounted:",s.path,"key:",s.slotKey,"isValid:",s.isValid)},{default:R(()=>[s.path?(O(),x(S(le),{key:0,class:"position-absolute bottom-0 left-50% cursor-pointer",title:s.path,getPopupContainer:C},{default:R(()=>[k(S(K),{icon:"octicon:ellipsis-16",size:20,color:"#dedede",hoverColor:"#a275d9"})]),_:2},1032,["title"])):X("",!0)]),_:2},1032,["path","format","stream","style","onVnodeBeforeCreate","onVnodeCreated","onVnodeBeforeUnmount","onVnodeUnmounted"])),Q(J("div",it,[k(S(le),{title:"当前无信号,请先选择通道",class:"no-stream-tip cursor-pointer",getPopupContainer:C,placement:"top"},{default:R(()=>[k(S(K),{icon:"pepicons-pop:television-play-off",size:u.value===1?50:24},null,8,["size"])]),_:1})],512),[[ee,!s.isValid]])]),_:2},1032,["span","class","onClick"])),[[ee,s.isVisible]])),128))]),_:1},512)])]))}});const ut=be(at,[["__scopeId","data-v-f9724f3f"]]);export{ut as C,Qe as a,Je as u};
|