perf(golive/spike): binding addTrack + TS port of @dank074 media stack
Phase 1 spike: replace @dank074/discord-video-stream + node-datachannel +
node-av (1.3GB) with minimal libdatachannel N-API binding + native RTP
packetizers (H264 FU-A, RTCP SR/NACK, pacer) + pure-TS GoLive stack.
Binding v0.4: addTrack (m=audio/video SDP), TrackWrap w/ setPacketizer +
sendFrame (raw RTP to transport) + addTimestamp — verified by two-peer
handshake emitting SDP with audio(opus 120)+video(H264 101) and 8-frame
RTP roundtrip.
TS layer (src/goLive/, 21 files): CodecPayloadType, VoiceOpCodes,
GatewayOpCodes, utils, BaseMediaConnection (voice WS + DAVE + heartbeat),
VoiceConnection, StreamConnection, Streamer, WebRtcWrapper (SDP mungling,
DAVE encrypt, packetizer chain), BaseMediaStream (pacing/sync), VideoStream,
AudioStream, Demuxer (ffmpeg-spawn NUT/AnnexB, no node-av 114M binary),
Encoders, prepareStream/playStream.
Integration: screenShareController.ts now imports from ../../goLive/index.js —
prepareStream(prepared, ...) + playStream(prepared, streamer, {...}).
Tests: tests/goLive-port.test.ts (8/8 pass). tsc --noEmit clean. biome clean.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* StreamConnection — GoLive stream connection (screen share).
|
||||
* Ported from @dank074/discord-video-stream StreamConnection.js.
|
||||
*/
|
||||
|
||||
import { BaseMediaConnection } from "./BaseMediaConnection.js";
|
||||
import { VoiceOpCodes } from "./VoiceOpCodes.js";
|
||||
|
||||
export class StreamConnection extends BaseMediaConnection {
|
||||
_streamKey: string | null = null;
|
||||
_serverId: string | null = null;
|
||||
|
||||
setSpeaking(speaking: boolean): void {
|
||||
if (!this.webRtcParams) throw new Error("WebRTC connection not ready");
|
||||
this.sendOpcode(VoiceOpCodes.SPEAKING, {
|
||||
delay: 0,
|
||||
speaking: speaking ? 2 : 0,
|
||||
ssrc: this.webRtcParams.audioSsrc,
|
||||
});
|
||||
}
|
||||
|
||||
get daveChannelId(): string {
|
||||
if (this._serverId === null) {
|
||||
throw new Error("Server ID not set (this shouldn't happen)");
|
||||
}
|
||||
const channelId = BigInt(this._serverId) - 1n;
|
||||
return channelId.toString();
|
||||
}
|
||||
|
||||
get serverId(): string | null {
|
||||
return this._serverId;
|
||||
}
|
||||
|
||||
set serverId(id: string | null) {
|
||||
this._serverId = id;
|
||||
}
|
||||
|
||||
get streamKey(): string | null {
|
||||
return this._streamKey;
|
||||
}
|
||||
|
||||
set streamKey(value: string | null) {
|
||||
this._streamKey = value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user