[電腦] 電腦工具 / ffmpeg === ###### tags: `學科` ###### tags: `學科`, `電腦`, `工具`, `ffmpeg`, `video`, `m3u8`, `mpd`, `m4s`, `mp4`, `剪接`, `剪輯`, `裁減` <br> [TOC] <br> ## 教學 ### 轉檔 - [[vob -> mp4] ffmpeg – 把光碟轉換成MP4](http://jashliao.eu/wordpress/2020/11/26/ffmpeg-%E6%8A%8A%E5%85%89%E7%A2%9F%E8%BD%89%E6%8F%9B%E6%88%90mp4/) 1. 合併多個 vob 文件 Linux: `$ cat *.VOB > output.vob` Windows: `> copy *.VOB output.vob` 2. 識別vob 信息 `ffmpeg -i output.vob` 3. 進一步識別視頻信息 `$ ffmpeg -analyzeduration 100M -probesize 100M -i output.vob` 4. 轉檔 ``` $ ffmpeg -i output.vob -preset superfast -crf 21 \ -c:a ac3 \ -c:s copy \ -map 0:1 -map 0:2 -map 0:3 -map 0:4 -map 0:5 \ output.mkv ``` 速度和質量比較理想的平衡 `-preset superfast -crf 18` ### 參數 - ### [x264的preset與編碼速度、影片畫質以及位元率的關聯](https://magiclen.org/x264-preset/) - ### [超簡單的中階影片轉檔教學](https://blog.xuite.net/ak47xd/blog/63836273) C:CRF (Constant Rate Factor) 固定 質量/品質 係數 - 指定影片品質,無法預先得知位元率 - 數值0~51,可以是浮點數。數值越大檔案越小、畫質越差 - 接近無損:17、18 - 畫質良好:19~22 - 畫質好:23、24 - 不能看:>30 - ### [FFmpeg H.264 編碼器](https://blog.dexiang.me/zh-tw/technologies/ffmpeg-h264-options/) - Constant Rate Factor(CRF) - 固定品質指標,而不在意大小 - CRF 會得到最佳的 bitrate 分配結果 - 缺點是你不能直接指定一個目標 bitrate 或是檔案大小。 - 設定值範圍為 0 – 51 - 0 為最高品質 - 預設值為 23 - 建議的範圍在 18 - 28,17 或 18 接近視覺無損, 但在技術上來說並不是無損。 - Preset 用來設定編碼速度,相對的也會影響到壓縮比;編碼越快則壓縮比越低。 - 參數優先順序 preset -> tune -> "custom" -> profile -> level - [X264碼率控制總結1——ABR,CQP,CRF](https://www.twblogs.net/a/5c9c055ebd9eee73ef4b130e) - ### map - [ffmpeg命令行map参数的使用](https://blog.csdn.net/xiaoluer/article/details/81136478) :+1: :100: - 输出文件的stream顺序取决于在命令行中-map的参数顺序。 - 範例1 - input ``` Stream #0:0(eng): Video: h264 (High), .. Stream #0:1(ger): Audio: dts (DTS), ... Stream #0:2(eng): Audio: dts (DTS), ... Stream #0:3(ger): Subtitle: text (default) ``` - target - 将视频流复制 - 将德语音频流编码为MP3(128kbps)和AAC(96kbps)(在输出中创建两个音频流) - 将英语音频流删除 - 将字幕流复制 - command ```bash= $ ffmpeg -i input.mkv \ -map 0:0 -map 0:1 -map 0:1 -map 0:3 \ -c:v copy \ -c:a:0 libmp3lame -b:a:0 128k \ -c:a:1 libfaac -b:a:1 96k \ -c:s copy \ output.mkv ``` - 範例8 - input `Stream #0:3[0x81]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s` - map 用法(同義) - `-map 0:3` - `-map i:0x81` - ### mkv > 須加上 `-fflags +genpts` - [Timestamps are unset in a packet for stream 0. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly](https://video.stackexchange.com/questions/24462) - ### subtitle - [[FFmpeg] 烙印字幕至影像上 (Hardsub)](https://www.mobile01.com/topicdetail.php?f=510&t=4462836) - [How to extract subtitle from video using ffmpeg?](https://superuser.com/questions/583393) ### error 排解 - `Stream map '0:4' matches no streams. To ignore this, add a trailing '?' to the map.` - **原始指令** `$ ffmpeg.exe -i VTS_05_1.VOB -c:a copy -c:s copy -map 0:1 -map 0:2 -map 0:3 -map 0:4 -map 0:5 VTS_05_1.mp4` <br> - **解決方法:** 添加參數 `-analyzeduration 100M -probesize 100M` 且要放在 `-i` 前面 `$ ffmpeg.exe -analyzeduration 100M -probesize 100M -i VTS_05_1.VOB` 字幕檔資訊,約出現在 30M 左右 [![](https://i.imgur.com/QzcS35u.png)](https://i.imgur.com/QzcS35u.png) - 在沒有 `-map 0:4 -map 0:5` 參數,隨後找到的資訊 <br> - **完整指令** `$ ffmpeg.exe -analyzeduration 100M -probesize 100M -i VTS_05_1.VOB -c:a copy -c:s copy -map 0:1 -map 0:2 -map 0:3 -map 0:4 -map 0:5 VTS_05_1.mp4` - **參考說明** - [ffmpeg: how to include a later starting dvb-subtitle stream?](https://askubuntu.com/questions/1105050) > option `-probesize` to force ffmpeg to search enough bytes into the input file > option `-analyzeduration` to force it to search for enough seconds. - **注意**:底下兩者結果不同 - `$ ffmpeg.exe -analyzeduration 100M -probesize 100M -i VTS_05_1.VOB` ``` Input #0, mpeg, from 'VTS_05_1.VOB': Duration: 00:23:30.88, start: 0.280633, bitrate: 6088 kb/s Stream #0:0[0x1bf]: Data: dvd_nav_packet Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, progressive), 720x480 [SAR 32:27 DAR 16:9], 30 fps, 59.94 tbr, 90k tbn, 59.94 tbc Side data: cpb: bitrate max/min/avg: 9000000/0/0 buffer size: 1835008 vbv_delay: N/A Stream #0:2[0x80]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s Stream #0:3[0x81]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s Stream #0:4[0x21]: Subtitle: dvd_subtitle Stream #0:5[0x20]: Subtitle: dvd_subtitle ``` - `$ ffmpeg.exe -i VTS_05_1.VOB -analyzeduration 100M -probesize 100M` ``` Input #0, mpeg, from 'VTS_05_1.VOB': Duration: 00:23:30.88, start: 0.280633, bitrate: 6088 kb/s Stream #0:0[0x1bf]: Data: dvd_nav_packet Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, progressive), 720x480 [SAR 32:27 DAR 16:9], 30.47 fps, 59.94 tbr, 90k tbn, 59.94 tbc Side data: cpb: bitrate max/min/avg: 9000000/0/0 buffer size: 1835008 vbv_delay: N/A Stream #0:2[0x80]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s Stream #0:3[0x81]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s ``` ### 參考資料 - ### [FFmpeg 簡易教學](https://lnpcd.blogspot.com/2012/09/ffmpeg.html) - 映射功能 - 重新轉檔 - 切割影片 - 合併影片檔 - ### [利用ffmpeg指令影片轉檔與合併字幕](https://shimeche.github.io/2016/10/14/利用ffmpeg影片轉檔與合併字幕/) <br> <hr> <br> ## 剪接/剪輯/裁減 - ### ffmpeg可以作影片裁減嗎? 比如指定第 0 - 10 秒輸出 > 使用 FFmpeg 裁減影片 FFmpeg 可以用來裁減影片的特定部分,使用 `-ss` 和 `-to` 參數即可完成。以下是一個範例,裁減影片第 0 到 10 秒: ### 範例指令 ``` ffmpeg -i input.mp4 -ss 0 -to 10 -c copy output.mp4 ``` ### 參數說明 1. **`-i input.mp4`**:指定輸入的影片檔案。 2. **`-ss 0`**:設定起始時間為第 0 秒。 3. **`-to 10`**:設定結束時間為第 10 秒。 4. **`-c copy`**:直接複製編碼,不重新壓縮,處理速度更快,且保留原始畫質。 ### 如果需要重新編碼 如果你需要重新編碼影片(例如改變格式或壓縮),可以省略 `-c copy`,如下: ``` ffmpeg -i input.mp4 -ss 0 -to 10 output.mp4 ``` 這樣的方式會重新壓縮影片,輸出檔案的大小和畫質可能會有所改變。 ### 注意事項 - **更精確裁減**:如果需要更精確的時間裁減(到幀級),可以將 `-ss` 放在 `-i` 後面(如上述範例),這樣裁減會更精準。 - **測試片段**:若處理的檔案非常大,建議先測試小片段,確保參數正確,再對完整檔案操作。 --- - ### [排解問題] 為何轉檔完,前面的影格都沒有變換,直到數秒後,才能正常撥放? > FFmpeg 剪裁影片問題與解決方案: > - 不要使用 `-c copy` > - 且需要重新編碼 > (2025/01/03 驗證過) ### 問題描述 當使用 FFmpeg 剪裁影片時,可能會出現影片的前幾秒未正常變換的情況,直到數秒後才正常播放。這通常是因為 `-ss` 參數的使用位置與解碼方式造成的。 ### 問題原因 1. **`-ss` 放在輸入檔 (`-i`) 之前** - 此時 FFmpeg 以「快速跳過幀」的方式定位到指定的時間點,但這種方式可能不夠精確。 - 如果指定的起始時間點不是關鍵幀(Keyframe),影片仍需解碼從最近的關鍵幀開始的所有幀,導致頭幾秒可能包含未裁減的畫面。 2. **關鍵幀問題** - 關鍵幀是完整存儲畫面數據的幀,其餘幀依賴關鍵幀進行解碼。 - 若裁剪點不在關鍵幀上,FFmpeg 會包括從最近關鍵幀開始到指定時間點之間的畫面。 --- ### 解決方法 1. **將 `-ss` 放在輸入檔 (`-i`) 後** - 這樣 FFmpeg 會先解碼再定位,能更精確地裁減到指定的時間點: ``` ffmpeg -i input.mp4 -ss 0 -to 10 -c copy output.mp4 ``` 2. **使用重新編碼** - 不使用 `-c copy`,讓 FFmpeg 重新編碼影片: ``` ffmpeg -i input.mp4 -ss 0 -to 10 output.mp4 ``` - 雖然重新編碼耗時較長,但能確保裁減的畫面完全正確。 3. **結合快速定位與精確裁減** - 使用 `-ss` 放在輸入之前快速跳到接近時間點,再進行精確裁減: ``` ffmpeg -ss 0 -i input.mp4 -to 10 output.mp4 ``` ### 推薦使用方法 - **快速方式**: 使用 `-c copy` 並將 `-ss` 放在輸入檔之前,處理速度快,但精度可能稍低。 - **精確方式**: 將 `-ss` 放在輸入檔之後,或直接重新編碼,能保證時間點精確。 ### 注意事項 1. **快速剪裁與精確性**: 如果需要更精確的裁減結果,推薦重新編碼或將 `-ss` 放在輸入檔之後。 2. **處理大檔案**: 建議先測試小片段以確保參數正確,避免耗時處理整個檔案後才發現問題。 <br> <hr> <br> ## 轉檔 ### mov to mp4 - [Convert .mov to .mp4 with ffmpeg](https://mrcoles.com/convert-mov-mp4-ffmpeg/) ``` ffmpeg -i input.mov -vcodec h264 -acodec mp2 output.mp4 ``` - [Getting the smallest video with same quality, how to with FFMPEG?](https://superuser.com/questions/933264/) ``` ffmpeg -i input.avi -c:v libx264 -crf 18 -preset veryslow -c:a copy out.mp4 ``` - -vcodec libx264 -crf 18 ### mp4 to mkv ``` ffmpeg -i input.mp4 -c:v copy -crf 19 output.mkv ``` <br> <hr> <br> ### mp4 to mp3 - ### [How can I convert MP4 video to MP3 audio with FFmpeg?](https://superuser.com/questions/332347/) ``` ffmpeg -i filename.mp4 filename.mp3 ``` or ``` ffmpeg -i video.mp4 -b:a 192K -vn music.mp3 ``` <br> ### m3u8 to ts - ### [利用ffmpeg合併m3u8串流影片,並且轉成MP4格式/](https://shimeche.github.io/2017/04/13/利用ffmpeg合併m3u8串流影片,並且轉成MP4格式/) - 範例 `ffmpeg -i "m3u8網址" -c copy output.ts` <br> ### m3u8 to mp4 - ### [利用ffmpeg合併m3u8串流影片,並且轉成MP4格式/](https://shimeche.github.io/2017/04/13/利用ffmpeg合併m3u8串流影片,並且轉成MP4格式/) - 範例 `ffmpeg -i "m3u8網址" -c copy output.mp4` - 網址最好用雙引號標示 (在 windows 可能有不如預期) - -c copy 告知影音編碼用複製就好,不需要再次轉碼 - 透過 wget 下載 + cat 合併 - ### [[stackoverflow] Protocol 'https' not on whitelist](https://stackoverflow.com/questions/50455695) - 參數用法 `-protocol_whitelist file,http,https,tcp,tls,crypto` - 範例 ``` ffmpeg \ -protocol_whitelist file,http,https,tcp,tls,crypto \ -i input.m3u8 \ -c copy \ output.mp4 ``` <br> <hr> <br> ## 合併 - ### [How to merge audio and video file in ffmpeg](https://superuser.com/questions/277642) ``` ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac output.mp4 ``` ### [討論] 使用 ffmpeg 合併無音訊影片與音訊檔案 - ### Q: 我要執行 ffmpeg ``` - input: videoplayback.mp4 (no audio) - input: videoplayback.m4a (audio) - output: mp4 with audio ``` - ### gpt-4o ### 指令說明: 使用 `ffmpeg` 將影片 (`videoplayback.mp4`) 與音訊 (`videoplayback.m4a`) 合併成包含音訊的 MP4 檔案。 #### 指令: ``` ffmpeg -i videoplayback.mp4 \ -i videoplayback.m4a \ -c:v copy \ -c:a aac -b:a 192k \ output.mp4 ``` #### 參數說明: - `-i videoplayback.mp4`:指定影片輸入檔(無音訊)。 - `-i videoplayback.m4a`:指定音訊輸入檔。 - `-c:v copy`:保持影片編碼不變(直接複製,不重新編碼)。 - `-c:a aac -b:a 192k`:將音訊轉換為 AAC(如果 m4a 已經是 AAC,可省略重新編碼)。 - `output.mp4`:輸出的 MP4 檔案。 --- ### 如果音訊檔 (`m4a`) 已經是 AAC 格式 如果 `videoplayback.m4a` 已經是 AAC 格式,可省略音訊轉碼,使用以下指令來直接複製音訊與影片: ``` ffmpeg -i videoplayback.mp4 \ -i videoplayback.m4a \ -c:v copy -c:a copy \ output.mp4 ``` 這樣可以避免重新編碼,提高處理速度並保持原始音訊品質。 <br> <hr> <br> ## 參數 ### CRF (Constant Rate Factor) > 固定 質量/品質 係數 - ### [超簡單的中階影片轉檔教學](https://blog.xuite.net/ak47xd/blog/63836273) - 接近無損:17、18 - 畫質良好:19~22 - 畫質好:23、24 - 不能看:>30 <br> ### [討論] `-b:a 192k` 中的 `-b` 意思為何?全名為? > b: bitrate - ### gpt-4o > FFmpeg `-b` 參數說明 `-b` 參數的全名是 **`-b:stream_specifier`**,代表 **比特率(bitrate)** 設定,適用於音訊與影片流。 在 `ffmpeg` 指令中: ``` ffmpeg -i videoplayback.mp4 \ -i videoplayback.m4a \ -c:v copy -c:a aac -b:a 192k \ output.mp4 ``` - `-b:a` 是 `-b:audio` 的縮寫,代表 **設定音訊(audio)比特率**。 - `192k` 代表 **192 kbps(kilobits per second)**,即音訊的比特率為 192kbps。 ## `-b` 的常見用法: - `-b:v 3000k`:設定影片(video)比特率為 **3000kbps (3Mbps)**。 - `-b:a 128k`:設定音訊(audio)比特率為 **128kbps**。 在上述情境下,`-b:a 192k` 讓 ffmpeg 在轉換音訊時,使用 192kbps 作為 AAC 壓縮的比特率。 若省略 `-b:a`,ffmpeg 會使用編碼器的預設比特率。 <br> <hr> <br> ## 檔案類型 ### .m3u8 (.ts list) ``` ffmpeg.exe -i "manifest.m3u8" -c copy output.mp4 ``` - [由M3U8(TS)或MPD(M4S)获取视频](https://blog.csdn.net/jansenzhu/article/details/113785659) <br> ### .mpd (.m4s list) ``` ffmpeg.exe -i "manifest.mpd" -c copy output.mp4 ``` - [FFMPEG: How to manually select video quality from mpd manifest?](https://stackoverflow.com/questions/60549399) ``` $ ffprobe your_manifest.mpd ``` - [由M3U8(TS)或MPD(M4S)获取视频](https://blog.csdn.net/jansenzhu/article/details/113785659) - mpd 有兩種類型:video 和 audio - 得到视频和音频的*.mp4+*.m4s。但这时候的*.mp4是看不了的,因为它只是一个视频(音频)头 ``` copy /b d:\video\1.mp4 d:\video\*.m4s video.mp4 ``` - 最后用 ffmpeg 合并 video.mp4 和 audio.mp4 `ffmpeg.exe -i "d:\video\video.mp4" -i "d:\audio\audio.mp4" -c:v copy -c:a copy "D:\final.mp4"` <br> ### m4s - [如何无损合并video.m4s与audio.m4s为mp4文件](https://www.bilibili.com/read/cv10533506) ``` ffmpeg -i video.m4s -i audio.m4s -codec copy output.mp4 ``` <br> ### .ts > [wiki](https://zh.wikipedia.org/wiki/MPEG2-TS) - merge `copy /b *.ts merged.ts` - File Type : M2T (MPEG-2 transport stream) - MIME Type : video/mpeg - Audio Stream Type : MPEG-2 AAC Audio - 參考資料 - [利用ffmpeg合併m3u8串流影片,並且轉成MP4格式/](https://shimeche.github.io/2017/04/13/利用ffmpeg合併m3u8串流影片,並且轉成MP4格式/) <br> ### .mp4 > [wiki](https://zh.wikipedia.org/wiki/MP4) > - File Type : MP4 - MIME Type : video/mp4 - Audio Stream Type : MP4 Base Media v1 [IS0 14496-12:2003] - 參考資料 - [利用ffmpeg合併m3u8串流影片,並且轉成MP4格式/](https://shimeche.github.io/2017/04/13/利用ffmpeg合併m3u8串流影片,並且轉成MP4格式/) {%hackmd vaaMgNRPS4KGJDSFG0ZE0w %}