fix(goLive): black screen root cause — h264 muxer can't carry audio; disable self_video camera

ROOT CAUSE of empty GoLive tile (finally): prepareStream ran with
includeAudio: true + output -f h264. The h264 muxer cannot mux audio
('h264 muxer does not support any stream of type audio') → header write
fails -22 → stdout empty → Demuxer ffmpeg 'Invalid data found when
processing input' → 0 frames → black tile. Reproduced locally end-to-end
(13s backpressure delay + prepareStream + demux).

Fixes:
- screenShareController: includeAudio: false (video-only GoLive; demux
  path never delivers audio anyway)
- Demuxer: pin input format -f h264 for stream inputs (raw AnnexB H264
  has no magic header → auto-detect unreliable on delayed pipes)
- Streamer.signalStream: self_video: false — stop flipping on the bot's
  camera in Discord (user request; screen share ≠ camera)

Verified: local repro now emits 644 frames 1280x720 (was 0); tsc/biome/
vitest all green.
This commit is contained in:
asepharyana
2026-08-12 00:25:01 +07:00
parent 968a43b0f4
commit 407e003399
3 changed files with 14 additions and 6 deletions
@@ -302,16 +302,15 @@ export class Streamer {
channelId: channel_id,
botId: user_id,
} = this.voiceConnection;
// Mimic the real Discord client when starting Go Live: flip the voice
// state to video-enabled (and un-deafen) BEFORE requesting the stream.
// Discord's gateway silently ignores STREAM_CREATE while the user's
// voice state still has self_video: false.
// Un-deafen before requesting the stream (mimic real client). Do NOT
// set self_video: true — that flips on the bot's camera in Discord
// (visible to everyone); screen share should not enable the camera.
this.sendOpcode(GatewayOpCodes.VOICE_STATE_UPDATE, {
guild_id,
channel_id,
self_mute: false,
self_deaf: false,
self_video: true,
self_video: false,
});
this.sendOpcode(GatewayOpCodes.STREAM_CREATE, {
type,