1 line
9.7 KiB
JavaScript
1 line
9.7 KiB
JavaScript
import{C as e,G as t,J as n,L as r,N as i,O as a,S as o,T as s,U as c,V as l,_ as u,a as d,b as f,c as p,g as m,i as ee,j as h,k as te,n as g,p as _,q as v,r as y,s as b,t as x}from"./ui-BjxGELcM.js";import{t as S}from"./cloud-CIOLOOjB.js";import{a as ne,c as re,i as ie,l as ae,n as oe,o as se,s as C,u as w}from"./webrtc-C76mftVq.js";import{t as T}from"./globe-Cy3sFr4f.js";import{t as ce}from"./message-square-DGTwCJY8.js";import{t as E}from"./server-nMqD8oSq.js";import{t as D}from"./video-02fL9iqS.js";import{a as le}from"./index-BsK239Bd.js";var O=[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`rect`,{x:`9`,y:`9`,width:`6`,height:`6`,rx:`1`,key:`1ssd4o`}]],ue=e=>r(u,t(e,{iconNode:O,name:`circle-stop`})),de=a(`<div class="flex flex-wrap items-end justify-between gap-4"><div><p class="mono-label text-muted-foreground">publish / </p><h1 class="display mt-2 text-4xl sm:text-5xl">开始直播</h1><p class="mt-3 max-w-lg text-sm text-muted-foreground">推流仅进入 SRS 主干(WHIP),分发由服务端按配置扇出到多路。</p></div><div class="flex items-center gap-3 border border-line bg-card/60 px-4 py-2.5"><span class=mono-label>`),fe=a(`<div class="pointer-events-none absolute inset-0 flex flex-col items-center justify-center gap-2.5 text-white/60"><span class="flex size-12 items-center justify-center border border-white/20 bg-white/5"></span><span class="micro-label text-white/50">camera off`),k=a(`<div class="relative h-full border border-line bg-card/50 p-4 sm:p-5"><div class="flex flex-wrap items-center justify-between gap-2"><div class="flex items-center gap-2"><h3 class=font-semibold>本地预览</h3><span class="micro-label text-muted-foreground">preview · trunk: </span></div><div class="flex items-center gap-3"><span class="font-mono text-[11px] text-muted-foreground"></span></div></div><div class="relative mt-4 aspect-video overflow-hidden border border-line/70 bg-black"><video autoplay playsinline muted class=size-full></video><div class="pointer-events-none absolute top-3 left-3 flex flex-wrap items-center gap-1.5"></div></div><div class="mt-4 flex flex-wrap gap-2">`),A=a(`<div class="relative border border-line bg-card/50 p-4 sm:p-5"><div class="flex items-center justify-between gap-2"><div class="flex items-center gap-2"><h3 class=font-semibold>分发方式</h3><span class="micro-label text-muted-foreground">distributions</span></div></div><p class="mt-2 text-xs leading-relaxed text-muted-foreground">由服务端按 DISTRIBUTORS 配置自动扇出,推流端无需选择后端。</p><div class="mt-4 space-y-2.5"></div><p class="mt-4 border-t border-line/70 pt-4 text-xs leading-relaxed text-muted-foreground">主干为 SRS,推流凭证仅在服务端会话中生效。`),j=a(`<div class="mt-4 grid gap-3 md:grid-cols-2">`),M=a(`<div class="relative border border-line bg-card/50 p-4 sm:p-5"><div class="flex items-center gap-2"><h3 class=font-semibold>主干状态</h3><span class="micro-label text-muted-foreground">trunk status`),N=a(`<div class="relative border border-line bg-card/50 p-4 sm:p-5"><div class="flex items-center justify-between gap-2"><div class="flex items-center gap-2"><h3 class=font-semibold>房间弹幕 / 聊天</h3><span class="micro-label text-muted-foreground">danmaku</span></div></div><div class="mt-4 h-80 min-h-0">`),P=a(`<div class="mx-auto max-w-[1400px] space-y-5 px-4 py-8 sm:px-6 sm:py-10"><div class="grid gap-4 lg:grid-cols-[minmax(0,1.6fr)_minmax(0,1fr)]">`),F=a(`<p class="text-sm text-muted-foreground">正在读取分发配置…`),I=a(`<div><div class="flex min-w-0 items-center gap-3"><span class="flex size-9 shrink-0 items-center justify-center border border-line bg-background text-foreground/80"></span><div class=min-w-0><p class="text-sm font-medium"></p><p class="micro-label mt-1 text-muted-foreground"> · `),L=a(`<div class="mt-4 border border-dashed border-line px-5 py-8 text-center text-sm text-muted-foreground">尚未开始推流`),R=a(`<div class="mt-3 flex flex-wrap gap-2"><a class=mono-chip target=_blank rel=noreferrer>HLS</a><a class=mono-chip target=_blank rel=noreferrer>FLV`),z=a(`<div class="relative border border-line/80 bg-background/40 p-4"><span class="absolute top-0 left-0 h-3 w-3 border-t-2 border-l-2 border-acid-lime"aria-hidden=true></span><div class="flex items-center justify-between gap-2"><span class="truncate text-sm font-medium">SRS 主干`);function B(e){return e===`DISTRIBUTION_KIND_SRS_HLS`?`SRS HLS 直推`:e===`DISTRIBUTION_KIND_CF_SFU`?`Cloudflare SFU`:e===`DISTRIBUTION_KIND_CDN`?`第三方 CDN`:e}function pe(e){return e===`DISTRIBUTION_KIND_SRS_HLS`?E:e===`DISTRIBUTION_KIND_CF_SFU`?S:e===`DISTRIBUTION_KIND_CDN`?T:E}var V=()=>{let t=le({from:`/publish`}),a=()=>t().room,[u,S]=c([]),[T,O]=c(`SRS`),[V,H]=c(null),[U,W]=c(!1),[G,K]=c([]),[q,J]=c(``),[Y,me]=c([]),[X,he]=c(!0),Z,Q;n(()=>{m.getConfig().then(e=>{S(e.distributors||[]),e.trunk&&O(e.trunk.name||`SRS`)}).catch(()=>{});let e=C(a(),e=>{K(e.targets||[])}),t=se(a(),e=>me(t=>[...t,e].slice(-100)));v(()=>{e(),t()})});let ge=(e,t)=>{ne(a(),e,t).catch(()=>{})},_e=async()=>{if(!_.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=await m.publish(a(),`BACKEND_KIND_SRS`,``);Q=await ie({stream:t.stream,token:t.publish_token,local:e,iceServers:(t.ice_servers||[]).map(oe)})}catch(e){J(String(e?.message||e)),W(!1)}},$=async()=>{try{Q?.close()}catch{}Q=void 0;for(let e of G())try{await m.stop(a(),e.backend)}catch{}V()&&(V().getTracks().forEach(e=>e.stop()),H(null)),K([]),W(!1)};return v($),(()=>{var t=P(),n=t.firstChild;return o(t,r(p,{get children(){var e=de(),t=e.firstChild,n=t.firstChild;n.firstChild;var i=t.nextSibling,s=i.firstChild;return o(n,a,null),o(i,r(d,{get active(){return U()}}),s),o(s,()=>U()?`推流中 / live`:`待机 / standby`),o(i,r(b,{get active(){return U()}}),null),e}}),n),o(t,r(i,{get when(){return!_.can(`room:publish`)},get children(){return r(x,{tone:`warning`,get children(){return[`当前角色(`,e(()=>_.role()),`)无权发布,仅 admin / publisher 可推流。可切换到「观看」进入房间发弹幕。`]}})}}),n),o(t,r(i,{get when(){return q()},get children(){return r(x,{tone:`error`,get children(){return q()}})}}),n),o(n,r(p,{delay:1,class:`min-w-0`,get children(){var t=k(),n=t.firstChild,a=n.firstChild,s=a.firstChild,c=s.nextSibling;c.firstChild;var l=a.nextSibling,u=l.firstChild,f=n.nextSibling,p=f.firstChild,m=p.nextSibling,h=f.nextSibling;return o(t,r(ee,{}),n),o(a,r(D,{class:`size-4 text-acid-lime`}),s),o(c,T,null),o(u,(()=>{var t=e(()=>!!V());return()=>t()?`${V().getVideoTracks().length} 视频 · ${V().getAudioTracks().length} 音频`:`tracks · off`})()),o(l,r(y,{variant:`ghost`,size:`sm`,onClick:()=>he(e=>!e),get children(){return X()?`隐藏弹幕`:`显示弹幕`}}),null),te(e=>Z=e,p),o(f,r(i,{get when(){return X()},get children(){return r(ae,{messages:Y})}}),m),o(m,r(g,{get variant(){return U()?`success`:`outline`},class:`bg-black/50 shadow-sm backdrop-blur-sm`,get children(){return[r(d,{get active(){return U()}}),e(()=>U()?`LIVE`:`STANDBY`)]}}),null),o(m,r(g,{variant:`secondary`,class:`border-line bg-black/50 text-white/90 shadow-sm backdrop-blur-sm`,children:`SRS WHIP`}),null),o(f,r(i,{get when(){return!V()},get children(){var e=fe(),t=e.firstChild;return o(t,r(D,{class:`size-5`})),e}}),null),o(h,r(y,{class:`h-10`,onClick:_e,get disabled(){return U()||!_.can(`room:publish`)},get children(){return[r(D,{class:`size-4`}),`开始推流`]}}),null),o(h,r(y,{variant:`danger`,class:`h-10`,onClick:$,get disabled(){return!U()},get children(){return[r(ue,{class:`size-4`}),`停止推流`]}}),null),t}}),null),o(n,r(p,{delay:2,class:`min-w-0 self-start`,get children(){var t=A(),n=t.firstChild,a=n.firstChild,s=a.firstChild,c=n.nextSibling.nextSibling;return o(a,r(E,{class:`size-4 text-acid-lime`}),s),o(n,r(g,{variant:`muted`,get children(){return[e(()=>u().length),` 路`]}}),null),o(c,r(i,{get when(){return u().length>0},get fallback(){return F()},get children(){return r(h,{get each(){return u()},children:e=>{let t=pe(e.kind);return(()=>{var n=I(),i=n.firstChild.firstChild,a=i.nextSibling.firstChild,s=a.nextSibling,c=s.firstChild;return o(i,r(t,{class:`size-4`})),o(a,()=>e.name),o(s,()=>B(e.kind),c),o(s,()=>e.enabled?`已启用`:`未启用`,null),o(n,r(g,{get variant(){return e.configured?`success`:`muted`},get children(){return e.configured?`就绪`:`未配置`}}),null),l(()=>f(n,`flex items-center justify-between gap-3 border p-3 transition-colors ${e.configured?`border-line bg-background/50`:`border-line/60 bg-background/20 opacity-70`}`)),n})()}})}})),t}}),null),o(t,r(p,{delay:1,get children(){var e=M(),t=e.firstChild,n=t.firstChild;return o(t,r(w,{class:`size-4 text-acid-lime`}),n),o(e,r(i,{get when(){return G().length>0},get fallback(){return L()},get children(){var e=j();return o(e,r(h,{get each(){return G()},children:e=>(()=>{var t=z(),n=t.firstChild.nextSibling;return n.firstChild,o(n,r(g,{variant:`success`,get children(){return[r(d,{active:!0}),`直播中`]}}),null),o(t,r(i,{get when(){return e.stream},get children(){var t=R(),n=t.firstChild,i=n.firstChild,a=n.nextSibling,c=a.firstChild;return o(n,r(w,{class:`size-3`}),i),o(a,r(w,{class:`size-3`}),c),l(t=>{var r=`/live/${e.stream}.m3u8`,i=`/live/${e.stream}.flv`;return r!==t.e&&s(n,`href`,t.e=r),i!==t.t&&s(a,`href`,t.t=i),t},{e:void 0,t:void 0}),t}}),null),t})()})),e}}),null),e}}),null),o(t,r(p,{delay:2,get children(){var e=N(),t=e.firstChild,n=t.firstChild,i=n.firstChild,a=t.nextSibling;return o(n,r(ce,{class:`size-4 text-acid-lime`}),i),o(t,r(g,{variant:`muted`,get children(){return Y().length}}),null),o(a,r(re,{messages:Y,get canChat(){return _.can(`room:chat`)},onSend:ge})),e}}),null),t})()};export{V as Publish}; |