moviepy音視頻剪輯:使用fl_time進行諸如快播、慢播、倒序播放等時間特效處理的原理和可能遇到的坑

一、引言

在《moviepy音視頻剪輯:moviepy中的剪輯基類Clip的屬性和方法詳解》介紹了fl_time方法返回一個新剪輯,新剪輯是調用剪輯的一個淺拷貝,但新剪輯的時間線被調整,實際上這個方法就是對剪輯進行一個基於時間特效的處理,如快播、慢播、倒序播放等。

二、時間特效處理的基本原理

時間特效處理其實非常簡單,就是對時間的一個變換,變換時,假設t1是剪輯的時間線,從0開始一直到剪輯的最後end地方的一個線性座標,而時間特效是通過調用函數或方法得到t2,t2 = t_fun(t1),然後特效處理後的剪輯時間線t1對應的幀被替換爲原剪輯t2位置的幀。

n倍速變換,其實是新剪輯t1時刻的幀對應原剪輯n*t1時刻的幀,慢速播放則是新剪輯t1時刻的幀對應原剪輯t1/n時刻的幀,倒序播放則是將新剪輯t1時刻的幀對應原剪輯end-t1時刻的幀。

在moviepy中,時間特效處理是通過方法fl_time來進行變換處理的,變換的函數則通過fl_time的參數t_func來傳遞。關於fl_time的詳細介紹請參考《moviepy音視頻剪輯:moviepy中的剪輯基類Clip的屬性和方法詳解》。

t_func參數指定的函數要求一個入口參數t,返回一個經過函數處理後的新的時間值。

三、時間變換的坑

時間變換講清楚以後,看起來很簡單,但具體實現時會存在稍不留神就會被坑,我們來看幾個筆者遭遇的坑。

3.1、OSError: MoviePy error: failed to read the first frame of video file

在進行變換處理時報如下錯誤信息:

OSError: MoviePy error: failed to read the first frame of video file F:\video\WinBasedWorkHard_src.mp4. That might mean that the file is corrupted. That may also mean that you are using a deprecated version of FFMPEG. On Ubuntu/Debian for instance the version in the repos is deprecated. Please update to a recent version from the website.

之所以出現這個報錯,估計是因爲使用fl_time對時間變換時,從原剪輯的0-end時間段讀取幀時,原剪輯end這個時間位置已經到視頻結尾,可能沒有有效的幀,導致讀取視頻時報錯。解決方案就是將end位置稍微往後退一點,退一個幀就夠了。

3.2、ValueError: Attribute ‘duration’ not set情況1

這是因爲調用fl_time時,keep_duration默認值爲False,只要該值爲False,moviepy就會將duration設置爲None,解決辦法是設置keep_duration = True 或者手工設置剪輯的duration。

3.3、ValueError: Attribute ‘duration’ not set情況2

下面的案例是倍速播放,由於是倍速播放,視頻的時長時間上只有原視頻的一半,此時使用keep_duration=True已經不合適,只能自行設定duration的值。示例代碼如下:

from  moviepy.editor import *
clipVideo = VideoFileClip(r"F:\video\WinBasedWorkHard_src.mp4")
newclip = clipVideo.fl_time(lambda t:  2*t , apply_to=['mask'])
newclip.set_duration(clipVideo.duration/2)
newclip.write_videofile(r"F:\video\WinBasedWorkHard_new.mp4")

執行時還是報錯,這是因爲剪輯的絕大多數set方法,基本上都不是對調用者的直接修改,而是對調用者進行淺拷貝後,對淺拷貝剪輯進行修改,且這些方法返回值都是一個剪輯。只需要將調用返回的剪輯記錄下來作爲後續處理才行。

3.4、OSError: Error in file xxxx, Accessing time

上面的案例沒有調整音頻只調整了視頻,會導致視頻播完之後,音頻還只播放一半,要保持音頻完整播放,有3個辦法,一是不同步改變音頻,但視頻duration保持不變,這時出來的效果就是視頻播放到一半後,後續畫面不再變化,第二種是將音頻同步變換duration減半,只是音頻播放速度也翻倍了;第三種是保持duration不變但同樣變換音頻。前面兩種方式處理都沒有問題,但第三種方式會遇到問題。此時執行時會報如下錯誤:

OSError: Error in file F:\video\WinBasedWorkHard_src.mp4, Accessing time t=54.84-54.93 seconds, with clip duration=54 seconds, 

這個報錯信息應該是訪問的音頻超出了剪輯的時長導致,但如果不變換音頻不會報錯,且自動置爲最後一個視頻幀,而音頻沒有這樣處理,且不停重複最後的音頻感知不好。這種問題最好的解決是按前兩種方式處理。

廣告

老猿關於PyQt的付費專欄《使用PyQt開發圖形界面Python應用》只需要9.9元,本專欄《PyQt+moviepy音視頻剪輯實戰》文檔的同樣內容在付費專欄上也有相應內容,總體來說付費專欄介紹更詳細或案例更多。本節內容對應付費專欄的《moviepy音視頻剪輯:使用fl_time進行諸如快播、慢播、倒序播放等時間特效處理的原理、代碼實現以及需要注意的坑》。如果有興趣也願意支持老猿的讀者,歡迎購買付費專欄。

跟老猿學Python、學5G!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章