I’m feeding an FFmpeg-sourced RTSP camera’s audio into mediasoup via a PlainTransport producer, then consuming it via a standard WebRtcTransport consumer in the browser. The audio has a persistent crackling/static artifact — but only after passing through mediasoup. I’ve done extensive isolation testing and would appreciate any insight into what might be happening in the relay itself.
Setup:
- Source: IP camera, RTSP, native audio is G.722 16kHz mono
- FFmpeg transcodes to Opus for the mediasoup leg
- mediasoup version: [3.19.17]
- Node.js version: [22.17.0]
FFmpeg audio args:
-af aresample=48000 -c:a libopus -application voip -ar 48000 -ac 2 -b:a 40k
Producer Creation
const audioProducer = await entry.audioTransport.produce({
kind: "audio",
rtpParameters: {
codecs: [
{
mimeType: "audio/opus",
payloadType: 97,
clockRate: 48000,
channels: 2,
parameters: {
"sprop-stereo": 1,
"usedtx": 0,
},
},
],
encodings: [{ ssrc }],
},
});
What I’ve isolated so far (each step tested independently):
FFmpeg resample alone → local WAV file → clean, no crackling
FFmpeg full Opus encode (audio-only) → local .opusfile → clean
FFmpeg combined video+audio encode (matching production args) → local .mkvfile → clean
FFmpeg’s actual RTP output → received directly via ffplay(bypassing mediasoup entirely, using a manual SDP file) → clean
Same FFmpeg RTP stream → mediasoup PlainTransportproducer →WebRtcTransportconsumer → browser → crackling- Confirmed the corruption is present in the raw
MediaStreamTrackitself (captured directly viaMediaRecorderfromconsumer.trackin the browser, bypassing any<video>element / UI code) → still crackles
Producer and consumer stats during a crackling session (packetsLost, nackCount, jitter all clean):
// producer (inbound-rtp, what mediasoup received from ffmpeg)
{"packetsLost":0,"jitter":669,"nackCount":0,"score":10,"packetCount":190}
// consumer (outbound-rtp, what mediasoup sent to browser)
{"packetsLost":0,"jitter":658,"nackCount":0,"score":10,"packetCount":241}
Question: Since mediasoup terminates and re-originates the RTP stream (new SSRC/sequence/timestamp base) rather than doing a byte-level passthrough, is there a known issue or requirement around:
- RTP timestamp granularity/consistency expected from non-browser (FFmpeg) Opus producers specifically?
- DTX/FEC parameter mismatches between producer and consumer causing decode-side artifacts?
- Any known interaction between
PlainTransportcomedia mode and Opus timestamp remapping for the WebRTC consumer leg?