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:
@@ -161,6 +161,11 @@ export async function demux(
|
|||||||
// stderr and are parsed for dimensions/fps.
|
// stderr and are parsed for dimensions/fps.
|
||||||
"-loglevel",
|
"-loglevel",
|
||||||
"info",
|
"info",
|
||||||
|
// Input format hint: prepareStream always emits raw AnnexB H264 on
|
||||||
|
// pipe:0. Raw H264 has NO magic header, so ffmpeg's auto-detection
|
||||||
|
// fails with "Invalid data found when processing input" whenever the
|
||||||
|
// first bytes arrive late/buffered. Pin the demuxer input format.
|
||||||
|
...(isStream ? ["-f", "h264"] : []),
|
||||||
"-i",
|
"-i",
|
||||||
isStream ? "pipe:0" : input,
|
isStream ? "pipe:0" : input,
|
||||||
"-c:v",
|
"-c:v",
|
||||||
|
|||||||
@@ -302,16 +302,15 @@ export class Streamer {
|
|||||||
channelId: channel_id,
|
channelId: channel_id,
|
||||||
botId: user_id,
|
botId: user_id,
|
||||||
} = this.voiceConnection;
|
} = this.voiceConnection;
|
||||||
// Mimic the real Discord client when starting Go Live: flip the voice
|
// Un-deafen before requesting the stream (mimic real client). Do NOT
|
||||||
// state to video-enabled (and un-deafen) BEFORE requesting the stream.
|
// set self_video: true — that flips on the bot's camera in Discord
|
||||||
// Discord's gateway silently ignores STREAM_CREATE while the user's
|
// (visible to everyone); screen share should not enable the camera.
|
||||||
// voice state still has self_video: false.
|
|
||||||
this.sendOpcode(GatewayOpCodes.VOICE_STATE_UPDATE, {
|
this.sendOpcode(GatewayOpCodes.VOICE_STATE_UPDATE, {
|
||||||
guild_id,
|
guild_id,
|
||||||
channel_id,
|
channel_id,
|
||||||
self_mute: false,
|
self_mute: false,
|
||||||
self_deaf: false,
|
self_deaf: false,
|
||||||
self_video: true,
|
self_video: false,
|
||||||
});
|
});
|
||||||
this.sendOpcode(GatewayOpCodes.STREAM_CREATE, {
|
this.sendOpcode(GatewayOpCodes.STREAM_CREATE, {
|
||||||
type,
|
type,
|
||||||
|
|||||||
@@ -105,7 +105,11 @@ export class ScreenShareController {
|
|||||||
frameRate: 30,
|
frameRate: 30,
|
||||||
bitrateVideo: 2500,
|
bitrateVideo: 2500,
|
||||||
bitrateVideoMax: 4000,
|
bitrateVideoMax: 4000,
|
||||||
includeAudio: true,
|
// Video-only GoLive: the -f h264 output muxer cannot carry audio
|
||||||
|
// ("h264 muxer does not support any stream of type audio" → header
|
||||||
|
// write fails → empty stdout → demux 'Invalid data' → black tile).
|
||||||
|
// Audio is not delivered by the GoLive demux path anyway.
|
||||||
|
includeAudio: false,
|
||||||
videoCodec: normalizeVideoCodec("H264"),
|
videoCodec: normalizeVideoCodec("H264"),
|
||||||
});
|
});
|
||||||
const { command } = prepared;
|
const { command } = prepared;
|
||||||
|
|||||||
Reference in New Issue
Block a user