当我用opuslib解码Python中编码的opus数据时,会有一些噪声

2024-06-02 08:54:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我在python中用opuslib对音频文件进行了编码,解码时有一些噪声,质量比主文件低。 我使用了这个库:https://github.com/jlaine/opuslib

我不知道为什么会这样。甚至我尝试过其他帧大小,其他速率,和其他比特率,但我无法修复它。到底是什么问题??在

FFMPEG_BIN = "ffmpeg"  # on Linux
import subprocess as sp

import pyaudio

import opuslib
import opuslib.api.ctl
from opuslib.api import decoder as opus_decoder
from opuslib.api import encoder as opus_encoder


class OpusCodec():

    def __init__(self, *args, **kwargs):
        self.frame_size = 2880  # 960
        self.channels = 2
        self.rate = 48000  
        self.bitrate = 64000
        print(opus_encoder.get_size(1))
        self.decoder = opus_decoder.create_state(self.rate, self.channels)
        self.encoder = opus_encoder.create_state(self.rate, self.channels, opuslib.APPLICATION_AUDIO)
        err = opus_encoder.encoder_ctl(self.encoder, opuslib.api.ctl.set_bitrate, self.bitrate)
        # print(err)
        opus_encoder.encoder_ctl(self.encoder, opuslib.api.ctl.set_signal, opuslib.SIGNAL_MUSIC)
        # opus_encoder.encoder_ctl(self.encoder,opuslib.api.ctl.set_complexity, 10)

    def encode(self, data, **kwargs):
        if not 'frame_size' in kwargs:
            kwargs['frame_size'] = self.frame_size
        out = opus_encoder.encode(self.encoder, data, self.frame_size, len(data))
        return out

    def decode(self, data, **kwargs):
        if not 'frame_size' in kwargs:
            kwargs['frame_size'] = self.frame_size
        out = opus_decoder.decode(self.decoder, data, len(data), self.frame_size, 0, self.channels)
        return out[0:int(len(out) / 2)]

def main():
    op = OpusCodec()

    command = [FFMPEG_BIN,
               '-i', "shallow-main.mp3",
               '-f', 's16le',
               '-acodec', 'pcm_s16le',
               '-ar', str(op.rate),  # ouput will have 44100 Hz
               '-ac', str(op.channels),  # stereo (set to '1' for mono)
               '-']

    pipe = sp.Popen(command, stdout=sp.PIPE, bufsize=10 ** 8)

    data = []
    while True:
        da = pipe.stdout.read(op.frame_size * op.channels)
        if not da:
            break
        data.append(da)
    # print(data[0])
    # playing(op, data)
    # str
    # eamout.write(da)

    encdata = []
    for x in data:
        encdata.append(op.encode(x))
    # print(encdata[0])

    print("DATA LENGTH :", len(b''.join(data)))
    print("ENCDATA LENGTH :", len(b''.join(encdata)))
    decdata = []
    for x in encdata:
        decdata.append(op.decode(x))
    print("DECDATA LENGTH :", len(b''.join(decdata)))
    # print(decdata[0])

    playing(op, decdata)

def playing(op, data):
    frame_size = op.frame_size
    FORMAT = pyaudio.paInt16
    CHANNELS = op.channels
    RATE = op.rate
    p = pyaudio.PyAudio()
    streamout = p.open(format=FORMAT,
                       channels=CHANNELS,
                       rate=RATE,
                       output=True,
                       output_device_index=p.get_default_input_device_info()["index"],
                       frames_per_buffer=frame_size)

    for da in data:
        streamout.write(da)

    # streamin.close()
    streamout.close()


main()

你可以听到下面两个音频文件,你完全明白我的目的。 主音频文件:https://www.dropbox.com/s/l2znt9ql0sxpa7n/shallow-main.mp3?dl=0 解码的音频文件:https://www.dropbox.com/s/sb6wwqjpsvkepwf/shallow-decode.opus?dl=0


Tags: importselfapiencoderdatasizeframekwargs