concentus icon indicating copy to clipboard operation
concentus copied to clipboard

How to read Bit rate of opus file in C#

Open liankuai opened this issue 4 years ago • 2 comments

Due to development needs, I need to get the bitrate of the opus file by C#. I can see the average bitrate by using opus-tools 0.2 (https://opus-codec.org/downloads/),but I can't get the bit rate. My idea is to get the bitrate of the opus file through the Concentus library, but I only saw OpusEncode, OpusDecode.Does anyone know how to get the bitrate of opus files?

liankuai avatar Jan 06 '21 02:01 liankuai

This typically isn't something you would do at the Opus codec level. An .opus file is just an Ogg formatted container which has a stream with Opus packets in it. Even in the container, there is no simple metadata field that just has "the bitrate" stored in it that you can read. There are just a bunch of Opus packets in a row, and each one has a "granule position" which tells how far along (milliseconds) in the audio stream that packet corresponds with.

The most correct way do what you want is to open an .opus file, seek to the last packet in the file, and find the granule position of that packet. That will give the the length of the audio stream in minutes:seconds:milliseconds. Then just divide the file size by the audio length to get bits per second. You could probably do this using the Concentus.Oggfile library by doing a SeekTo() and then comparing the audio granule position with the current byte position in the file stream. Or, if you can't guarantee that the stream supports seeking, you could just open the file with a decoder like normal, decode the first few seconds of audio (discarding the audio data), and then estimate using # bytes of the audio stream read divided by # of seconds of audio that was decoded, which will give an approximation of the whole file's bitrate. That's a bit slower though since decoding takes CPU time, and it could give incorrect results if, for example, the audio starts with a long silence which encodes at a much lower bitrate than normal audio.

lostromb avatar Jan 06 '21 19:01 lostromb

This typically isn't something you would do at the Opus codec level. An .opus file is just an Ogg formatted container which has a stream with Opus packets in it. Even in the container, there is no simple metadata field that just has "the bitrate" stored in it that you can read. There are just a bunch of Opus packets in a row, and each one has a "granule position" which tells how far along (milliseconds) in the audio stream that packet corresponds with.

The most correct way do what you want is to open an .opus file, seek to the last packet in the file, and find the granule position of that packet. That will give the the length of the audio stream in minutes:seconds:milliseconds. Then just divide the file size by the audio length to get bits per second. You could probably do this using the Concentus.Oggfile library by doing a SeekTo() and then comparing the audio granule position with the current byte position in the file stream. Or, if you can't guarantee that the stream supports seeking, you could just open the file with a decoder like normal, decode the first few seconds of audio (discarding the audio data), and then estimate using # bytes of the audio stream read divided by # of seconds of audio that was decoded, which will give an approximation of the whole file's bitrate. That's a bit slower though since decoding takes CPU time, and it could give incorrect results if, for example, the audio starts with a long silence which encodes at a much lower bitrate than normal audio.

Thank you very much . I will try it.

liankuai avatar Jan 08 '21 08:01 liankuai