content-74444b6d.js 26 KB

1
  1. var ke=Object.defineProperty;var Ce=(d,t,e)=>t in d?ke(d,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[t]=e;var N=(d,t,e)=>(Ce(d,typeof t!="symbol"?t+"":t,e),e);import{d as ve,k as V,r as te,s as j,b as se,o as Ve,x as we,X as O,a6 as Y,t as Q,A as ee,f as C,u as b,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,bb as Ae,bA as Ne,ac as Re,V as be,aJ as Le,s as De,G as ae,aZ as re,a_ as oe,bq as Oe,a0 as K,U as ne,bk as Ge,a3 as le,bl as Me}from"./radical-3ee02118.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-137e94ff.js";import{k as Ke}from"./gb28181-fe7ed9bb.js";const Je=Se({id:"screen-store",persist:{paths:["customInfo"]},state:()=>({curScreenNum:1,multiPlayRef:{webrtc:!1,streamList:[],updateItem:async(d,t)=>{},delItem:async d=>{},resetStreamList:async d=>{},resizeStreamList:async d=>{},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(d){this.curScreenNum=d},setMultiPlayRef(d){this.multiPlayRef=d},setActiveInfo(d){this.activeInfo=d},setCustomInfo(d){const t=Object.assign(this.customInfo,d);this.customInfo=t}}}),qe={class:"video-container"},je=["id","srcObject"],Xe=ve({__name:"batch",props:{path:{},format:{},stream:{},videoShadow:{},speed:{},pause:{type:Boolean},startTime:{}},emits:["postion","play"],setup(d,{emit:t}){const e=d;e.path,e.format,e.stream,new Date().toISOString();const r=t;let a,o=0,h=0;const w=V();let T,k;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 c=null,n=null;const m=te(new We(""));let S=!1;j(()=>{w.value&&(w.value.addEventListener("playing",()=>{r("play",!0)}),w.value.addEventListener("pause",()=>{r("play","pause")}),w.value.addEventListener("ended",()=>{r("play","ended")}),w.value.addEventListener("error",()=>{r("play","error")}))});function L(y){const p=new y;return p.on(Z.VideoCodecInfo,f=>{`${f.width}${f.height}`}),p.on(Z.VideoFrame,f=>{k?k.write(f):I&&P.value&&(A.value=!1,I.writeVideo(f),f.close())}),p.on(Z.Error,f=>{console.error(f),S=!1,c instanceof ue&&(c=L(l()?Be:he),c.initialize().then(()=>{$&&c&&c.configure({...$})}))}),p}function F(y){const p=new y;return p.on(me.Error,f=>{console.error(f),p instanceof ce&&(n=F(de),n.initialize().then(()=>{G&&n&&n.configure({...G})}))}),p.on(me.AudioFrame,f=>{T?T.write(f):I&&(A.value=!1,I.writeAudio(f))}),p}function U(){n==null||n.close(),G=null}function z(){c==null||c.close(),$=null}se(()=>{}),j(()=>{m.mediaStream&&(E.value=m.mediaStream)}),j(async()=>{if(e.path,e.format,e.stream,new Date().toISOString(),e.format==="ws-flv"&&e.path&&e.path.trim()!==""){e.path;try{a&&(e.path,U(),z(),await a.close()),e.path,n=F(_?ce:de),c=L(_?ue:he),await c.initialize(),await n.initialize(),a=new Ue(`${He("flv","","ws")}/${e.path}`),q(new ze(a,xe.PUSH)),await a.connect()}catch(y){Ae.error({message:"播放失败",description:y instanceof Event?"连接失败":String(y)}),r("play","connect error")}}else e.format==="webrtc"?(e.stream&&(E.value=e.stream),a&&(U(),z(),await a.close(),a=null)):(e.path,e.format,a&&(U(),z(),await a.close(),a=null),E.value=void 0)});function q(y){if(_&&typeof MediaStreamTrackGenerator=="function"){const p=new MediaStreamTrackGenerator({kind:"audio"});T=p.writable.getWriter(),p.onmute=()=>{r("play","audio mute")};const f=new MediaStreamTrackGenerator({kind:"video"});k=f.writable.getWriter(),f.onmute=()=>{r("play","videomute")},E.value=new MediaStream([p,f])}y.on(pe.VIDEO_ENCODER_CONFIG_CHANGED,p=>{$={...p},delete $.description,c&&c.state==="initialized"&&c.configure($),!_&&P.value&&(I=new Fe(P.value))}),y.on(pe.AUDIO_ENCODER_CONFIG_CHANGED,p=>{G=p;try{n&&n.configure({...p})}catch(f){console.error(f)}}),y.gotVideo=p=>{try{if(!c||c.state!=="configured"){console.warn("Video decoder not configured yet, waiting...");return}if(!S&&p.type!=="key"){console.warn("Waiting for keyframe...");return}p.type==="key"&&(S||(S=!0)),c.decode(p),o=p.timestamp,e.startTime!==void 0&&e.startTime!==null&&r("postion",o-h+e.startTime)}catch(f){console.error(f,p)}},y.gotAudio=p=>{if(!n||n.state!=="configured"){console.warn("Audio decoder not configured yet, waiting...");return}n.decode(p)}}const A=V(!0);return Ve(()=>{var y;if(!_&&w.value){const p=document.createElement("canvas");p.style.width="100%",p.style.objectFit="cover",p.style.borderRadius="6px",e.videoShadow&&(p.style.boxShadow="4px 4px 8px 4px #dedede"),(y=w.value.parentElement)==null||y.replaceChild(p,w.value),P.value=p}Ne(w.value,"canplay",()=>{A.value=!1}),e.path,e.format}),se(()=>{e.path,e.format}),we(()=>{e.path,e.format}),(y,p)=>(O(),Y("div",qe,[Q(C(b(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,je),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 r={iceTransportPolicy:"all",bundlePolicy:"max-bundle",rtcpMuxPolicy:"require",iceCandidatePoolSize:1};this.pc=new RTCPeerConnection(r);const a=this.pc.addTransceiver("video",{direction:"sendrecv"});this.videoSenders.set("placeholder",a.sender),this.log("已向 PeerConnection 添加占位轨道","info"),this.setupPeerConnectionEventHandlers();const o=await this.pc.createOffer();await this.pc.setLocalDescription(o),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=r=>{this.log(`WebSocket 错误: ${r}`,"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],r=this.videoSenders.get("placeholder");r&&(await r.replaceTrack(e),this.log("已用真实轨道替换占位视频轨道","success")),this.videoSenders.delete("placeholder"),this.videoSenders.set(t,r);const a=await this.pc.createOffer();return await this.pc.setLocalDescription(a),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(a=>a.stop()),this.localStream=null);const r=await this.pc.createOffer();return await this.pc.setLocalDescription(r),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(o=>{o&&this.subscribedStreams.add(o)});const r=[];e.forEach(o=>{if(!this.subscribedStreams.has(o)){const h=this.streamToTransceiver.get(o);h&&(h.direction="inactive",this.log(`已将移除流 ${o} 的转接器设置为 inactive`,"info"),this.streamToTransceiver.delete(o)),r.push(o),this.emit("streamRemoved",{streamPath:o})}}),r.length>0&&await this.sendUnsubscribeSignal(r);const a=Array.from(this.subscribedStreams).filter(o=>!e.has(o));if(this.log(`新流路径: ${a.join(", ")}`,"info"),a.length>0){const o=this.pc.getTransceivers().filter(k=>k.direction==="inactive");this.log(`可用转接器数量: ${o.length}`,"info");const h=[...a];for(;h.length>0&&o.length>0;)h.pop(),o.pop().direction="recvonly";const w=h.length;if(w>0){this.log(`添加 ${w} 个新视频转接器`,"info");for(let k=0;k<w;k++)this.pc.addTransceiver("video",{direction:"recvonly"})}const T=await this.pc.createOffer();await this.pc.setLocalDescription(T),this.sendMessage({type:"subscribe",streamList:a,offer:this.pc.localDescription.sdp}),this.log(`订阅了 ${a.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 r=this.eventListeners.get(t),a=r.indexOf(e);a!==-1&&r.splice(a,1)}emit(t,e){if(!this.eventListeners.has(t))return;const r=this.eventListeners.get(t);for(const a of r)a(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 r={};t.track.onunmute=()=>{this.log(`轨道已 unmute: ${t.track.kind}/${t.track.id}`,"success")};const a=setInterval(async()=>{if(!this.pc||this.pc.connectionState!=="connected"){this.log("连接状态变更,停止统计收集","info"),clearInterval(a);return}try{(await this.pc.getStats(t.track)).forEach(h=>{if(h.type==="inbound-rtp"&&h.kind===t.track.kind){const w=h.packetsReceived||0;(r[t.track.id]||0)!==w&&(r[t.track.id]=w)}})}catch(o){this.log(`获取统计信息错误: ${o.message}`,"error")}},5e3);if(t.track.kind==="video"&&t.streams[0]){const o=t.streams[0].id;this.streamToTransceiver.set(o,e),this.emit("streamAdded",{streamId:o,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 r=new RTCSessionDescription({type:"answer",sdp:e.sdp});await this.pc.setRemoteDescription(r),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 r=()=>{this.pc.iceGatheringState==="complete"&&(this.pc.removeEventListener("icegatheringstatechange",r),e())};this.pc.addEventListener("icegatheringstatechange",r)}}),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(d=!1,t="webrtc"){const e=te([]),r=V([]);let a=null;const o=()=>e.map(l=>l.path),h=async()=>{if(t!=="ws-flv"&&a)try{await a.subscribeToStreams(o()),`${o().length}`}catch{}},w=async()=>{t!=="ws-flv"&&await k()},T=function(l){let c=String(l.getMilliseconds());return"padStart"in String.prototype&&(c=c.toString().padStart(3,"0")),`${l.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/,"$1")}:${c}`},k=async()=>new Promise(async l=>{if(a)return l();const c=window.allEnv.media.startsWith(":")?`${location.protocol}//${location.hostname}${window.allEnv.media}`:window.allEnv.media;a=new Ye(c.startsWith("http")?c.replace("http://","").replace("https://",""):location.host+c),a.on("log",n=>console[["info","debug","warn","error"].indexOf(n.level)!==-1?n.level:"info"](T(n.time),n.message)),a.on("error",n=>console.log(`客户端错误: ${n.message}`)),a.on("connected",()=>{l()}),a.on("disconnected",()=>{a=null;const n=e.length;e.length=0,e.push(...new Array(n).fill(0).map(()=>({path:"",stream:void 0}))),r.value.length=0}),a.on("publishStarted",n=>{`${n.streamPath}`}),a.on("publishStopped",n=>{`${n.streamPath}`}),a.on("streamList",n=>{`${n.streams.length}`,n.streams.length===0&&(e.length=0)}),a.on("streamAdded",n=>{`${n.streamId}`,e.some(S=>S.path===n.streamId)&&(r.value.push({id:n.streamId,stream:n.stream}),I())}),a.on("streamRemoved",n=>{`${n.streamId}`});try{await a.connect()}catch{a=null}}),E=async({deviceItem:l,streamItem:c,path:n},m)=>{if(t==="ws-flv"){if(m>=0&&m<e.length){const S={path:n};if(d&&l){if(!l.parentId||!l.deviceId){console.error("GB28181设备信息不完整,无法更新流");return}S.deviceItem=l}else c&&(S.streamItem=c);e[m]={...S}}return}if(d&&l){if(!l.parentId||!l.deviceId){console.error("GB28181设备信息不完整,无法更新流");return}e[m].path=n,e[m].deviceItem=l}else c&&(e[m].path=n,e[m].streamItem=c);if(a||await w(),!r.value.some(S=>n===S.id)){await h();return}},_=async l=>{if(t==="ws-flv"){l>=0&&l<e.length&&(e[l]={path:"",deviceItem:d?{}:void 0,streamItem:d?void 0:{},stream:void 0});return}e[l].path="",delete e[l].deviceItem,delete e[l].streamItem,delete e[l].stream,await h()},P=async l=>{e.length,JSON.stringify(e,null,2);const c=e.length;if(l>c){const n=new Array(l-c).fill({}).map((m,S)=>d?{path:"",deviceItem:{},stream:void 0}:{path:"",streamItem:{},stream:void 0});e.push(...n)}else l<c&&e.splice(l).forEach((m,S)=>{m.stream&&m.path,m.path="",m.stream=void 0,d?m.deviceItem={}:m.streamItem={}});JSON.stringify(e,null,2),t==="webrtc"&&await h()},I=()=>{e.forEach(l=>{var c;l.stream=(c=r.value.find(n=>n.id===l.path))==null?void 0:c.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"&&(r.value.length=0,await h())},resizeStreamList:P,closeAll:()=>{if(t==="ws-flv"){e.forEach((l,c)=>{e[c]=d?{path:"",deviceItem:{},stream:void 0}:{path:"",streamItem:{},stream:void 0}});return}a&&(a.disconnect(),a=null,e.length=0,r.value.length=0)},preConnect:w}}const Qe=Se({id:"app-group-store",state:()=>({groupTree:[],selectedChannel:[],curPlayGroupId:-2}),actions:{setCurPlayGroupId(d){this.curPlayGroupId=d},setGroupTree(d){this.groupTree=d},setSelChannel(d){this.selectedChannel=d},async fetchGroupTree(){const{data:d}=await Ke(-1),t=Ie(d);this.setGroupTree(t)}}});function Ie(d){return d.map(t=>{const e=Ie(t.children),r=t.channels.map(o=>({...o,key:`${o==null?void 0:o.channelId}_${o==null?void 0:o.deviceId}_${o.id}`,isChannel:!0})),a=[...e.map(o=>({...o})),...r];return{...t,key:`${(t==null?void 0:t.key)||t.id}`,children:a}})}const et={class:"screen-container"},tt={class:"flex items-center gap-2 mb-2"},st={class:"text-center"},it={class:"video-player-placeholder"},ge=16,at=ve({__name:"content",props:{type:{default:"device"}},setup(d){const t=V("ws-flv"),e=V(!1),r=d,a=Qe(),o=Je(),h=B({get:()=>o.curScreenNum,set:u=>o.setCurScreenNum(u)}),w=[{label:"单屏",value:1},{label:"四分屏",value:4},{label:"九分屏",value:9},{label:"十六分屏",value:16}],T=B(()=>{switch(h.value){case 1:return 24;case 4:return 12;case 9:return 8;case 16:return 6;default:return 24}}),k=()=>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 u=RTCRtpReceiver.getCapabilities("video");u&&u.codecs&&u.codecs.some(s=>s.mimeType.toLowerCase().includes("h265")||s.mimeType.toLowerCase().includes("hevc"))||(I.value=!0)}else I.value=!0}catch(u){console.warn("检测 H265 支持时发生错误:",u),I.value=!0}},$=V(fe(r.type==="device","webrtc")),l=V(fe(r.type==="device","ws-flv")),c=async u=>{const i=new Array(h.value||1).fill({}).map(()=>r.type==="device"?{path:"",deviceItem:{},stream:void 0}:{path:"",streamItem:{},stream:void 0});await u.resetStreamList(i)};(async()=>{await Promise.all([c($.value),c(l.value)])})();const m=B(()=>o.multiPlayRef),S=B(()=>o.multiPlayRef.streamList);W(S,(u,i)=>{if(t.value,u.length,i==null||i.length,JSON.stringify(u,null,2),i&&(u.forEach((s,g)=>{const v=i[g];v?s.path!==v.path&&`${g}${v.path||"(空)"}${s.path||"(空)"}`:(`${g}`,s.path)}),i.length>u.length))for(let s=u.length;s<i.length;s++)`${s}`,i[s].path},{deep:!0,immediate:!1});const L=V(Array.from({length:ge},(u,i)=>({path:"",deviceItem:{},streamItem:{},stream:void 0,idx:i,isValid:!1,isVisible:!1,slotKey:`fixed-slot-${i}`,colSpanValue:24/1}))),F=()=>{h.value,t.value,JSON.stringify(S.value,null,2);const u=T.value;for(let i=0;i<ge;i++){const s=L.value[i],g=S.value[i],v=i<h.value;g&&"path"in g&&v?(s.path=g.path||"",s.deviceItem=g.deviceItem||{},s.streamItem=g.streamItem||{},s.stream=g.stream,s.isValid=!!(g.path&&g.path.trim().length>0),s.isVisible=!0):(s.path="",s.deviceItem={},s.streamItem={},s.stream=void 0,s.isValid=!1,s.isVisible=v),s.colSpanValue=u}L.value.slice(0,h.value).forEach((i,s)=>{`${s}${i.path||"(空)"}${i.isValid}${i.isVisible}${i.slotKey}`})};W([S,h,t,T],()=>{F()},{immediate:!0,deep:!0}),W(L,(u,i)=>{u.length,i==null||i.length;const s=u.filter(v=>v.isVisible),g=(i==null?void 0:i.filter(v=>v.isVisible))||[];if(s.forEach((v,D)=>{const M=g[D];M?v.path!==M.path?`${D}${M.path||"(空)"}${v.path||"(空)"}`:v.isValid!==M.isValid&&`${D}${M.isValid}${v.isValid}`:(`${D}`,v.path)}),g.length>s.length)for(let v=s.length;v<g.length;v++)`${v}`,g[v].path},{deep:!0,immediate:!1});const U=(u,i)=>(`${t.value}${i}`,m.value.updateItem(u,i)),z=async u=>(`${t.value}`,await m.value.resetStreamList(u)),q=()=>{`${t.value}`,m.value.closeAll()},A=te({selectNum:1});W(h,async(u,i)=>{t.value,e.value=!0,A.selectNum=0;let s=[];if(s=[...m.value.streamList],JSON.stringify(s,null,2),r.type==="device"?(o.setActiveInfo({parentId:"",parentName:"",deviceId:"",name:""}),a.setCurPlayGroupId(-2)):o.setActiveInfo({path:"",type:""}),t.value==="webrtc"){const g=new Array(h.value).fill({}).map(()=>r.type==="device"?{path:"",deviceItem:{},stream:void 0}:{path:"",streamItem:{},stream:void 0});await z(g)}else{s.length>0&&await m.value.resetStreamList(s);const g=m.value.streamList.length;await ie(),await m.value.resizeStreamList(h.value),h.value<g&&await ie()}e.value=!1},{immediate:!0});let y=!1;const p=(u,i)=>{if(A.selectNum=i,r.type!=="stream"&&r.type==="device"&&u.deviceItem&&"deviceId"in u.deviceItem){const s=u.deviceItem;o.setActiveInfo({parentId:s.parentId??"",deviceId:s.deviceId??"",parentName:s.parentName??"",name:s.name??""}),y=!0}};we(()=>q());const{getActiveInfo:f}=De(o);return W([()=>f.value.deviceId,()=>f.value.parentId],([u,i],[s,g])=>{if(e.value)return;const v=`${g}/${s}`,D=`${i}/${u}`;if(r.type==="device"&&D!==v){const M=f.value;if(S.value.some($e=>$e.path===D)&&!y)return ae.warn("当前设备已在分屏中!");U({path:D,deviceItem:M},A.selectNum)}y=!1},{immediate:!0}),W(()=>f.value.path,u=>{if(e.value)return;const i=f.value;if(r.type==="stream"&&u){if(S.value.some(s=>s.path===i.path))return ae.warn("当前设备流已在分屏中!");U({path:i.path,streamItem:i},A.selectNum)}}),W(t,async(u,i)=>{a.setCurPlayGroupId(-2);const s=[...m.value.streamList];JSON.stringify(s,null,2),u==="ws-flv"?(o.setMultiPlayRef(l.value),$.value.closeAll(),I.value=!1,l.value.streamList.length!==h.value&&await l.value.resizeStreamList(h.value),s.length>0&&await l.value.resetStreamList(s)):u==="webrtc"&&(o.setMultiPlayRef($.value),G(),l.value.closeAll(),$.value.streamList.length!==h.value&&await $.value.resizeStreamList(h.value),s.length>0&&await $.value.resetStreamList(s))},{immediate:!0}),(u,i)=>(O(),Y("div",et,[J("div",tt,[C(b(oe),{value:t.value,"onUpdate:value":i[0]||(i[0]=s=>t.value=s),size:"small"},{default:R(()=>[C(b(re),{value:"ws-flv"},{default:R(()=>i[3]||(i[3]=[H("WS-FLV")])),_:1}),C(b(re),{value:"webrtc"},{default:R(()=>i[4]||(i[4]=[H("WebRTC")])),_:1})]),_:1},8,["value"])]),J("div",st,[I.value&&t.value==="webrtc"?(O(),x(b(Oe),{key:0,type:"warning",message:"当前浏览器使用 WebRTC 不支持 H265 解码",description:"如需通过 WebRTC 观看 H265 视频请使用最新版的 Chrome 浏览器,确保显卡驱动已安装最新版本","show-icon":"",closable:"",class:"mb-12px",onClose:i[1]||(i[1]=s=>I.value=!1)})):X("",!0),C(b(oe),{value:h.value,"onUpdate:value":i[2]||(i[2]=s=>h.value=s),buttonStyle:"solid",options:w,optionType:"button"},null,8,["value"]),C(b(ne),{onClick:b(_)},{default:R(()=>[C(b(K),{icon:"ant-design:fullscreen-outlined",class:"v-text-bottom"}),i[5]||(i[5]=H("全屏 "))]),_:1},8,["onClick"]),C(b(Me),{gutter:4,class:"screen-list mt-10px",ref_key:"screenRef",ref:E},{default:R(()=>[b(P)?(O(),x(b(ne),{key:0,onClick:b(_),type:"link",class:"absolute right-2 top-2 z-10 text-white"},{default:R(()=>[C(b(K),{icon:"ant-design:fullscreen-exit-outlined",class:"v-text-bottom"}),i[6]||(i[6]=H(" 退出全屏 "))]),_:1},8,["onClick"])):X("",!0),(O(!0),Y(Ee,null,_e(L.value,s=>Q((O(),x(b(Ge),{key:s.slotKey,span:s.colSpanValue,class:ye(["mt-4px flex-center",{active:h.value>1&&A.selectNum===s.idx&&!b(P),isFullscreen:b(P)}]),onClick:()=>{s.idx,s.path,p({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:g=>console.log("🚀 VideoPlayer beforeCreate:",s.path,"key:",s.slotKey,"isValid:",s.isValid),onVnodeCreated:g=>console.log("✅ VideoPlayer created:",s.path,"key:",s.slotKey,"isValid:",s.isValid),onVnodeBeforeUnmount:g=>console.log("💀 VideoPlayer beforeUnmount:",s.path,"key:",s.slotKey,"isValid:",s.isValid),onVnodeUnmounted:g=>console.log("🗑️ VideoPlayer unmounted:",s.path,"key:",s.slotKey,"isValid:",s.isValid)},{default:R(()=>[s.path?(O(),x(b(le),{key:0,class:"position-absolute bottom-0 left-50% cursor-pointer",title:s.path,getPopupContainer:k},{default:R(()=>[C(b(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,[C(b(le),{title:"当前无信号,请先选择通道",class:"no-stream-tip cursor-pointer",getPopupContainer:k,placement:"top"},{default:R(()=>[C(b(K),{icon:"pepicons-pop:television-play-off",size:h.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-7595560b"]]);export{ut as C,Qe as a,Je as u};