使用 Python 只读取大型 wav 文件的一部分

Dav*_*ito 2 audio python-3.x

我有很大的 wav 文件(每个大约 4GB)。由于我的部署服务器有一个限制,每个进程不能使用超过 500 MB 的 RAM,因此我希望能够仅加载和处理音频文件的块,然后稍后读取并附加它们,例如一个文本文件。

我查看了pydub,但它似乎会在我可以切掉较小的块进行处理之前加载整个文件(如果我错了,请纠正我)。scipy.io.wavfile.read的情况也是如此。我希望能够读取大文件的块,处理它们,然后将它们放回去(理想情况下附加到硬盘驱动器上先前处理的块)。

我能找到的大多数可用的答案已经假设我可以将大文件加载到主内存中。

如何将一个 .wav 文件拆分为多个 .wav 文件?

在Python中读取*.wav文件

Lou*_*dox 5

您可能需要研究一些用于处理音频的包:通常soundfile用于 I/O,如下所示librosa。“采样率”又名“帧率”是每秒音频样本的数量,通常以 kHz 为单位,但在软件中仅以 Hz 为单位。

还有一个专门的声音设计 StackExchange,您可能会发现搜索它会更有效。

获取文件的一部分称为“查找”,该类soundfile.SoundFile支持它。

这个想法是您将“光标”的位置移动到特定的帧 ,SoundFile.seek(pos)然后在某些帧中读取 ,SoundFile.read(n_frames)之后光标的位置将移动许多帧,您可以使用 获得这些帧SoundFile.tell()

下面是访问 wav 文件的一部分的示例:

import soundfile as sf

def read_audio_section(filename, start_time, stop_time):
    track = sf.SoundFile(filename)

    can_seek = track.seekable() # True
    if not can_seek:
        raise ValueError("Not compatible with seeking")

    sr = track.samplerate
    start_frame = sr * start_time
    frames_to_read = sr * (stop_time - start_time)
    track.seek(start_frame)
    audio_section = track.read(frames_to_read)
    return audio_section, sr
Run Code Online (Sandbox Code Playgroud)

...并将其写入您刚刚使用的文件soundfile.write(注意:包中的函数,而不是soundfile.SoundFile类的方法)

def extract_as_clip(input_filename, output_filename, start_time, stop_time):
    audio_extract, sr = read_audio_section(input_filename, start_time, stop_time)
    sf.write(output_filename, audio_extract, sr)
    return
Run Code Online (Sandbox Code Playgroud)