Use PlainTransport Producer to receive any packet without knowing SSRC

Original question from Issues · versatica/mediasoup · GitHub
“Producers currently require at least 1 encoding with SSRC or RID defined (or MID). However, we are trying to receive SRTP using a PlainTransport from a 3rd party source that we don’t have implementation control over. We currently extract the crypto suite and key from the SDP that is sent over the SIP Invite but they do not send over the SSRC of the stream (same with RID and MID). This means we currently have no way of receiving the audio via PlainTransport since we cannot create a producer.”

Based on the answer “So if you use a single encoding (no simulcast) there is no need for signaling ssrc or rid in RtpParameters, so your use case would work.”, I’m assuming then I don’t need to specify SSRC but the code snippet below does not work without SSRC:

const worker = await mediasoup.createWorker({
  logLevel: 'debug',
  logTags: [
    'info',
    'ice',
    'dtls',
    'rtp',
    'srtp',
    'rtcp',
  ],
  rtcMinPort: 7000,
  rtcMaxPort: 8000,
});

const mediaCodecs: mediasoup.types.RtpCodecCapability[] = [
  {
    kind: 'audio',
    mimeType: 'audio/PCMU',
    clockRate: 8000,
    channels: 1,
    preferredPayloadType: 0,
  },
];
const rtpCodecParameters: mediasoup.types.RtpCodecParameters[] = [
  {
    mimeType: 'audio/PCMU',
    clockRate: 8000,
    channels: 1,
    payloadType: 0,
  },
];

const router = await worker.createRouter({ mediaCodecs });

const producerTransport = await router.createPlainTransport({
  listenIp: '0.0.0.0', 
  port: 6800, 
  rtcpMux: false,
  comedia: true, 
  enableSrtp: true, 
});
await producerTransport.connect({
  srtpParameters: {
    cryptoSuite: 'AES_CM_128_HMAC_SHA1_80',
    keyBase64: '<BASE64 KEY PLACEHOLDER>',
  }
});
const producer = await producerTransport.produce({
  kind: 'audio',
  rtpParameters: {
    codecs: rtpCodecParameters,
  }
});

When I run this I get this error:

  mediasoup:Channel request() [method:transport.connect, id:3] +1ms
  mediasoup:Channel request succeeded [method:transport.connect, id:3] +0ms
  mediasoup:Transport produce() +2ms
  mediasoup:Channel request() [method:transport.produce, id:4] +2ms
  mediasoup:ERROR:Channel [pid:11972 RTC::Producer::Producer() | throwing MediaSoupTypeError: wrong entry in rtpMapping.encodings (missing ssrc or rid, or rtpParameters.mid) +0ms
  mediasoup:ERROR:Channel [pid:11972 Worker::HandleRequest() | throwing MediaSoupTypeError: wrong entry in rtpMapping.encodings (missing ssrc or rid, or rtpParameters.mid) [method:transport.produce] +1ms
  mediasoup:WARN:Channel request failed [method:transport.produce, id:4]: wrong entry in rtpMapping.encodings (missing ssrc or rid, or rtpParameters.mid) [method:transport.produce] +0ms

Same thing if I do:

const producer = await producerTransport.produce({
  kind: 'audio',
  rtpParameters: {
    codecs: rtpCodecParameters,
    encodings: [{}]
  }
});

I am not quite sure how to get around this at the moment, any advice would be much appreciated.
Thank you

I was wrong in my previous response in GitHub. This scenario is indeed not supported (on purpose). I’ve updated the docs in the web:

  • If a single encoding is given, RTP send parameters must include mid value or the encoding must indicate the ssrc of the stream.

Definitely we cannot match a stream just based on payloadType. This existed in the past and we removed it because it was hell to maintain and a Pandora Box for unexpected issues and vulnerabilities. mediasoup is intented to support modern RTP stacks that could even send MANY RTP streams on the same UDP-TCP tuple/transport.

In summary: If you want to produce() a single RTP stream you need to signal rtpParameters.mid or rtpParameters.encodings[0].ssrc.

Ah okay, thank you for the response!

I have a follow up question. Is this the same for a consumer as well?

" The RTP receive parameters will always have their ssrc values randomly generated for all of its encodings (and optional rtx: { ssrc: XXXX } if the endpoint supports RTX), regardless of the original RTP send parameters in the associated producer. This applies even if the producer’s encodings have rid set."

According to this for a consumer we do not have to pass in a valid ssrc. However if we do not pass rtpParameters.encodings[0].ssrc, we are getting the following error.

“ERTC::Consumer::Consumer() | throwing MediaSoupTypeError: invalid encoding in rtpParameters (missing ssrc)“”.

What am I missing here?

You are reading the RTP parameters of the consumer (receive RTP parameters) that are generated by mediasoup. You need to read about send parameters.

1 Like