记录OPUS在python上运行的曲折历程
翻遍全网,在python上运行opus的资料少之又少,看了很多远古帖子,勉强把opus-python跑了起来,踩了好多个坑,必须记录下来,opus作为一种优秀的音频编码方式,在未来一定会占据广阔的市场
必备条件:
- windows操作系统-64位
- python3.x 64位
- 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.")
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
哥们,那个网址好像下载不了了,可以共享一下么
抱歉,我去年重装过一次系统,数据丢失了