问题
I am new learner of audio editing libs - Pydub. I want to change some audio files' playback speed using Pydub(say .wav/mp3 format files), but I don't know how to make it. The only module I saw that could possibly deal with this problem is speedup module in effect.py. However, there is no explanation about how I am supposed to call it.
Could anyone kindly explain how to do this task in Pydub? Many thanks!
(A related question: Pydub - How to change frame rate without changing playback speed, but what I want to do is to change the playback speed without changing the audio quality.)
回答1:
sound.set_frame_rate() does a conversion, it should not cause any "chipmunk effect", but what you can do is change the frame rate (without a conversion) and then convert the audio from there back to a normal frame rate (like 44.1 kHz, "CD quality")
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)
回答2:
This can be done using pyrubberband package which requires rubberband library that can stretch audio while keeping the pitch and high quality. I was able to install the library on MacOS using brew, and same on Ubuntu with apt install. For extreme stretching, look into PaulStretch
brew install rubberband
This works simply with librosa package
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')
To make pyrubberband work directly with AudioSegment from pydub without librosa I fiddled this function:
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
来源:https://stackoverflow.com/questions/51434897/how-to-change-audio-playback-speed-using-pydub