I am trying to write the contents of an RTP-OPUS stream to an OGG-OPUS file. 
The purpose is to send a WebRTC session to Google's Speech-to-text API, which 
accepts OGG-OPUS as input.

The opus muxer requires that an opus header be present in extradata. It seems 
that the demuxer from my RTP stream doesn't include this.

If I construct the opus header myself and insert it into extradata, everything 
works great. This seems like a hack though. Is this something that the RTP 
demuxer should be doing?

Here is the code. I'm using some node bindings for libavformat called 
"beamcoder". I can reproduce the same issue with the ffmpeg commandline.

  const demuxer = await beamcoder.demuxer({
    url: 'file:input.sdp',
    options: {
      protocol_whitelist: "file,rtp,udp"
    }
  });


  // Construct an Oups Header.
  // This seems like a hack, but is required to get the opux muxer to work
  const opusHeader = Buffer.alloc(19);
  // 
https://www.opus-codec.org/docs/opusfile_api-0.4/structOpusHead.html#details
  // 
https://github.com/xiph/opusfile/blob/4174c26e0aaab19d01afdea0a46f7f95fdc6b3e6/src/info.c#L40
  // magic bytes for opus
  opusHeader.write('OpusHead', 0, 8, "ascii");
  // Version
  opusHeader.writeUInt8(1, 8);
  // Channel count
  opusHeader.writeUInt8(2, 9);
  // Pre skip
  opusHeader.writeUInt16LE(0, 10);
  // Sample rate
  opusHeader.writeUInt32LE(48000, 12);
  // Output gain (db)
  opusHeader.writeUInt16LE(0, 16);
  // Mapping family
  opusHeader.writeUInt8(0, 18);

  const streamConfig = demuxer.streams[0];
  streamConfig.codecpar.extradata = opusHeader;

  const muxer = await beamcoder.muxer({ filename: 'file:test.opus' });

  const stream = muxer.newStream(demuxer.streams[0]);
  await muxer.openIO();

  // This invokes avformat_write_header, which will raise a "no extradata 
present" error unless I build my own opus header.
  // The error is raised from inside oggenc.c / ogg_init
  await muxer.writeHeader();

  while (true) {
    const packet = await demuxer.read();
    if (packet == null)
        break;
    await muxer.writeFrame(packet);
  }
  await muxer.writeTrailer();

This is my SDP file:

  v=0
  o=- 0 0 IN IP4 127.0.0.1
  s=Mediasoup
  c=IN IP4 127.0.0.1
  t =0 0
  m=audio 5004 RTP/AVPF 100
  a=rtcp:5005
  a=rtpmap:100 opus/48000/2

I asked a similar question yesterday in the ffmpeg-users list, but I think it 
may be more appropriate here:

http://www.ffmpeg-archive.org/Error-raised-in-oggenc-c-when-trying-to-create-opus-file-from-RTP-stream-td4694549.html
_______________________________________________
Libav-user mailing list
Libav-user@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
libav-user-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to