opus编解码初体验
背景
opus是流媒体的标准库。本文先暂时略过其中的背景故事,先来看一下其中的接入细节。
接入细节
客户端原始PCM --> encode --> 包的传输 --> decode --> 最终PCM
初体验
编译
编译:./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
编译
win32
下载Visual Studio 2015 community 中文版,然后打开源代码中的win32项目文件,选中win64环境,编译出ReleaseDll包。