PageSourceSearch

https://picockpit.com/dist/WrtcVideo-b619e531.js

js picockpit.com collected 2026-10-02 14:40:56 UTC 12,356 bytes, 9 lines download raw bytes

1import{m as u,N as k,A as P}from"./Kiosk-5189673b.js";import{w as v}from"./Terminal-74185f4a.js";import{b3 as y,b4 as l,ba as p,bd as U,b8 as I,ac as d,bI as V,b as q,c8 as W,T as A,bA as h,b5 as g,b6 as w,be as S,b7 as D,b9 as L,by as N,ah as _,bb as Q,cc as O}from"./AppNotFound-05d3ab5c.js";import{N as R}from"./Scheduler-cee6408e.js";async function E(){const s="/api/v2.0/system/client/clients";try{const t=await fetch(s,{method:"GET",headers:{"Content-Type":"application/json"}}),e=await t.json();return t.status==500?{...e,i18n:`${s}-500`}:e}catch(t){throw t}}const j=2e3,$=s=>JSON.parse(`"${s}"`),M=s=>s!==null?s.split(", ").map(t=>{const e=t.match(/^<(.+?)>; rel="ice-server"(; username="(.*?)"; credential="(.*?)"; credential-type="password")?/i),i={urls:[e[1]]};return e[3]!==void 0&&(i.username=$(e[3]),i.credential=$(e[4]),i.credentialType="password"),i}):[],B=s=>{const t={iceUfrag:"",icePwd:"",medias:[]};for(const e of s.split(`\r
2`))e.startsWith("m=")?t.medias.push(e.slice(2)):t.iceUfrag===""&&e.startsWith("a=ice-ufrag:")?t.iceUfrag=e.slice(12):t.icePwd===""&&e.startsWith("a=ice-pwd:")&&(t.icePwd=e.slice(10));return t},F=s=>{let t="",e=s.split(`\r
3`);for(let i=0;i<e.length;i++)if(e[i].startsWith("a=rtpmap:")&&e[i].toLowerCase().includes("opus/")){t=e[i].slice(9).split(" ")[0];break}if(t==="")return s;for(let i=0;i<e.length;i++)e[i].startsWith("a=fmtp:"+t+" ")&&(e[i].includes("stereo")||(e[i]+=";stereo=1"),e[i].includes("sprop-stereo")||(e[i]+=";sprop-stereo=1"));return e.join(`\r
4`)},H=s=>{const t=s.sdp.split("m=");for(let e=0;e<t.length;e++){const i=t[e];i.startsWith("audio")&&(t[e]=F(i))}s.sdp=t.join("m=")},J=(s,t)=>{const e={};for(const r of t){const o=r.sdpMLineIndex;e[o]===void 0&&(e[o]=[]),e[o].push(r)}let i="a=ice-ufrag:"+s.iceUfrag+`\r
5a=ice-pwd:`+s.icePwd+`\r
6`,n=0;for(const r of s.medias){if(e[n]!==void 0){i+="m="+r+`\r
7a=mid:`+n+`\r
8`;for(const o of e[n])i+="a="+o.candidate+`\r
9`}n++}return i};class z{constructor(t,e,i,n){this.video=t,this.clientId=e,this.onError=n,this.path=i,this.pc=null,this.restartTimeout=null,this.sessionUrl="",this.queuedCandidates=[],this.start()}start(){console.log("requesting ICE servers"),new u(`tf://${this.clientId}/mediamtx/${this.path}/whep`,{method:"OPTIONS"}).then(t=>this.onIceServers(t)).catch(t=>{console.log("error: "+t),this.scheduleRestart(),this.onError("Error Ice Servers: "+t)})}onIceServers(t){this.pc=new RTCPeerConnection({iceServers:M(t.headers.get("Link"))});const e="sendrecv";this.pc.addTransceiver("video",{direction:e}),this.pc.addTransceiver("audio",{direction:e}),this.pc.onicecandidate=i=>this.onLocalCandidate(i),this.pc.oniceconnectionstatechange=()=>this.onConnectionState(),this.pc.ontrack=i=>{console.log("new track:",i.track.kind),this.video.srcObject=i.streams[0]},this.pc.createOffer().then(i=>this.onLocalOffer(i))}onLocalOffer(t){H(t),this.offerData=B(t.sdp),this.pc.setLocalDescription(t),console.log("sending offer"),new u(`tf://${this.clientId}/mediamtx/${this.path}/whep`,{method:"POST",headers:{"Content-Type":"application/sdp"},body:t.sdp}).then(e=>{if(e.status!==201)throw this.onError("Error Whep: "+e.status),new Error("bad status code");return this.sessionUrl=e.headers.get("location"),e.text()}).then(e=>this.onRemoteAnswer(new RTCSessionDescription({type:"answer",sdp:e}))).catch(e=>{console.log("error: "+e),this.scheduleRestart()})}onConnectionState(){if(this.restartTimeout===null)switch(console.log("peer connection state:",this.pc.iceConnectionState),this.pc.iceConnectionState){case"disconnected":this.scheduleRestart()}}onRemoteAnswer(t){this.restartTimeout===null&&(this.pc.setRemoteDescription(t),this.queuedCandidates.length!==0&&(this.sendLocalCandidates(this.queuedCandidates),this.queuedCandidates=[]))}onLocalCandidate(t){this.restartTimeout===null&&t.candidate!==null&&(this.sessionUrl===""?this.queuedCandidates.push(t.candidate):this.sendLocalCandidates([t.candidate]))}sendLocalCandidates(t){new u(`tf://${this.clientId}/mediamtx${this.sessionUrl}`,{method:"PATCH",headers:{"Content-Type":"application/trickle-ice-sdpfrag","If-Match":"*"},body:J(this.offerData,t)}).then(e=>{if(e.status!==204)throw this.onError("Error Path: "+e.status),new Error("bad status code")}).catch(e=>{console.log("error: "+e),this.scheduleRestart()})}scheduleRestart(){this.restartTimeout===null&&(this.pc!==null&&(this.pc.close(),this.pc=null),this.restartTimeout=window.setTimeout(()=>{this.restartTimeout=null,this.start()},j),this.sessionUrl&&new u(`tf://${this.clientId}/mediamtx${this.sessionUrl}`,{method:"DELETE"}).then(t=>{if(t.status!==200)throw this.onError("Error Delete: "+t.status),new Error("bad status code")}).catch(t=>{console.log("delete session error: "+t)}),this.sessionUrl="",this.queuedCandidates=[])}}const G=s=>{const t=(s||window.location.search).split("?")[1];if(!t)return{};const e=t.split("&"),i={};for(let n=0;n<e.length;n++){const r=e[n].split("="),o=decodeURIComponent(r[0]),c=decodeURIComponent(r[1]||"");o&&(i[o]?Array.isArray(i[o])?i[o].push(c):i[o]=[i[o],c]:i[o]=c)}return i},f=(s,t)=>{const e=["1","yes","true"],i=["0","no","false"];return s=(s||"").toString(),e.includes(s.toLowerCase())?!0:i.includes(s.toLowerCase())?!1:t},K=s=>{let t=G();s.controls=f(t.controls,!0),s.muted=f(t.muted,!0),s.autoplay=f(t.auto
9play,!0),s.playsInline=f(t.playsinline,!0)},Z=(s,t)=>()=>{const e=document.createElement("video");e.id="video",K(e),t.append(e),s(e)},b={initVideoElement:Z,WHEPClient:z};const X={components:{},props:{serial:{type:String,default:"",required:!0},source:{type:String,default:"",required:!0},host:{type:String,default:"default",required:!1}},i18n:{},mounted:async function(){const s=(e=>this.$emit("notify",{text:e,timeout:5})).bind(this),t=await v.getCredentials(this.serial,s);v.postCredentialsToClient("wrtcvideo",this.serial,t,s),this.init()},data(){return{clientInfo:{},wrtcPeer:null}},methods:{async init(){try{this.allClients=await E()}catch(e){console.log(e)}this.clientBySerial={};for(const e of this.allClients)this.clientBySerial[e.serial]=e;this.clientInfo=this.clientBySerial[this.serial];const s=document.getElementById(`${this.host}-${this.source}-container`);console.log("Init",this.source);const t=(e=>this.$emit("notify",{text:e,timeout:5})).bind(this);b.initVideoElement(e=>(this.wrtcPeer=new b.WHEPClient(e,this.serial,this.source,t),this.wrtcPeer),s)()},endSession(){console.log("Ending wrtc video session."),this.wrtcPeer.restartTimeout=0,this.wrtcPeer.pc!==null&&(this.wrtcPeer.pc.close(),this.wrtcPeer.pc=null),this.wrtcPeer.sessionUrl="",this.wrtcPeer.queuedCandidates=[]}}},Y={class:"video-top"},ee={style:{padding:"0px 5px",position:"absolute",width:"fit-content","background-color":"#0008",color:"white"}};function te(s,t,e,i,n,r){return l(),p("div",Y,[U("div",ee,I(n.clientInfo.name+" "+e.source),1),d(V,{class:"video-parent pa-0",id:`${e.host}-${e.source}-container`,"data-path":e.source},null,8,["id","data-path"])])}const se=y(X,[["render",te]]);function ie(s,t){for(const e of s)new u(`tf://${e}/wrtcvideo/getsources`,{timeout:1e4}).then(i=>i.json()).then(i=>{if(i.statusCode!=0)if(i.statusCode==200)t(i.data.map(n=>({clientUUID:e,...n})));else throw new Error(`getSources status: ${i.statusCode}`)})}const T={getSources:ie};function ne(s,t){fetch("/api/v2.0/user/videostream_quota",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({call:"sta",serial:s,min:0})}).then(e=>e.json()).then(e=>{t(e)}).catch(e=>{throw"getQuota: "+e})}function oe(s,t,e){fetch("/api/v2.0/user/videostream_quota",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({call:"upd",serial:s,min:t})}).then(i=>i.json()).then(i=>{e&&e(i)}).catch(i=>{throw"getQuota: "+i})}async function re(s){if(s.status!=200){const t=await s.json(),e=`${t.statusCode}: ${t.error}`;throw console.log(e),new Error(e)}}async function ae(){const s=await fetch("/api/v2.0/user/profile",{method:"GET",headers:{"Content-Type":"application/json"}});return await re(s),await s.json()}const m={getQuota:ne,updQuota:oe,getProfile:ae};const ce={components:{WrtcVideo:se,Notifier:k,Nudge:R},props:{clientUUIDs:{type:Array,default:Array,required:!1},autoClients:{type:Boolean,default:!0,required:!1},denyDev:{type:Array,default:()=>[],required:!1},allowDev:{type:Array,default:()=>[],required:!1}},i18n:{messages:{en:{title:"Streaming Video",loading:"Loading...",nosrc:"No sources found",limit:"Time limit exceeded"},de:{title:"Video Streamen",loading:"Lädt...",nosrc:"Keine Quellen gefunden",limit:"Zeitlimit überschritten"}}},created(){this.$watch("clientUUIDs",()=>{let s;for(;(s=this.clientUUIDs.pop())!=null;)T.getSources([s],this.addSources)},{deep:!0,immediate:!0})},setup(){let s=q(0);const t=W();return A(async()=>{let e=!1;try{e=(await m.getProfile()).pro_tier=="pro"}catch(i){t.ctx.$refs.notifier.notify({text:i})}e==!1?(setTimeout(t.ctx.testQuota,1e3),s.value=setInterval(t.ctx.updQuota,6e4)):console.log("Quota disabled")}),{quotaTimer:s}},beforeRouteLeave(s,t,e){this.resetQuotaTimer(),e()},data(){return{sinkSources:[],mainMsg:"",hideVid:!0}},computed:{vwCol(){return this.calculateRowsCols(this.sinkSources.length).cols}},async mounted(){if(this.mainMsg=this.$t("loading"),this.autoClients){const s=await E();for(const t of s.map(e=>e.serial))T.getSources([t],this.addSources)}},methods:{resetQuotaTimer(){clearInterval(this.quotaTimer)},updQuota(){try{this.testQuota(),m.updQuota("",this.sinkSources.length)}catch(s){this.$refs.notifier.notify({text:s})}},testQuota(){try{m.getQuota("",s=>{s.used>30&&(this.resetQuotaTimer(),this.endSessions(),this.$refs.notifier.notify({text:this.$t("limit"),color:"warning",timeout:10}),this.mainMsg=this.$t("limit"),this.sinkSources=[],this.$refs.nudge.show("runVideoApp"))})}catch(s){this.$refs.notifier.notify({text:s})}},addSources(s){if(console.log(s),this.allowDev.length>0&&(s=s.filter(t=>this.allowDev.includes(t.name))),this.denyDev.length>0&&(s=s.filter(t=>!this.denyDev.includes(t.name))),s.length==0){this.mainMsg=this.$t("nosrc");return}this.sinkSources.push(...s)},onVidClick(s){this.hideVid?document.querySelectorAll(".video-item").forEach(e
9=>{e.getAttribute("data-name")==s?e.classList.add("show"):e.classList.add("hide")}):document.querySelectorAll(".video-item").forEach(e=>{e.classList.remove("hide"),e.classList.remove("show")}),this.hideVid=!this.hideVid},calculateRowsCols(s){const t=Math.sqrt(s),e=Math.ceil(t);return{rows:Math.ceil(s/e)||0,cols:e}},endSessions(){for(const s of this.sinkSources)this.$refs["vidWidget-"+s.name][0].endSession()}}},le={class:"d-flex ga-0 flex-wrap",style:{margin:"auto",width:"fit-content"}},de=["data-name","onClick"];function ue(s,t,e,i,n,r){const o=h("WrtcVideo"),c=h("Notifier"),x=h("Nudge");return l(),p(_,null,[n.sinkSources.length==0?(l(),g(L,{key:0},{default:w(()=>[d(S),D(I(n.mainMsg),1),d(S)]),_:1})):N("",!0),d(V,{class:"mt-4 mb-4"},{default:w(()=>[U("div",le,[(l(!0),p(_,null,Q(this.sinkSources,a=>(l(),p("div",{key:a,class:"video-item","data-name":`${a.clientUUID}-${a.name}`,style:O(`min-width: 300px; width: ${100/r.vwCol}%; height: auto; aspect-ratio: 16/9; background-color: black; overflow: hidden;`),onClick:C=>r.onVidClick(`${a.clientUUID}-${a.name}`)},[(l(),g(o,{ref_for:!0,ref:`vidWidget-${a.name}`,key:a.dev,serial:a.clientUUID,source:a.name,host:e.autoClients?a.clientUUID:"default",onNotify:t[0]||(t[0]=C=>s.$refs.notifier.notify(C))},null,8,["serial","source","host"]))],12,de))),128))]),d(c,{ref:"notifier"},null,512),d(x,{ref:"nudge"},null,512)]),_:1})],64)}const he=y(ce,[["render",ue]]),fe={components:{AppWrapper:P,WrtcVideoApp:he},i18n:{messages:{en:{title:"Streaming Video"},de:{title:"Video Streamen"}}},data(){return{clients:[]}},beforeRouteLeave(s,t,e){"wva"in this.$refs&&this.$refs.wva!=null&&(console.log("Exiting."),this.$refs.wva.endSessions(),this.$refs.wva.resetQuotaTimer()),e()},computed:{},mounted(){this.clients.push(this.$refs.aw.getClientUUID())},methods:{}};function pe(s,t,e,i,n,r){const o=h("WrtcVideoApp"),c=h("AppWrapper");return l(),g(c,{ref:"aw",icon:"mdi-camera-rear",title:this.$t("title")},{default:w(()=>[d(o,{ref:"wva",clientUUIDs:n.clients,autoClients:!1,denyDev:["video255"]},null,8,["clientUUIDs"])]),_:1},8,["title"])}const me=y(fe,[["render",pe]]),ve=Object.freeze(Object.defineProperty({__proto__:null,default:me},Symbol.toStringTag,{value:"Module"}));export{he as W,ve as a,m as u};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.