Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 转换wav->;mp3->;wav产生静态噪声_Python_Python 3.x_Audio_Pyaudio_Pydub - Fatal编程技术网

Python 转换wav->;mp3->;wav产生静态噪声

Python 转换wav->;mp3->;wav产生静态噪声,python,python-3.x,audio,pyaudio,pydub,Python,Python 3.x,Audio,Pyaudio,Pydub,我正在尝试将我的麦克风音频转换成mp3文件,然后将它们保存在磁盘上,以便录制和保存音频曲目 但是要用pyaudio播放它,我需要将它转换成wav格式。 它最初是在wav中录制的,我正在尝试做wav->mp3->wav 我将代码的最小调试版本放在一起,如下所示: import pyaudio from array import array from struct import pack from sys import byteorder from io import BytesIO from py

我正在尝试将我的麦克风音频转换成mp3文件,然后将它们保存在磁盘上,以便录制和保存音频曲目

但是要用
pyaudio
播放它,我需要将它转换成
wav
格式。
它最初是在
wav
中录制的,我正在尝试做
wav->mp3->wav

我将代码的最小调试版本放在一起,如下所示:

import pyaudio
from array import array
from struct import pack
from sys import byteorder
from io import BytesIO
from pydub import AudioSegment

p = pyaudio.PyAudio()
stream_mic = p.open(rate=11000,
                        format=pyaudio.paInt16,
                        channels=1,
                        input=True,
                        frames_per_buffer=500)

stream_out = p.open(rate=11000,
                        format=pyaudio.paInt16,
                        channels=1,
                        output=True,
                        frames_per_buffer=500)

def is_odd(a):
    return bool(a - ((a>>1)<<1))

def wav_obj(raw_data):
    wavHandle = AudioSegment(data=raw_data, sample_width=2, frame_rate=11000, channels=1)
    return wavHandle

def wavToMp3(audioFrame):
    mp3 = BytesIO()
    file_handle = audioFrame.export(mp3, format="mp3")
    mp3.seek(0)
    data = mp3.read()
    ## == Data needs to be multiple of (sample_width * channels)
    ##    Easiest way is to strip of a trailing data, 
    while is_odd(len(data)):
        data = data[:-1]
    return AudioSegment(data=data, sample_width=2, frame_rate=11000, channels=1)

def mp3ToWav(audioFrame):
    #remasteredAudioFrame = audioFrame.set_frame_rate(11000)
    wav = BytesIO()
    file_handle = audioFrame.export(wav, format="wav")
    wav.seek(0)
    return AudioSegment(data=wav.read(), sample_width=2, frame_rate=11000, channels=1)

while 1:
    snd_data = array('h', stream_mic.read(500))
    if byteorder == 'big':
        snd_data.byteswap()

    frame = array('h')
    frame.extend(snd_data)

    wav = wav_obj(frame)

    ## == convert from .wav -> .mp3 -> .wav
    ##    just to see the loss of audio.
    mp3 = wavToMp3(wav)
    wav = mp3ToWav(mp3)

    stream_out.write(wav.raw_data)

stream_out.stop_stream()
stream_mic.stop_stream()
stream_out.close()
stream_mic.close()
p.terminate()
wav = wav_obj(frame)
sound = sound + wav

sound.export("test.mp3",
              format="mp3",
              bitrate="11k",
              tags={"album": "test", "artist": "Not Ariana Grande"})
使播放声音“优美”。没有数据丢失,质量与我定义的一样

看在我的份上,我搞不清楚我在哪里把数据压缩搞混了。
注意:如果可能的话,我希望在内存中执行此操作,因为我稍后将处理数据,以便尝试创建效果等

进展 正如@Anthon指出的,我应该一个接一个地隔离转换,看看哪一个会失败。我通过将
wav->mp3
保存到磁盘来实现这一点。

started = time()
sound = AudioSegment(data=b'', sample_width=2, frame_rate=11000, channels=1)
while 1:
    snd_data = array('h', stream_mic.read(500))
    if byteorder == 'big':
        snd_data.byteswap()

    frame = array('h')
    frame.extend(snd_data)

    wav = wav_obj(frame)

    ## == convert from .wav -> .mp3 -> .wav
    ##    just to see the loss of audio.
    mp3 = wavToMp3(wav)
    sound = sound + mp3
    #wav = mp3ToWav(mp3)

    #stream_out.write(mp3.raw_data)
    if time() - started > 1.5:
        break

print(sound.raw_data)
with open('test.mp3', 'wb') as fh:
    fh.write(sound.raw_data)
然后我大胆地使用
test.mp3
,看看波浪形成的样子。
果然,看起来是
.mp3
转换不可靠

在肉眼看来,音频帧似乎被单独拖出和扭曲。声音总长度约为1.5秒,但从波形来看,压缩机添加的每一帧中都有暂停和延迟:

因此,在使用该值的所有实例中,我将值
frames\u per\u buffer=500
增加到
2000

stream_mic = p.open(frames_per_buffer=5000, ...)
stream_out = p.open(frames_per_buffer=5000, ...)
stream_mic.read(5000)
任何高于我的
1.5秒的值都应该是足够好的值。
果然,波形看起来完全不同:

似乎有效的方法如下:

import pyaudio
from array import array
from struct import pack
from sys import byteorder
from io import BytesIO
from pydub import AudioSegment

p = pyaudio.PyAudio()
stream_mic = p.open(rate=11000,
                        format=pyaudio.paInt16,
                        channels=1,
                        input=True,
                        frames_per_buffer=500)

stream_out = p.open(rate=11000,
                        format=pyaudio.paInt16,
                        channels=1,
                        output=True,
                        frames_per_buffer=500)

def is_odd(a):
    return bool(a - ((a>>1)<<1))

def wav_obj(raw_data):
    wavHandle = AudioSegment(data=raw_data, sample_width=2, frame_rate=11000, channels=1)
    return wavHandle

def wavToMp3(audioFrame):
    mp3 = BytesIO()
    file_handle = audioFrame.export(mp3, format="mp3")
    mp3.seek(0)
    data = mp3.read()
    ## == Data needs to be multiple of (sample_width * channels)
    ##    Easiest way is to strip of a trailing data, 
    while is_odd(len(data)):
        data = data[:-1]
    return AudioSegment(data=data, sample_width=2, frame_rate=11000, channels=1)

def mp3ToWav(audioFrame):
    #remasteredAudioFrame = audioFrame.set_frame_rate(11000)
    wav = BytesIO()
    file_handle = audioFrame.export(wav, format="wav")
    wav.seek(0)
    return AudioSegment(data=wav.read(), sample_width=2, frame_rate=11000, channels=1)

while 1:
    snd_data = array('h', stream_mic.read(500))
    if byteorder == 'big':
        snd_data.byteswap()

    frame = array('h')
    frame.extend(snd_data)

    wav = wav_obj(frame)

    ## == convert from .wav -> .mp3 -> .wav
    ##    just to see the loss of audio.
    mp3 = wavToMp3(wav)
    wav = mp3ToWav(mp3)

    stream_out.write(wav.raw_data)

stream_out.stop_stream()
stream_mic.stop_stream()
stream_out.close()
stream_mic.close()
p.terminate()
wav = wav_obj(frame)
sound = sound + wav

sound.export("test.mp3",
              format="mp3",
              bitrate="11k",
              tags={"album": "test", "artist": "Not Ariana Grande"})
因此,
wav-frame->mp3-frame->组合多个mp3-frame
无法工作。
但是执行
wav帧->组合多个wav帧->导出到mp3
工作

这就是我再次陷入困境的地方。
显然,
mp3
转换是不可靠的,它会在每个片段的波形中增加失真音调。
我希望在座的各位中有人曾经使用过
pydub
,尤其是mp3转换,因为我完全迷路了

以下是收集的mp3:s:


我不知道
.export
使用什么mp3编码器和/或是否可以设置其质量。我会先尝试进行外部转换(例如,
lame
save wav>lame>read mp3),以确定是编码(很可能)而不是解码,然后看看如何提高罪犯的质量。@Anthon Solid tip!我将尝试使用外部编码器/解码器
pyaudio
按顺序使用
libav
ffmpeg
。我试过这两种方法,结果都是一样的。我不认为你可以将MP3转换成块,然后再重新组合——大多数(可能全部?)MP3编码器会在转换后的音频的开头或结尾添加一些静音。如果您想压缩数据以节省带宽,请尝试通过lame管道传输数据,或仅抓住波形数据