微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从 numpy.ndarray 加载时,pydub.AudioSegment 会弄乱音频数据

如何解决从 numpy.ndarray 加载时,pydub.AudioSegment 会弄乱音频数据

我必须以编程方式混合音频文件(向录音添加背景噪音),而且我的所有文件都是 .opus 格式的 8-9 小时录音。

我曾尝试使用 pydub.AudioSegment 在内存中加载一个,但出现以下错误

path_to_input = '/path/to/my/input/file.opus'
sound_data = AudioSegment.from_file(path_to_input)
Traceback (most recent call last):
  File "<input>",line 1,in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pydub/audio_segment.py",line 728,in from_file
    fix_wav_headers(p_out)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pydub/audio_segment.py",line 142,in fix_wav_headers
    raise CouldntDecodeError("Unable to process >4GB files")
pydub.exceptions.CouldntDecodeError: Unable to process >4GB files

显然我不能使用 pydub.AudioSegment 来加载我的文件,因为它们太大了(我试图打开的文件实际上在磁盘上有 48MB,所以我猜它们太大了,无法加载到内存中 {{1 }}?)。无论如何,我已经设法使用 pydub 加载文件

librosa

我认为我可以通过从 sample_rate = 8000 sound_data_librosa = librosa.load(path_to_input,sr=sample_rate,res_type='kaiser_best') sound_data_librosa = sound_data_librosa[0] (它是一个 pydub.audio_segment.AudioSegment)创建一个 sound_data_librosa 对象来解决这个问题。

numpy.ndarray

这似乎工作正常,但是当我将它写回磁盘时,它听起来像是随机噪音。

sound_data = AudioSegment(
    sound_data_librosa.tobytes(),frame_rate=sample_rate,sample_width=sound_data_librosa.dtype.itemsize,channels=1
    )

所以我还没有修改任何东西,但不知何故我丢失了所有的音频数据。我无法理解到底是什么问题。有什么我做错的地方可以修复,这样我就不会扭曲音频数据吗?

另外,我不一定要这样做,只是我一直在使用 path_to_output = '/path/to/my/output/file.opus' sound_data.export(path_to_output,format="opus") 修改我的音频文件(应用增益、叠加、作为 .opus 文件写入磁盘)为什么我需要将它们作为 pydub.AudioSegment 对象加载。如果有另一种方法可以在 python 中做同样的事情,如果你能指出它,我将不胜感激。我主要担心的是缺乏对 .opus 文件(读取和写入)的支持,这就是我尝试坚持使用 pydub.audio_segment.AudioSegment 的原因。

解决方法

是的,在 MacOS 上使用 opusffmpeg 有一些奇怪之处。我试图修复文件大小问题一段时间,但没有任何进展。 相反,我建议将文件转换为 wav (或任何其他好的(:格式)并尝试使用它。 我尝试将 42MB 的 opus 文件转换为 WAV,结果大约为 2.7GB,但不知何故 pydub 能够读取它。 你可以使用这样的东西来转换文件

import subprocess

def convert_to_wav(name):
     command = ['ffmpeg','-i',f'{name}.opus',f'{name}.wav']
     subprocess.run(command,stdout=subprocess.PIPE,stdin=subprocess.PIPE)

或者在 GitHub 上 ping pydub 的所有者

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。