opus编解码初体验

  |   0 评论   |   0 浏览

背景

opus是流媒体的标准库。本文先暂时略过其中的背景故事,先来看一下其中的接入细节。

接入细节

客户端原始PCM --> encode --> 包的传输 --> decode --> 最终PCM

初体验

编译

下载opus-1.3.1.tar.gz源码

编译:./configure && make

opus_demo进行编解码

在编译出的目录下,有一个opus_demo可执行文件,可以用来测试编解码过程。

准备wav文件bot-sample.wav:https://b3logfile.com/file/2022/06/bot-sample-deac6c02.wav

编码:

opus_demo -e audio 16000 1 256000 bot-sample.wav t1.bit

结果

libopus 1.3.1
Encoding 16000 Hz input at 256.000 kb/s in auto bandwidth with 320-sample frames.
average bitrate:             229.503 kb/s
maximum bitrate:             407.600 kb/s
active bitrate:              278.163 kb/s
bitrate standard deviation:   54.642 kb/s

解码:

opus_demo -d 16000 1 t1.bit t1.pcm

结果

libopus 1.3.1
Decoding with 16000 Hz output (1 channels)
average bitrate:             229.503 kb/s
maximum bitrate:             407.600 kb/s
bitrate standard deviation:   54.642 kb/s

pcm转wav

ffmpeg -f s16le -ar 16k -ac 1 -i t1.pcm t1.wav

使用opus库进行麦克风收音和播放

运行[3]中的代码,可以实现通过麦克风进行收音,编码,解码和播放的过程。

音频文件读写

读取PCM文件为ShortBuffer

// 将原始音频,读入 ShortBuffer
        byte[] bytes = Files.readAllBytes(inputPcmPath);

        short[] audio = new short[bytes.length / 2];

        for (int i = 0; i != bytes.length; i += 2) {
            int b2 = bytes[i] & 0xff;
            int b1 = bytes[i + 1] << 8;
            audio[i / 2] = (short) (b1 | b2);
        }
        ShortBuffer audioBuffer = ShortBuffer.wrap(audio);

将ShortBuffer写入PCM文件

wav格式的文件是以小端形式来存储的,即低位存放在低位内存中,高位存放在高位内存中。

在生成pcm文件的时候,一定要以小端形式存储数据,否则播放音频文件的时候完全是混乱的杂音。

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        while (buffer.hasRemaining()) {
            short s = buffer.get();
            //存放低位
            byteArrayOutputStream.write((byte) ((s << 24) >> 24));
            //存放高位
            byteArrayOutputStream.write((byte) ((s << 16) >> 24));
        }

    return byteArrayOutputStream.toByteArray();

周边知识

编码模式application

  • OPUS_APPLICATION_AUDIO

OPUS_APPLICATION_RESTRICTED_LOWDELAY

OPUS_APPLICATION_VOIP

比特率 bitrate

bitrate单位是bit/s

复杂度 complexity

复杂度 complexity的范围为1-10,1最低,10最高,值越高越复杂。

信号类型 signal_type

  • OPUS_AUTO:默认值
  • OPUS_SIGNAL_VOICE
  • OPUS_SIGNAL_MUSIC

参考

  1. 实时音频编解码之十一Opus编码
  2. 实时音频编解码之十六 Opus解码
  3. tbocek/opus-wrapper@github
  4. java实现录音并保存为wav格式的音频文件