如何在不改变音调的情况下改变音频速度?

4

我需要在特定时间内将音频应用于视频,并具有一定的持续时间,但某些音频的持续时间比所需的要长(或短)。如何在不改变音调的情况下更改音频速度?我尝试通过改变帧速率(通过将所需持续时间除以音频持续时间的乘法或除法)来解决问题,但效果并不理想。

original = VideoFileClip("orig.mp4")
clips = [orig.audio.volumex(0.3)]
subs = [] #some array
i = 0
for sub in subs:
    clip = AudioFileClip("\\temp{}.mp3")
    mult = clip.duration / (sub.end - sub.start)  + 0.00001
    clip = AudioArrayClip(clip.to_soundarray(buffersize=500, fps=24000/mult), fps=24000).set_start(sub.start).set_end(sub.end)
    clips.append(clip)
    i += 1

final = CompositeAudioClip(clips)
final.write_audiofile("final.mp3")

您需要改变音频的音调,以便在不同速度播放时听起来正常。这可以通过以相应更高或更低的速率重新采样音频来完成。简单的例子:要以双倍速播放,需要将音调减半。 - martineau
2
你需要使用相位变频器算法来对音频进行时间拉伸,这可能很困难。这种算法的开发在数学上非常复杂。 - ederwander
2个回答

1

你可以使用librosa模块:

from scipy.io import wavfile
import librosa, numpy as np

song, fs = librosa.load("song.wav")

song_2_times_faster = librosa.effects.time_stretch(song, 2)

scipy.io.wavfile.write("song_2_times_faster.wav", fs, song_2_times_faster) # save the song

请问您能否编辑您的回答,将所有相关信息放在其中并删除链接? - phoenixstudio
我刚刚尝试在一个mp4文件上执行此操作,生成的mp4文件没有图像,只有音频。 - PhoenixFireFlite
song_2_times_faster = librosa.effects.time_stretch(song, 0.04) TypeError: time_stretch()函数只接受一个位置参数,但给出了两个。 - Ronalds Mazītis
@Ronalds Mazītis 看起来模块已经更新了,librosa.effects.time_stretch(song, rate=2) 这个函数能用吗? - dzbanecznix
问题是文件是立体声的,而它们需要是单声道的。 - Ronalds Mazītis

-1

使用 wave 库:更改采样率

import wave

CHANNELS = 1
swidth = 2
Change_RATE = 2

spf = wave.open('VOZ.wav', 'rb')
RATE=spf.getframerate()
signal = spf.readframes(-1)

wf = wave.open('changed.wav', 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(swidth)
wf.setframerate(RATE*Change_RATE)
wf.writeframes(signal)
wf.close()

3
只是改变采样率不是解决办法,这会同时改变速度和音高... - ederwander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接