python : PortAudio + Opus encoding/decoding

标签 python portaudio pyaudio opus

我正在使用 Pyaudio 从麦克风捕获音频,并尝试使用 opus 编解码器对其进行编码/解码。我正在使用 SvartalF ( https://github.com/svartalf/python-opus ) 对 libopus 的绑定(bind)。

这是我的代码:

import pyaudio
from opus import encoder, decoder

def streaming(p):
    chunk = 960
    FORMAT = pyaudio.paInt16
    CHANNELS = 1
    RATE = 48000
    streamin = p.open(format = FORMAT,
            channels = CHANNELS, 
            rate = RATE, 
            input = True,
            input_device_index = 7,
            frames_per_buffer = chunk)
    streamout = p.open(format = FORMAT,
            channels = CHANNELS, 
            rate = 48000, 
            output = True,
            output_device_index = p.get_default_input_device_info()["index"],
            frames_per_buffer = chunk)
    enc = encoder.Encoder(RATE,CHANNELS,'voip')
    dec = decoder.Decoder(RATE,CHANNELS)
    data = []
    for i in xrange(100):
        data.append(streamin.read(chunk*2))
    streamout.write(''.join(data))
    encdata = []
    for x in data:
        encdata.append(enc.encode(x,chunk))
    print "DATA LENGTH :", len(''.join(data))
    print "ENCDATA LENGTH :", len(''.join(encdata))
    decdata = ''
    for x in encdata:
        decdata += dec.decode(x,chunk)
    print "DECDATA LENGTH :", len(decdata)
    streamout.write(decdata)
    streamin.close()
    streamout.close()


p = pyaudio.PyAudio()
streaming(p)
p.terminate()

我必须在 data.append(streamin.read(chunk*2)) 中放置 chunk*2 而不是 chunk >DECDATA LENGTH == DATA LENGTH*2 我不知道为什么。

输出:

DATA LENGTH :    384000  
ENCDATA LENGTH : 12865  
DECDATA LENGTH : 384000

如果没有编码/解码,第一个streamout.write(''.join(data))工作完美。通过编码/解码,streamout.write(decdata) 可以工作,但混有很多爆裂声。

我在这里做错了什么?

最佳答案

这似乎是由 python-opus 的解码方法中的错误引起的。

根据Opus API , opus_decode 返回解码的样本数。 python 绑定(bind)假设它将完全填充它传入的结果缓冲区,因此每组解码样本都会附加一个静音。这种沉默会导致低帧尺寸时出现裂纹,而高帧尺寸时会出现卡顿。虽然文档没有提及任何内容,但返回的数字似乎是每个 channel 的。

换线150 of opus/api/decoder.py以下为我解决了这个问题:

    return array.array('h', pcm[:result*channels]).tostring()

如果您需要使用decode_float方法,则可能需要进行相同的更改。

关于 python : PortAudio + Opus encoding/decoding,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17728706/

相关文章:

python - 关于python中的Buffer接口(interface)

linux - 如何发现物理音频输入 channel 列表?

c++ - 端口音频导致 50% 的测试发出响亮的嗡嗡声

c++ - PortAudio Test应用程序-未解析的外部符号Pa_GetVersionInfo

python - 尽管安装了 Pyaudio 模块但未找到

python - 从列表 PySpark 的列表创建单行数据框

Docker 中的 Python Tkinter .TclError : couldn't connect to display

python - 列表列表,最后一项与python比较

python - paInt32、paInt16、paInt24、paFloat32 等之间的区别?

python - "No Module named ' _portaudio' : Unable to find solution