今天在用moviepy合成一段视频和语音,想要视频和语音同步,即视频结束语音也结束,语音结束视频也结束,很简单的一个短板优先的办法,代码如下:
my_clip = mpe.VideoFileClip('./temp/test.avi')
audio_background = mpe.AudioFileClip('./temp/test.wav')
videoLength = my_clip.duration
audioLength = audio_background.duration
print "视频时长:" + str(videoLength)
print "声音时长:" + str(audioLength)
#以较短的为主
if (videoLength > audioLength):
my_clip = my_clip.subclip(0, audioLength)
elif (audioLength > videoLength):
audio_background = audio_background.subclip(0, videoLength)
#
# print my_clip.duration
# print audio_background.duration
new = my_clip.set_audio(audio_background)
print "最终视频时长:" + str(new.duration)
new.write_videofile('./temp/result.mp4', audio_codec="aac")
我的音频是2.2s,视频是3s的,并且代码输出的最终视频时长也为2.2s,但是写入result.mp4后,视频却是3s的!
分析:很奇怪的问题,于是去看write_videofile函数的代码,发现它有个参数,是fps,如果不填则默认使用原视频的fps,而我的原视频的fps为1,即一秒播放一帧,一共播放三秒;所以在经过‘短板优先’的那个条件剪切音视频时,虽然视频被剪切为2.2s长,但是我的视频只有3帧,软件不可能剪出0.2帧出来,于是取天花板,为3,所以输出的视频又是三秒了;
**结论:**截取视频时,实际上截取的是帧,比如视频时长为3s,截取2.2s,则实际截取的是:ceil(视频的fps * 2.2);
**解释:**按照上面结论,我的视频是3s,每秒一帧,截取2.2秒,最终时长为:ceil(1*2.2) / 1= 3s,于是我把视频进行了处理,一秒60帧,结果很完美,播放时长在2.2秒(公式:ceil(60 * 2.2) / 60= 2.2)