[Libav-user] RTP Opus demuxer is missing extradata with Opus header
Jonathan Baudanza
jon at jonb.org
Thu Oct 29 23:45:52 EET 2020
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20201029/02af93bd/attachment.html>
More information about the Libav-user
mailing list