Rantanen / node-opus

Opus bindings for Node.js
MIT License
79 stars 32 forks source link

Strange encoder output format #72

Closed cnm-n closed 5 years ago

cnm-n commented 5 years ago

I'm trying to encode some PCM data:

const opus = require('node-opus');

const rate = 48000;
const frame = rate / 100;

const pcmStream = ...
const encodeStream = new opus.Encoder(rate, 1, frame);

pcmStream.pipe(encodeStream);

encodeStream.on('data', data => {
    console.log(data);
});

The output object contains two fields: 'ref.buffer' and flush, where ref.buffer is:

<Buffer@0x00000000031A5C10 c0 a6 1a 03 00 00 00 00 45 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 48 01 00 00 00 00 00 b0 00 00 00 00 00 00 00, type:
   { [Function: StructType]
     defineProperty: [Function: defineProperty],
     toString: [Function: toString],
     fields: [Object],
     size: 40,
     alignment: 8,
     indirection: 1,
     isPacked: false,
     get: [Function: get],
     set: [Function: set],
     _instanceCreated: true }, _refs:
   [ <Buffer@0x00000000031AA6C0 f0 3d d6 7f 94 51 89 9d 2f ac ec c6 d2 f6 2e db dc 60 9c 72 3a 46 ca a0 1c 0c c3 19 5c a2 58 bb 6e 32 89 82 3d 0d 9d 92 58 7d 0e a6 bd 90 b5 35 61 da ... 19 more bytes> ]>

where _refs buffer seems like valid opus data. I expected to get raw node buffer.

Node v11.10.0

Rantanen commented 5 years ago

Oh, that's unfortunate.

The underlying type is an ogg-packet: https://github.com/TooTallNate/node-ogg-packet/blob/master/index.js

You'll get the actual Opus data with data.packet. Note that there are some metadata frames in there as well, you can skip these by checking for data.granulepos - the headers and tags do not have a position and will define the granulepos as -1.

cnm-n commented 5 years ago

@Rantanen: the data.packet is only first byte of the packet (uchar). Is there a way to get all data without reading memory manually?

Rantanen commented 5 years ago

Probably not. I don't know the insides of the node-ogg or ref-struct packages that well. Personally I've used the raw encode/decode calls instead of the stream interface. You might have more luck with that.