diff --git a/src/lib/agora-config.ts b/src/lib/agora-config.ts index ae1c231..2e7c637 100644 --- a/src/lib/agora-config.ts +++ b/src/lib/agora-config.ts @@ -20,7 +20,7 @@ export class AgoraClient { constructor(config: AgoraConfig) { this.config = { - mode: 'rtc', + mode: 'live', codec: 'vp8', ...config }; @@ -31,10 +31,12 @@ export class AgoraClient { const AgoraRTC = (await import('agora-rtc-sdk-ng')).default; - // Force RTC mode and VP8 codec for video streaming + // Use live-broadcast mode so the client can subscribe to streams injected + // by Agora Media Gateway (RTMP/SRT ingest), which join the channel as + // live-broadcast hosts. An rtc/communication-mode client cannot see them. this.client = AgoraRTC.createClient({ - mode: 'rtc', - codec: 'vp8' + mode: this.config.mode || 'live', + codec: this.config.codec || 'vp8' }); this.setupEventListeners(); @@ -205,11 +207,24 @@ export class AgoraClient { } } + // In live-broadcast mode every client must declare its role before joining: + // publishers join as hosts, viewers as audience so they subscribe to hosts. + await this.client.setClientRole(role === 'publisher' ? 'host' : 'audience'); + + // Coerce a numeric uid to a Number. The cameras are injected by Media + // Gateway with integer uids; joining with a *string* uid puts us in + // user-account mode, where we don't receive the host's published stream + // (black screen). Keep genuinely non-numeric accounts as-is. + const joinUid = + this.config.uid === undefined || this.config.uid === null || this.config.uid === '' + ? null + : (isNaN(Number(this.config.uid)) ? this.config.uid : Number(this.config.uid)); + const uid = await this.client.join( this.config.appId.trim(), this.config.channel.trim(), token, - this.config.uid || null + joinUid ); console.log(`Joined channel as ${role} with uid:`, uid);