翻遍全网,在python上运行opus的资料少之又少,看了很多远古帖子,勉强把opus-python跑了起来,踩了好多个坑,必须记录下来,opus作为一种优秀的音频编码方式,在未来一定会占据广阔的市场

必备条件:

  1. windows操作系统-64位
  2. python3.x 64位
  3. opus.dll 64位

一路经历:
先通过pip安装opus,pip install opuslib 这个OPUS库并不包含编码器,只是调用了相关平台的动态链接库的接口,因此我们还需要下载动态链接库opus.dll,安装的第三方库位于C:\Users\13588\AppData\Local\Programs\Python\Python37\Lib\site-packages\opuslib,我们在api文件夹内修改__init__.py中的代码,注释掉这部分代码:

# lib_location = find_library('opus')
# if lib_location is None:
#     raise Exception(
#         'Could not find Opus library. Make sure it is installed.')

手动修改载入dll库:

libopus = ctypes.windll.LoadLibrary(r"C:\Users\13588\AppData\Local\Programs\Python\Python37\Lib\site-packages\opuslib\opus.dll")

刚开始从百度下载的opus.dll,但是是32位的,在64位系统中无法调用,在这里下载了64位的dll,放在对应文件夹中,下载地址在:
https://ci.appveyor.com/project/rillian/opus,选择Configuration: ReleaseDLL_fixed; Platform: x64----->Artifacts 点击下载,到此为止opus动态链接库算是完成了

刚开始使用的python是32位,库中有一个ctype的操作用到了指针操作,在32位python上无法操作,提示有超出16位的字节,于是重装成64位的python,重新安装opuslib,修改调用动态库的代码和动态库,应该就可以使用了。

以下是demo:

import opuslib
import opuslib.api.encoder
import opuslib.api.decoder
#导入库

rwalist = [i for i in range(0,160)]#创建一个原始样本

enc = opuslib.Encoder(fs = 16000,channels = 1 ,application = "audio")#创建编码器
dec = opuslib.Decoder(fs = 16000,channels = 1 )#创建解码器
enc._set_vbr(1)
encoutput = enc.encode(bytes(rwalist),160)#开始编码,数据保存在encoutput中
decoutput = dec.decode(encoutput,160)#开始解码,数据保存在decoutput中

print(rwalist)
print(encoutput)
print(decoutput)


2022.9.30,国庆快乐,更新了demo,但是仍然存在问题,采样频率与实际不匹配,可能是pyaudio声卡的问题

import opuslib
import opuslib.api.encoder
import opuslib.api.decoder
import pyaudio
import wave
import struct
import numpy as np
import time #导入库

wave_read = wave.open(r"C:\Users\13588\Desktop\test.wav", "rb")
wav_channels = wave_read.getnchannels()
wav_samplewidth = wave_read.getsampwidth()
wav_samplerate = wave_read.getframerate()
wav_frames = wave_read.getnframes()

print("通道:",wav_channels)
print("位深:",wav_samplewidth)
print("采样率:",wav_samplerate)
print("数据总长度:",wav_frames)

p = pyaudio.PyAudio()#创建一个声卡输出
stream = p.open(format=p.get_format_from_width(wav_samplewidth), channels=wav_channels, rate=wav_samplerate, output=True)

rwalist = []
for i in range(wav_frames):
    val, = struct.unpack('h', wave_read.readframes(1))
    rwalist.append(val)
rwalist = np.array(rwalist)
#stream.write(rwalist.tobytes())#这里可以试听读取出来的WAV



enc = opuslib.Encoder(fs = wav_samplerate,channels = 1 ,application = "audio")#创建编码器
enc._set_bandwidth(1105)
enc._set_lsb_depth(16)
enc._set_complexity(10)
enc._set_bitrate(wav_samplerate*2)
enc._set_vbr(1)
enc._set_force_channels(1)
enc._set_packet_loss_perc(0)
dec = opuslib.Decoder(fs = wav_samplerate,channels = 1 )#创建解码器

wav_frame_cnt = 0
bunk = int(wav_samplerate*0.06)
print(bunk)
while wav_frame_cnt<wav_frames-bunk :
    print(wav_frame_cnt,wav_frame_cnt+bunk)
    rawData = rwalist[wav_frame_cnt:wav_frame_cnt+bunk]
    encoutput = enc.encode(bytes(rawData),bunk)#开始编码,数据保存在encoutput中
    decoutput = dec.decode(encoutput,bunk)#开始解码,数据保存在decoutput中
    stream.write(decoutput) #数据通过声卡打印出来
    wav_frame_cnt = wav_frame_cnt +bunk
print("end.")