pygame播放視訊並實現音視訊同步

2023-11-22 06:00:57

一、前言

在我接觸pygame時最新的pygame已經不支援movie模組,這就導致在pygame播放視訊變成一個問題,網上搜了下解決方案有兩個:

一是使用opencv播放視訊,再結合pygame.mixer來播放音訊

二是使用moviepy播放視訊,再結合pygame.mixer播放音訊

上述兩個方案其實都是先將mp4的視訊分離成「畫面幀」和「mp3音訊」,所謂的播放實際上是不停地在切換「畫面幀」,同時播放音訊,最終實現音視訊的同時播放。

但上述兩個方案都存在「音畫同步」的問題,因為無論是opencv還是moviepy都只負責將視訊切片成幀,播放則是pygame自己在執行一個while迴圈來不停切換介面上展示出來的圖片幀,這也就導致while迴圈很快就將幀播放完畢,而音訊則還按著原有節奏緩慢播放。

解決是在while迴圈中加入合適的延時同時根據當前視訊播放進度來設定音訊的播放起點以實現同步,但這個方案據我實踐在加入延時後就實現了較好的音畫同步效果不知道為啥還要去設定音訊的播放起點,另外在設定音訊播放起點時一直提示錯誤也不知道為何,所以我這裡提供兩個方案:

方案一:在while迴圈中加入延時,短視訊測試效果還行

方案二:根據音訊的播放節奏來決定視訊幀的播放節奏,這樣音畫肯定是同步的

我選擇使用moviepy來做,因為moviepymp4中分離mp3比較簡單。

 

二、方案一

在專案的目錄下新建videos目錄,並放入一個測試使用的mp4檔案test.mp4

上述程式碼實際上是將整個遊戲的影格率設定成與視訊一致,這樣可能存在一些隱患(直覺)。

 

三、方案二

程式碼如下:

上述程式碼的邏輯如下:

1、通過pygame.mixer.music.get_pos()」獲取當前音訊的播放進度

2、通過音訊播放進度除以視訊的總時長,得到音訊播放的百分比進度(音畫同步的話,音訊百分比進度就應該跟視訊百分比進度一致)

3、百分比進度乘以視訊總幀數可得到當前應當播放哪一個視訊幀

4、再判斷一下當前實際播放的幀是否已超過了理論應該播放的視訊幀(是的話就跳過當前幀的播放)

注意音訊播放結束或視訊幀播放結束都要結束視訊的播放。

 

四、總結

本篇提供了pygame播放視訊的兩個方案,第一個方案是網上找的現成的,第二個方案則是參考了opencv(主流方案)自己逆向思維做的,還未經過實際驗證。