如何使用 Pydub 更改音频播放速度?

its*_*sMe 3 python audio mp3 wav pydub

我是音频编辑库 - Pydub 的新学习者。我想使用 Pydub(比如 .wav/mp3 格式文件)更改一些音频文件的播放速度,但我不知道如何制作。我看到的唯一可能解决这个问题的模块是 effect.py 中的加速模块。但是,没有解释我应该如何称呼它。

谁能解释一下如何在 Pydub 中完成这项任务?非常感谢!

(一个相关的问题:Pydub - 如何在不改变播放速度的情况下改变帧速率,但我想要做的是在不改变音频质量的情况下改变播放速度。)

小智 6

from pydub import AudioSegment
from pydub import effects

root = r'audio.wav'
velocidad_X = 1.5 # No puede estar por debajo de 1.0

sound = AudioSegment.from_file(root)
so = sound.speedup(velocidad_X, 150, 25)
so.export(root[:-4] + '_Out.mp3', format = 'mp3')
Run Code Online (Sandbox Code Playgroud)

  • 这实际上似乎有效,但质量太差了 (2认同)

abh*_*nan 5

sound.set_frame_rate() 进行转换,它不应该引起任何“花栗鼠效应”,但是您可以做的是更改帧速率(不进行转换),然后将音频从那里转换回正常的帧速率(如 44.1 kHz,“CD 质量”)

from pydub import AudioSegment
sound = AudioSegment.from_file(…)

def speed_change(sound, speed=1.0):
    # Manually override the frame_rate. This tells the computer how many
    # samples to play per second
    sound_with_altered_frame_rate = sound._spawn(sound.raw_data, overrides={
         "frame_rate": int(sound.frame_rate * speed)
      })
     # convert the sound with altered frame rate to a standard frame rate
     # so that regular playback programs will work right. They often only
     # know how to play audio at standard frame rate (like 44.1k)
    return sound_with_altered_frame_rate.set_frame_rate(sound.frame_rate)


slow_sound = speed_change(sound, 0.75)
fast_sound = speed_change(sound, 2.0)
Run Code Online (Sandbox Code Playgroud)


小智 5

这可以使用pyrubberband包来完成,它需要rubberband库来拉伸音频,同时保持音调和高质量。我可以使用brew在MacOS上安装该库,也可以使用apt install在Ubuntu上安装该库。对于极限拉伸,请查看 PaulStretch

brew install rubberband
Run Code Online (Sandbox Code Playgroud)

这仅适用于 librosa 包

import librosa
import pyrubberband
import soundfile as sf

y, sr = librosa.load(filepath, sr=None)
y_stretched = pyrubberband.time_stretch(y, sr, 1.5)
sf.write(analyzed_filepath, y_stretched, sr, format='wav')
Run Code Online (Sandbox Code Playgroud)

为了使 Pyrubberband 直接与 pydub 中的 AudioSegment 一起工作而不需要 librosa,我摆弄了这个函数:

def change_audioseg_tempo(audiosegment, tempo, new_tempo):
    y = np.array(audiosegment.get_array_of_samples())
    if audiosegment.channels == 2:
        y = y.reshape((-1, 2))

    sample_rate = audiosegment.frame_rate

    tempo_ratio = new_tempo / tempo
    print(tempo_ratio)
    y_fast = pyrb.time_stretch(y, sample_rate, tempo_ratio)

    channels = 2 if (y_fast.ndim == 2 and y_fast.shape[1] == 2) else 1
    y = np.int16(y_fast * 2 ** 15)

    new_seg = pydub.AudioSegment(y.tobytes(), frame_rate=sample_rate, sample_width=2, channels=channels)

    return new_seg
Run Code Online (Sandbox Code Playgroud)