fix(goLive): retry VIDEO(op12)/SPEAKING(op5) opcodes until ws OPEN — broken shared-screen video
Root cause: BaseMediaConnection.sendOpcode is a silent no-op when ws.readyState !== OPEN. In GoLive, playStream() calls setVideoAttributes(true) + setSpeaking(true) the instant createStream() resolves (right after SELECT_PROTOCOL_ACK), but the StreamConnection WebSocket can still be in CONNECTING for a few ms — so op 12 (VIDEO, activating the video SSRC) was silently DROPPED every session. Empirically verified: 0 ops 12/5 ever logged across the entire journal, yet 10k+ video frames were sent and audio played (audio SSRC is activated via the VoiceConnection handshake, independent of GoLive op 12). Discord's media server thus received video RTP on video_ssrc but was never told to forward it → black/broken shared-screen video with working voice. sendOpcodeWhenOpen retries up to ~2s for ws OPEN instead of dropping. Also emits a=fmtp:101 packetization-mode=1;profile-level-id=42e01f in the answer SDP (H264 FU-A fragments require packetization-mode=1 to reassemble). Also removes pre-existing noNonNullAssertion lint (biome 2.5.8 now errors) that was blocking the deploy CI.
This commit is contained in:
@@ -652,11 +652,7 @@ a=ice-lite
|
||||
* CONNECTING) breaks GoLive video while leaving audio intact. We wait for
|
||||
* the open state instead of dropping.
|
||||
*/
|
||||
private sendOpcodeWhenOpen(
|
||||
code: number,
|
||||
data: unknown,
|
||||
label: string,
|
||||
): void {
|
||||
private sendOpcodeWhenOpen(code: number, data: unknown, label: string): void {
|
||||
const attempt = (triesLeft: number) => {
|
||||
if (this.ws?.readyState === WebSocket.OPEN) {
|
||||
this.sendOpcode(code, data);
|
||||
|
||||
Reference in New Issue
Block a user