# [FFmpeg] MPEG-4 與 QuickTime 檔案格式 ## 簡介 MP4或稱MPEG-4第14部分(英語:MPEG-4 Part 14)是一種標準的數位多媒體容器格式。 MPEG-4第14部分的擴充名為 .mp4 ,以儲存數位音訊及數位影片為主,但也可以儲存字幕和靜止圖像。 ## 支援性 以下為 檔案/容器 (File / Container) 格式 與 合成器 (Muxers) 所使用輸出副檔名與其所能支援封裝的視訊 (Video)、音訊 (Audio)、字幕 (Subtitle) 格式。 **MPEG-4 檔案格式合成器** - mp4, ismv 副檔名: .mp4 視訊格式: hevc, h.264, mpeg4 音訊格式: aac, mp3, ac3, dts 字幕格式: mov_text, dvd_subtitle - ipod 副檔名: .m4v, .m4a (只有音訊) 視訊格式: h.264, mpeg4 音訊格式: alac, aac, mp3, ac3, dts 字幕格式: mov_text, dvd_subtitle **QuickTime 檔案格式合成器** - mov 副檔名: .mov, .qt 視訊格式: hevc, h.264, mpeg4 音訊格式: alac, aac, mp3, ac3, dts 字幕格式: mov_text, dvd_subtitle 大部分播放設備不支援 mov_text 格式字幕,可以將視訊重新編碼來把字幕烙印到畫面上,即 Hardsub。 ## 應用範例 ### 重新編碼 輸出視訊、音訊、字幕格式必須被 合成器 (Muxer) 所支援才可以。 hevc + aac 封裝為 mp4 (ismv muxer): ```powershell ffmpeg -i input.mkv -c:v libx265 -c:a aac -f ismv output.mp4 ``` hevc + alac 封裝為 mov (mov muxer): ```powershell ffmpeg -i input.mkv -c:v libx265 -c:a alac -f mov output.mov ``` h.264 + aac 封裝為 m4v (ipod muxer): ```powershell ffmpeg -i input.mkv -c:v libx264 -c:a alac -f ipod output.m4v ``` aac 封裝為 m4a (ipod muxer): ```powershell ffmpeg -i input.flac -c:a aac -f ipod output.m4a ``` 通常不需要手定指定 muxer,所以 `-f` 是可以省略的,ffmpeg 將會自動依照輸出檔案的副檔名來呼叫 muxer。例如使用 `.m4a` 副檔名,ffmpeg 將會自動呼叫 `ipod` muxer 來封裝輸出。 承上,省略 `-f` 選項: ```powershell ffmpeg -i input.flac -c:a aac output.m4a ``` ### 複製串流 如果輸入視訊或音訊或字幕格式是已被輸出檔案格式所支援,則你可以 `-c copy` / `-codec copy` 來直接複製輸入串流至輸出檔案。 假設 input.m2ts 內是 h.264 視訊 + TrueHD 音訊,若要複製視訊串流: ```powershell ffmpeg -i input.m2ts -c:v copy -c:a aac output.mp4 ``` 假設 input.mov 內是 h.264 視訊 + AAC 音訊,若要複製視訊與音訊串流: ```powershell ffmpeg -i input.mov -c copy output.mp4 ``` ### 修改畫面顯示寬高比 你可以使用 `-aspect` 指定顯示寬高比,控制輸出影片被播放時畫面寬高比。這不會改變影片本身的解析度。例如將一個解析度 1440x1080 的影片的顯示寬高比指定為為 16:9,此 "1440x1080, DAR 16:9" 的影片被在 PC 上播放時,其顯示解析度應該為 1920x1080。 **指定輸出 MP4 檔顯示寬高比** 輸出顯示寬高比 16:9: ```powershell ffmpeg -i input.mp4 -c copy -aspect 16/9 output.mp4 ``` **設定輸出視訊串流顯示寬高比** 如果以上方法對於你的播放器不管用的話,可以嘗試將比例訊息寫入視訊串流。由於 H.264 與 H.265 位元流只接受 Sample Aspect Ratio (取樣寬高比) 亦即像素寬高比 (Pixel Aspect Ratio),則必須先使用下列算式做換算得到 SAR。 $$ SampleAspectRatio = DisplayAspectRatio / (Width / Height) $$ 對於輸出解析度 1440x1080 且顯示寬高比為 16:9 的影片,則 SAR 值... $$ SampleAspectRatio = 16 / 9 / (1440 / 1080) = 4 / 3 $$ H.264 / AVC 視訊: ```powershell ffmpeg -i input.mp4 -c copy -bsf:v "h264_metadata=sample_aspect_ratio=4/3" output.mp4 ``` H.265 / HEVC 視訊: ```powershell ffmpeg -i input.mp4 -c copy -bsf:v "hevc_metadata=sample_aspect_ratio=4/3" output.mp4 ``` ### 封裝字幕 必須確認輸出檔案格式有支援輸入字幕格式才可以封裝,若輸出檔案不支援輸入字幕格式可以使用 `-c:s` 字幕格式 轉換為有支援的。例如 MP4 只有支援封裝 `mov_text` 與 `dvdsub` 格式,若要將 SRT 字幕插入 MP4 檔內,就必須先轉為 `mov_text` 格式。 將 srt 轉換成 mov_text 插入 mp4 檔: ```powershell ffmpeg -input.mp4 -i input.srt -c copy -c:s mov_text output.mp4 ``` 將 input.idx + input.sub 插入 mp4 檔: ```powershell ffmpeg -input.mp4 -i input.idx -c copy output.mp4 ``` ### 對於網路播放優化 通常情況下,MPEG-4 與 QuickTime 檔案其詮釋資料(Metadata)位在檔案尾部,這使影片必須要被下載完成後才能開始播放,你可以將 `faststart` 加入 `movflags` 來將它移動到檔頭以得到更好的播放。除了 ffmpeg 以外,也可以使用 qt-faststart 工具來達到此目的。 將 `faststart` 加入 `movflags`: ```powershell ffmpeg -i input.mp4 -movflags +faststart -c copy output.mp4 ``` ###### tags: `ffmpeg`