上一篇文章的下載YouTube影片程式裡面的「檢測影片是否有聲音」與「合併視訊和聲音」,以及《超圖解Python程式設計入門》第5章的批次轉換多媒體檔案格式和MP3聲音檔的功能,全都仰賴FFmpeg工具程式完成。本文將補充說明上一篇文章使用到的ffmpeg命令和操作。
使用ffprobe檢測影片是否有聲音
書本提到FFmpeg工具程式組合當中,有個ffprobe程式能夠讀取視訊和聲音的串流資訊。假設有個名叫“影片.mp4”的視訊檔,底下的命令將顯示這個影片檔的資訊:
中文檔名顯示亂碼是因為Windows命令行視窗的文字編碼不是UTF-8,請參閱第10章末尾的「查看git紀錄並解決中文亂碼」單元說明。若執行ffprobe或ffmpeg命令時出現“Invalid argument”(無效的參數)錯誤訊息,請把媒體檔案重新命名成英文,例如,把“影片.mp4”改成“video.mp4”再重新執行命令。
這個影片的檢測結果顯示它有視訊(Video)和聲音(Audio)兩個串流內容,後面跟著它們的編碼格式;若影片檔不包含音訊,檢測的結果就不會有“Audio”串流。檢測訊息之中的0:0和0:1代表串流的索引編號,在合併視訊和聲音檔案時將會用到它們。
如果影片檔包含多國語音,例如:英語和國語配音,第一個音軌的串流編號將是0:1、第2個音軌的編號是0:2。
假如影片檔沒有聲音,檢測內容將只顯示一個串流,類型是Video:
倘若影片檔沒有視訊,也將只顯示一個串流,類型是Audio,編號同樣是0:0:
因此,在Python程式中執行上面的ffprobe命令並接收分析結果,再透過find()指令找尋“Audio”字串,如果有找到,代表影片包含音軌,否則就是沒有聲音。
提取並轉換影片檔裡的串流視訊或聲音
FFmpeg官網的「進階選項參數」說明文件指出,”map”參數(直譯為「映射」,在此相當於「選取」),能讓我們選取影片檔裡的串流,假設“影片.mp4”包含視訊和聲音,底下的命令將提取影片的聲音串流,用預設的編碼程式(參閱下文)轉成MP3檔:
但是,假如這個MP4檔案只有一個串流媒體,無論是視訊或聲音,執行上面的命令將導致“Stream map ‘0:1’ matches no streams.”(沒有符合“0:1”索引的串流)錯誤。
因此,map參數提供“a”(代表“audio”)和“v”(代表“video”)參數,來表示「聲音」和「視訊」串流。例如,只要這個MP4檔案裡面包含音軌,就可以用底下的map參數提取出來:
執行上面的命令時,省略“-map 0:1”或“-map 0:a”參數,ffmpeg會依照輸出檔案格式(此例為MP3),自動選擇輸出串流。所以,底下的命令將能自動把“影片.mp4”裡的音軌轉換、輸出成“音軌.mp3”聲音檔。
ffmpeg -i 影片.mp4 音軌.mp3
同樣地,底下兩道命令都代表取出“影片,mp4”裡的視訊內容,用預設編碼另存成“視訊.mp4”:
ffmpeg -i 影片.mp4 -map 0:0 視訊.mp4 ffmpeg -i 影片.mp4 -map 0:v 視訊.mp4
附帶一提,執行上述命令時,若同名的檔案已經存在,ffmpeg將詢問是否要覆寫檔案?按下Y鍵確認或者N鍵取消。
我們也能在命令中加入“-y”參數,代表「無條件覆寫舊檔」,就不會出現上面的訊息了:
ffmpeg -i 影片.mp4 -y 音軌.mp3
指定codec以及不轉碼直接輸出
把影片的音軌輸出成MP3檔的過程中,ffmpeg將自動採用“libmp3lame”壓縮編碼程式,將聲音壓縮成MP3格式。我們也可以透過”-c”參數(代表“codec”,壓縮編碼程式)自行指定codec,例如:
假若要維持原始檔的格式,不轉碼直接輸出,請將「壓縮編碼程式」參數改成“copy”(代表「複製」):
ffmpeg -i 影片.mp4 -c copy -y 音軌.mp3
合併視訊和聲音的ffmpeg命令
不轉碼、直接合併視訊和聲音檔的ffmpeg命令格式如下(為了方便說明,所以寫成數行,實際請寫成一行):
為了避免中文導致亂碼干擾命令運作,請把媒體檔案先改成英文,執行結果如下: