如何将numpy数组转换为mp3文件

lnlaulya  于 2022-12-26  发布在  其他
关注(0)|答案(2)|浏览(345)

我正在使用声卡库来记录我的麦克风输入,它记录在一个numpy数组中,我想抓住那个音频并将其保存为mp3文件。
代码:

import soundcard as sc
import numpy 
import threading

speakers = sc.all_speakers() # Gets a list of the systems speakers
default_speaker = sc.default_speaker() # Gets the default speaker
mics = sc.all_microphones() # Gets a list of all the microphones

default_mic = sc.get_microphone('Headset Microphone (Arctis 7 Chat)') # Gets the default microphone

# Records the default microphone
def record_mic():
  print('Recording...')
  with default_mic.recorder(samplerate=48000) as mic, default_speaker.player(samplerate=48000) as sp:
      for _ in range(1000000000000):
          data = mic.record(numframes=None) # 'None' creates zero latency
          sp.play(data) 
          
          # Save the mp3 file here 

recordThread = threading.Thread(target=record_mic)
recordThread.start()
sd2nnvve

sd2nnvve1#

带Scipy(到wav文件)

您可以轻松地转换为wav,然后单独将wav转换为mp3。更多详情here

from scipy.io.wavfile import write

samplerate = 44100; fs = 100
t = np.linspace(0., 1., samplerate)

amplitude = np.iinfo(np.int16).max
data = amplitude * np.sin(2. * np.pi * fs * t)

write("example.wav", samplerate, data.astype(np.int16))

带pydub(到mp3)

从这个优秀的thread尝试这个函数-

import pydub 
import numpy as np

def write(f, sr, x, normalized=False):
    """numpy array to MP3"""
    channels = 2 if (x.ndim == 2 and x.shape[1] == 2) else 1
    if normalized:  # normalized array - each item should be a float in [-1, 1)
        y = np.int16(x * 2 ** 15)
    else:
        y = np.int16(x)
    song = pydub.AudioSegment(y.tobytes(), frame_rate=sr, sample_width=2, channels=channels)
    song.export(f, format="mp3", bitrate="320k")

#[[-225  707]
# [-234  782]
# [-205  755]
# ..., 
# [ 303   89]
# [ 337   69]
# [ 274   89]]

write('out2.mp3', sr, x)

注:输出MP3必然是16位的,因为MP3总是16位的。但是,您可以按照@Arty的建议将sample_width=3设置为24位输入。

wfauudbj

wfauudbj2#

截至目前,公认的答案产生极其扭曲的声音,至少在我的情况下,所以这里是改进的版本:

#librosa read 
y,sr=librosa.load(dir+file,sr=None)
y=librosa.util.normalize(y)

#pydub read
sound=AudioSegment.from_file(dir+file)
channel_sounds = sound.split_to_mono()
samples = [s.get_array_of_samples() for s in channel_sounds]
fp_arr = np.array(samples).T.astype(np.float32)
fp_arr /= np.iinfo(samples[0].typecode).max

fp_arr=np.array([x[0] for x in fp_arr])
#i normalize the pydub waveform with librosa for comparison purposes
fp_arr=librosa.util.normalize(fp_arr)

所以你从任何库中读取音频文件,你有一个波形,然后你可以用下面的代码将其导出到任何pydub支持的编解码器,我还使用了librosa读取波形,它工作得很完美。

wav_io = io.BytesIO()
scipy.io.wavfile.write(wav_io, sample_rate, waveform)
wav_io.seek(0)
sound = AudioSegment.from_wav(wav_io)

with open("file_exported_by_pydub.mp3",'wb') as af:
    sound.export(
        af,
        format='mp3',
        codec='mp3',
        bitrate='160000',
)

相关问题