live-sfu-demo/internal/server/static/assets/publish-B-tBrFGx.js

1 line
8.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import{C as e,D as t,E as n,F as r,G as i,K as a,U as o,V as s,a as ee,b as c,f as l,h as u,i as d,j as f,k as p,m,n as h,o as te,r as g,t as _,x as v,z as ne}from"./ui-W1Pm8dqI.js";import{t as y}from"./cloud-CTCP3hC3.js";import{a as re,c as ie,d as ae,f as oe,l as se,m as b,o as ce,p as le,r as x,t as ue,u as de}from"./webrtc-D2p8RYHA.js";import{t as S}from"./server-C0Pmpptj.js";import{a as fe,t as C}from"./index-CFU6bGFM.js";var w=[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`rect`,{x:`9`,y:`9`,width:`6`,height:`6`,rx:`1`,key:`1ssd4o`}]],pe=e=>r(u,o(e,{iconNode:w,name:`circle-stop`})),me=n(`<div class="flex items-center justify-between"><div class="flex items-center gap-2"><h3 class=font-semibold>本地预览</h3></div><span class="font-mono text-xs text-muted-foreground">`),he=n(`<div class="pointer-events-none absolute inset-0 flex flex-col items-center justify-center gap-2 text-white/60"><span class="flex size-12 items-center justify-center rounded-full border border-white/20 bg-white/5"></span><span class=text-xs>摄像头未开启`),ge=n(`<div class="acid-frame relative aspect-video overflow-hidden rounded-md border bg-black"><video autoplay playsinline muted class=size-full>`),T=n(`<div class="flex flex-wrap gap-2">`),E=n(`<div class="flex items-center justify-between"><div class="flex items-center gap-2"><h3 class=font-semibold>分发后端`),D=n(`<div class=space-y-2>`),O=n(`<p class="text-xs leading-relaxed text-muted-foreground">推流凭证仅在服务端会话中生效,浏览器端不会出现 SFU 密钥。`),k=n(`<div class="flex items-center gap-2"><h3 class=font-semibold>分发状态`),A=n(`<div class="grid gap-2 md:grid-cols-2">`),j=n(`<div class="flex items-center justify-between"><div class="flex items-center gap-2"><h3 class=font-semibold>房间弹幕 / 聊天`),M=n(`<div class="h-80 min-h-0">`),N=n(`<div class=space-y-6><div class="flex flex-col gap-2 sm:flex-row sm:items-end sm:justify-between"><div class=space-y-1.5><h1 class="text-2xl font-semibold">开始直播</h1><p class="text-sm text-muted-foreground">房间 <span class="font-mono text-foreground"></span> · 选择分发后端,一路推流将扇出到所选 SFU。</p></div></div><div class="grid grid-cols-1 gap-4 lg:grid-cols-2">`),P=n(`<p class="text-sm text-muted-foreground">正在读取后端配置…`),F=n(`<div class="flex items-center justify-between gap-3 rounded-md border p-3"><div class="flex min-w-0 items-center gap-3"><span class="flex size-8 shrink-0 items-center justify-center rounded-md bg-secondary text-foreground/70"></span><div class=min-w-0><p class="mt-1 text-xs text-muted-foreground"> · `),I=n(`<div class="rounded-md border border-dashed p-5 text-center text-sm text-muted-foreground">尚未开始推流`),L=n(`<div class="flex flex-wrap gap-x-3 gap-y-1 font-mono text-xs"><a class="inline-flex items-center gap-1 text-primary hover:underline"target=_blank>HLS</a><a class="inline-flex items-center gap-1 text-primary hover:underline"target=_blank>FLV`),_e=n(`<p class="truncate font-mono text-[11px] text-muted-foreground">session:`),R=n(`<div class="space-y-2 rounded-md border p-3"><div class="flex items-center justify-between gap-2"><span class="flex min-w-0 items-center gap-2 text-sm font-medium">`);function z(e){return e===`BACKEND_KIND_CLOUDFLARE`?`Cloudflare Realtime`:e===`BACKEND_KIND_SRS`?`SRS`:e}function ve(e){return e===`BACKEND_KIND_CLOUDFLARE`?y:S}var B=()=>{let n=fe({from:`/publish`}),o=()=>n().room,[u,y]=s([]),[w,B]=s({BACKEND_KIND_CLOUDFLARE:!0,BACKEND_KIND_SRS:!0}),[V,H]=s(null),[U,W]=s(!1),[G,K]=s([]),[q,J]=s(``),[Y,ye]=s([]),[X,be]=s(!0),Z,Q={};a(()=>{m.getConfig().then(e=>y(e.backends||[])).catch(()=>{});let e=se(o(),e=>K(e.targets||[])),t=ie(o(),e=>ye(t=>[...t,e].slice(-100)));i(()=>{e(),t()})});let xe=(e,t)=>{ce(o(),e,t).catch(()=>{})},Se=e=>B(t=>({...t,[e]:!t[e]})),Ce=async()=>{if(!l.can(`room:publish`)){J(`当前角色无权发布(需要 room:publish)`);return}J(``),W(!0);try{if(!V()){let e=await navigator.mediaDevices.getUserMedia({video:!0,audio:!0});H(e),Z&&(Z.srcObject=e)}let e=V(),t=u().filter(e=>w()[e.kind]);for(let n of t){let t=await m.publish(o(),n.kind,``);n.kind===`BACKEND_KIND_SRS`?Q.srs=await re({stream:t.stream,token:t.publish_token,local:e,iceServers:(t.ice_servers||[]).map(x)}):n.kind===`BACKEND_KIND_CLOUDFLARE`&&(Q.cloudflare=await ue({sessionId:t.session_id,local:e,iceServers:(t.ice_servers||[]).map(x)}))}}catch(e){J(String(e?.message||e)),W(!1)}},$=async()=>{for(let e of Object.keys(Q)){try{Q[e].close()}catch{}delete Q[e]}for(let e of G())try{await m.stop(o(),e.backend)}catch{}V()&&(V().getTracks().forEach(e=>e.stop()),H(null)),K([]),W(!1)};return i($),(()=>{var n=N(),i=n.firstChild,a=i.firstChild.firstChild.nextSibling.firstChild.nextSibling,s=i.nextSibling;return c(a,o),c(i,r(h,{get variant(){return U()?`success`:`outline`},get children(){return[r(te,{get active(){return U()}}),v(()=>U()?`推流中`:`待机`)]}}),null),c(n,r(f,{get when(){return!l.can(`room:publish`)},get children(){return r(_,{tone:`warning`,get children(){return[`当前角色(`,v(()=>l.role()),`)无权发布,仅 admin / publisher 可推流。可切换到「观看」进入房间发弹幕。`]}})}}),s),c(n,r(f,{get when(){return q()},get children(){return r(_,{tone:`error`,get children(){return q()}})}}),s),c(s,r(d,{class:`space-y-3 p-5`,get children(){return[(()=>{var e=me(),t=e.firstChild,n=t.firstChild,i=t.nextSibling;return c(t,r(C,{class:`size-4 text-primary`}),n),c(e,r(g,{variant:`ghost`,size:`sm`,onClick:()=>be(e=>!e),get children(){return X()?`隐藏弹幕`:`显示弹幕`}}),i),c(i,(()=>{var e=v(()=>!!V());return()=>e()?`${V().getVideoTracks().length} 视频 · ${V().getAudioTracks().length} 音频`:`off`})()),e})(),(()=>{var e=ge(),n=e.firstChild;return t(e=>Z=e,n),c(e,r(f,{get when(){return X()},get children(){return r(ae,{messages:Y})}}),null),c(e,r(f,{get when(){return!V()},get children(){var e=he(),t=e.firstChild;return c(t,r(C,{class:`size-5`})),e}}),null),e})(),(()=>{var e=T();return c(e,r(g,{onClick:Ce,get disabled(){return U()||!l.can(`room:publish`)},get children(){return[r(C,{class:`size-4`}),`开始推流`]}}),null),c(e,r(g,{variant:`danger`,onClick:$,get disabled(){return!U()},get children(){return[r(pe,{class:`size-4`}),`停止推流`]}}),null),e})()]}}),null),c(s,r(d,{class:`space-y-3 p-5`,get children(){return[(()=>{var e=E(),t=e.firstChild,n=t.firstChild;return c(t,r(S,{class:`size-4 text-primary`}),n),c(e,r(h,{variant:`secondary`,get children(){return[v(()=>u().length),` 路`]}}),null),e})(),(()=>{var e=D();return c(e,r(f,{get when(){return u().length>0},get fallback(){return P()},get children(){return r(p,{get each(){return u()},children:e=>{let t=ve(e.kind);return(()=>{var n=F(),i=n.firstChild.firstChild,a=i.nextSibling,o=a.firstChild,s=o.firstChild;return c(i,r(t,{class:`size-4`})),c(a,r(ee,{get label(){return e.name},get checked(){return!!w()[e.kind]},onChange:()=>Se(e.kind),get disabled(){return U()}}),o),c(o,()=>z(e.kind),s),c(o,()=>e.primary?`主 SFU`:`对照后端`,null),c(n,r(h,{get variant(){return e.configured?`success`:`warning`},get children(){return e.configured?`已配置`:`未配置`}}),null),n})()}})}})),e})(),O()]}}),null),c(n,r(d,{class:`space-y-3 p-5`,get children(){return[(()=>{var e=k(),t=e.firstChild;return c(e,r(le,{class:`size-4 text-primary`}),t),e})(),r(f,{get when(){return G().length>0},get fallback(){return I()},get children(){var t=A();return c(t,r(p,{get each(){return G()},children:t=>(()=>{var n=R(),i=n.firstChild,a=i.firstChild;return c(a,()=>z(t.backend)),c(i,r(h,{variant:`success`,children:`直播中`}),null),c(n,r(f,{get when(){return t.stream},get children(){var n=L(),i=n.firstChild,a=i.firstChild,o=i.nextSibling,s=o.firstChild;return c(i,r(b,{class:`size-3.5`}),a),c(o,r(b,{class:`size-3.5`}),s),ne(n=>{var r=`/live/${t.stream}.m3u8`,a=`/live/${t.stream}.flv`;return r!==n.e&&e(i,`href`,n.e=r),a!==n.t&&e(o,`href`,n.t=a),n},{e:void 0,t:void 0}),n}}),null),c(n,r(f,{get when(){return t.session_id},get children(){var e=_e();return e.firstChild,c(e,()=>t.session_id,null),e}}),null),n})()})),t}})]}}),null),c(n,r(d,{class:`flex flex-col gap-3 p-5`,get children(){return[(()=>{var e=j(),t=e.firstChild,n=t.firstChild;return c(t,r(oe,{class:`size-4 text-primary`}),n),c(e,r(h,{variant:`muted`,get children(){return Y().length}}),null),e})(),(()=>{var e=M();return c(e,r(de,{messages:Y,get canChat(){return l.can(`room:chat`)},onSend:xe})),e})()]}}),null),n})()};export{B as Publish};