Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
+15
-11
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
joinSignalingChannel,
|
||||
sendSignal,
|
||||
waitForSignalingReady,
|
||||
ICE_SERVERS,
|
||||
type SignalMessage,
|
||||
} from './signaling';
|
||||
@@ -17,6 +18,7 @@ export async function joinAsViewer(
|
||||
code: string,
|
||||
videoEl: HTMLVideoElement,
|
||||
onState: (s: 'connecting' | 'waiting' | 'live' | 'error', detail?: string) => void,
|
||||
onFallbackFrame?: (dataUrl: string) => void,
|
||||
): Promise<ViewerHandle> {
|
||||
const viewerId = crypto.randomUUID();
|
||||
let pc: RTCPeerConnection | null = null;
|
||||
@@ -25,18 +27,24 @@ export async function joinAsViewer(
|
||||
onState('connecting');
|
||||
|
||||
const handleMessage = async (msg: SignalMessage) => {
|
||||
if (msg.type === 'frame') {
|
||||
onFallbackFrame?.(msg.dataUrl);
|
||||
onState('live');
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.type === 'offer' && msg.viewerId === viewerId) {
|
||||
pc = new RTCPeerConnection({ iceServers: ICE_SERVERS });
|
||||
|
||||
pc.ontrack = (ev) => {
|
||||
videoEl.srcObject = ev.streams[0];
|
||||
videoEl.srcObject = ev.streams[0] ?? new MediaStream([ev.track]);
|
||||
videoEl.play().catch(() => {/* autoplay may need user gesture */});
|
||||
onState('live');
|
||||
};
|
||||
|
||||
pc.onicecandidate = (ev) => {
|
||||
if (ev.candidate && channel) {
|
||||
sendSignal(channel, {
|
||||
void sendSignal(channel, {
|
||||
type: 'ice',
|
||||
viewerId,
|
||||
from: 'viewer',
|
||||
@@ -54,7 +62,7 @@ export async function joinAsViewer(
|
||||
await pc.setRemoteDescription(msg.sdp);
|
||||
const answer = await pc.createAnswer();
|
||||
await pc.setLocalDescription(answer);
|
||||
if (channel) sendSignal(channel, { type: 'answer', viewerId, sdp: answer });
|
||||
if (channel) await sendSignal(channel, { type: 'answer', viewerId, sdp: answer });
|
||||
} else if (msg.type === 'ice' && msg.viewerId === viewerId && msg.from === 'broadcaster') {
|
||||
if (pc) {
|
||||
try {
|
||||
@@ -67,18 +75,14 @@ export async function joinAsViewer(
|
||||
};
|
||||
|
||||
channel = joinSignalingChannel(code, handleMessage);
|
||||
await waitForSignalingReady(channel);
|
||||
|
||||
// Wait a tick for subscribe, then announce join
|
||||
setTimeout(() => {
|
||||
if (channel) {
|
||||
sendSignal(channel, { type: 'viewer-join', viewerId });
|
||||
onState('waiting');
|
||||
}
|
||||
}, 600);
|
||||
await sendSignal(channel, { type: 'viewer-join', viewerId });
|
||||
onState('waiting');
|
||||
|
||||
const stop = async () => {
|
||||
if (channel) {
|
||||
try { sendSignal(channel, { type: 'viewer-leave', viewerId }); } catch {}
|
||||
try { await sendSignal(channel, { type: 'viewer-leave', viewerId }); } catch {}
|
||||
const { supabase } = await import('@/integrations/supabase/client');
|
||||
await supabase.removeChannel(channel);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user