FFmpeg 簡易教學

若對「命令提示字元」不熟,可以先學習之後再來。



  1. FFmpeg 是什麼?
  2. 轉神。

  3. FFmpeg 可以吃嗎?
  4. 不可以。

  5. FFmpeg 要從哪裡開始理解啊?
  6. 起源。

  7. 啥?
  8. 「FFmpeg」、「Mplayer」和「VLC」是三個很早就開始開發的的大型程式,「FFmpeg」主攻影音轉檔、「Mplayer」主攻影音串流、「VLC」主攻影音播放。但之後三個互通有無,所以三個都有彼此的功能。

  9. 又再講古了。
  10. 還有很多古沒說!「FFmpeg」早期多在支援 VCD、DVD 等格式,所以使用上會有很多問題,經常會當掉。但最近大力開發解碼、libx264 ,讓使用上大幅加分。

  11. 還有古嗎?
  12. 因為 FFmpeg 希望有容乃大,所以裡面盡量包山包海,再加上 FFmpeg 利用 Linux 的特性,使用「lib」函式庫的特性,讓使用者可以選擇需要用的編碼或解碼器自行編譯,製出符合自己的 FFmpeg。

  13. 等一下,作業系統是怎麼回事?
  14. 因為開發環境的便利、作業系統穩定因素等等, FFmpeg 使用 Linux 做為開發環境,而 Windows 版相繼有很多人釋出編譯版本,目前最大的是 Zeranoe 的 FFmpeg。

  15. 等於說我們不用自己下載 FFmpeg 來編譯了嗎?
  16. 對,大型作業系統都有很多人編譯完成,只要去下載使用即可。事實上編譯 FFmpeg 是一個浩大工程,不但要知道需要加入什麼函式庫,更要知道發現錯誤時要怎麼解決。

  17. 可以開始了嗎?
  18. 好吧。 Windows 請去 http://ffmpeg.zeranoe.com/builds/ 下載最新 Static 版本。早期版本有差,但現在己經沒有那種問題了;而請它的作業系統請去軟體中心找 FFmpeg 安裝。Linux 的使用者可以直接透過軟體管理工具安裝,又或者可以選其他 Static 方案,像是這裡

  19. 接下來呢?
  20. Windows 請解開並取出 \bin\ffmpeg.exe,跟其它作業系統一樣,打 FFmpeg 就可以執行了。其他作業系統可以直接使用 ffmpeg。

  21. 要如何叫出說明?
  22. ffmpeg -h


  23. 這沒有人看的懂啊!
  24. 沒錯,但這已經是縮小版的了,可以看 ffmpeg -h long 或是 ffmpeg -h full 更長,而之前的說明都是完整說明,根本沒有人想看。

  25. 有沒有速解法啊?
  26. 最基本的用法如:
    ffmpeg -i input.mpg output.mp4


  27. 咦?什麼資訊都沒有加?
  28. 對, FFmpeg 會用預設的參數執行。在 -i 後面加上輸入檔,最後一個參數指定輸出檔,它會自動判斷檔名來使用不同的編碼器。

  29. 可是這不一定是我要的結果啊!
  30. 所以開始要加參數了嘛,如函式庫、轉檔要求等。

  31. 函式庫?有什麼?
  32. 對於「.mp4」檔案,影像常用的是「h264」,音訊常用的是「aac」。

  33. 所以要怎麼用?
  34. 去「ffmpeg -codecs」找,可以看到有「h264」和「aac」可以使用,這時只要加上參數變成:

    ffmpeg -i input.mpg -c:v libx264 -c:a aac output.mp4


    c:v 的意思是說,對於影片,用 libx264 的編碼器,c:a 的意思是說,對於聲音,用 aac 的編碼器。
  35. 那要怎麼調比碼率(Bit Rate)?
  36. 用 -b:v 和 -b:a ,注意不同編譯版單位不同,大寫的 K 和小寫的 k 是差很多的,可以去説明看。

    ffmpeg -i input.mpg -c:v libx264 -c:a aac -b:v 1M -b:a 256k output.mp4


  37. 使用 libx264 有什麼需要注意的?
  38. 這是一個很複雜的議題,請前往這裡看。

  39. 還要自己確認複寫,好累喔!
  40. 可以加上不確認複寫的參數,如:

    ffmpeg -y -i i.mpg -c:v libx264 -c:a aac -b:v 1M -b:a 256k -pass 1 o.mp4
    ffmpeg -y -i i.mpg -c:v libx264 -c:a aac -b:v 1M -b:a 256k -pass 2 o.mp4


  41. 難道只能用 .mp4 檔案?
  42. Xvid 也可以啊,如:

    ffmpeg -i i.mp4 -c:v mpeg4 -c:a mp3 o.mpg


  43. 那可以做成 DVD 的格式嗎?
  44. 可以啊,如:

    ffmpeg -i i.mp4 -target ntsc-dvd dvd.mpg


  45. 不能燒啊,你騙我。
  46. 其實用 FFmpeg 做實在太累了,建議用 DVDStyler

  47. FFmpeg 就只有這樣嗎?
  48. 「這樣」就已經煉了好幾年。當然,FFmpeg 不只這樣,其實有一個基本的功能沒有說。

  49. 你混啊!到底是什麼?
  50. FFmpeg 可以重新對一個影片重新整理(mux),像是如果要把格式換成 .mpg,可以下指令如下:

    ffmpeg -i i.ts -c copy o.mpg


    這裡必須要提醒輸出的格式必須是有意義的,像是上述的範例是原始 i.ts 就是用 MPEG 的編碼,要不然轉檔會失敗。
  51. 這好像也沒有什麼了不起啊?
  52. FFmpeg 可以使用方便的映射功能,範例如下:

    ffmpeg -i i.ts -map 0:0 -map 0:2 -map 0:1 o.mpg


    可以用 ffmpeg -i i.ts 看每一軌的編號,再依序用 -map 指令放進去,亦可指定放入的方式,如 -map 1:2 是指第一個 -i 的第三軌(從 0 開始),而 -c:a:2 是指依 -map 放入的音軌中第二個要使用的編碼器。也可以放入多個檔案,如 ffmpeg -i i1.ts -i i2.ts。

  53. 它會重新轉檔嗎?
  54. 在以前,若要直接複製一軌,要分別下 -c:v copy -c:a copy ,但現在只要:

    ffmpeg -i i.ts -c copy o.mpg


  55. 這用不到,下一個。
  56. FFmpeg 也可以用來切割影片, -ss 是指定從哪裡開始切, -t 是從 -ss 開始切幾秒。如:

    ffmpeg -i i.ts -ss 00:05:00.0 -t 00:55:00.0 o.ts


    有一些新的 FFmpeg 有提供 -to 的指令,是切出 -ss 到 -to 這段時間影片。
  57. 這個動好像有點久?
  58. 在 FFmpeg 的説明中,有説到把 -ss 放在 -i 後面是慢速搜尋,FFmpeg 會從檔案的一開始搜尋,直到找到影格為止。如果把指令放在前面,如下:

    ffmpeg -ss 00:05:00.0 -i i.ts -t 00:55:00.0 o.ts


    會用快速搜尋,FFmpeg 會直接用關鍵影格(Keyframe)搜尋,會比較快,在 FFmpeg 2.1 版後有提高精準度,可以考慮使用。
  59. 那要怎麼合併影片檔?
  60. 這個問題學問不淺,這裡提供基本做法,建議是在使用上述切影片的方式切出影片後,再行合併會比較没有問題。

    ffmpeg -f concat -safe 0 -i mylist.txt -c copy -map 0 o.ts


    其中 mylist.txt 是:

    file 'file1.ts'
    file 'file2.ts'
    file 'file3.ts'
  61. 還有嗎?
  62. FFmpeg 現在已經加入 FontConfig ,可以輕易實現字幕內嵌的功能。

  63. 聴起來不錯。
  64. 首先,要去 http://oss.netfarm.it/mplayer-win32.php 最新版的 Mplayer ,把裡面的 \fonts 資料夾解出來與 ffmpeg.exe 同一資料夾。其他作業系統應該裝 Mplayer 就可以了。

  65. 再來呢?
  66. 就可以轉檔了:

    ffmpeg -i i.mp4 -filter:v ass=i.ass o.mp4


    這個方法是把字幕嵌進影片,之後是没有辦法移除,如果只是單純的放字幕,可以考慮直接放進去(ffmpeg -i i.ass)就好。
  67. 這好像是濾鏡喔?
  68. FFmpeg 支持很多濾鏡,上例 ass 是其中一個,有興趣的可以看看。



在此提供一些往下延伸的教學網站:


寫完了,FFmpeg 是很強大但問題不少,有使用上的問題可以提問看看。但 FFmpeg 本身太複雜不可能一一回答,在中國大陸還有網友成立一整個論壇就是在討論 FFmpeg ,以個人微薄之力不可能全部回答。不過還是可以試試看,也許是這篇教學不完整也說不定。



以下是寫給酷看的: FFmpeg 在影音轉檔上經常受到重視,這也是這篇教學的主要目地。這篇教學也改用 Libav 的新指令,也都有基本範例。

41 則留言:

  1. 很棒的入門教學!真感謝~

    請問:FFmpeg能夠將原本「長方形」影片轉成「梯形」影片嗎?
    如~

    |--------| /----\
    | | -> / \
    |--------| /--------\

    也就是我想調整四個角,有這樣的功能嗎?

    回覆刪除
    回覆
    1. 不好意思,由於留言會縮減「空白鍵」,
      在此我以其它字元代替,再次留言。

      |--------|....../----\
      |--------|..->./------\
      |--------|..../--------\

      刪除
    2. 請問一下這個是要做特效嗎?

      刪除
    3. 沒錯,就是透視投影!在OpenCV上可以做到,不知道FFmpeg能不能在播放時,將影片mapping到另一個座標空間?

      刪除
    4. 研究一下子

      目前有濾鏡 frei0r 可以做一些特效
      用關鍵字「perspective frei0r ffmpeg」可以搜出一些東西
      但指令卻行不通

      可能要再等一陣子會再找看看其他濾鏡吧

      刪除
  2. 呵~感謝你的嘗試!

    我之前用OpenCV作透視投影變換,
    發現影片fps變慢,
    在想FFmpeg能不能作透視投影變換,
    而且可以運算得非常快速,
    使得可以至少維持影片原本的fps。

    回覆刪除
  3. 對不起我們有一個專案想用ffmpeg來開發,您可以介紹高手給我們嗎?

    seandnlee@gmail.com

    回覆刪除
    回覆
    1. 對不起...
      本篇是個人胡亂研究出來的
      至於編譯 FFmpeg 是根本沒想過...
      開發這部分可能要讓您失望了

      刪除
  4. 謝謝大大的基本教學~

    回覆刪除
  5. 請問 FFmpeg 能不能在轉檔後自動刪除原始檔案?

    回覆刪除
    回覆
    1. 不可以
      但可以在 Windows 下 del 或在 Linux 下 rm 刪除

      刪除
  6. 感謝分享
    有段影片需要轉換成h.264 和acc 才能成功導入iMovie
    用vlc 轉換失敗(沒有acc)
    剛好看見你的教學,解決了問題

    回覆刪除
    回覆
    1. VLC 本身提供的轉檔本來就只有附加的功能而已
      可以的話用 FFmpeg 更快,也不會出現意外

      刪除
  7. 回覆
    1. 不要把 FFmpeg 想的太複雜喔
      相信很快你也可以上手的

      刪除
  8. 作者已經移除這則留言。

    回覆刪除
  9. 大大可以請教你一個問題嗎?我出現這樣的訊息

    Stream #0:0(eng): Video: h264 (libx264), yuv420p, 1280x536 [SAR 1:1 DAR 160:
    67], q=-1--1, 23.98 fps, 23.98 tbn, 23.98 tbc (default)
    Metadata:
    _STATISTICS_WRITING_APP: mkvmerge v7.9.0 ('Birds') 64bit
    _STATISTICS_WRITING_APP-eng: mkvmerge v7.9.0 ('Birds') 64bit
    _STATISTICS_WRITING_DATE_UTC: 2015-09-25 05:38:23
    _STATISTICS_WRITING_DATE_UTC-eng: 2015-09-25 05:38:23
    _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    BPS : 5581122
    BPS-eng : 5581122
    DURATION : 02:05:43.006000000
    DURATION-eng : 02:05:43.006000000
    NUMBER_OF_FRAMES: 180851
    NUMBER_OF_FRAMES-eng: 180851
    NUMBER_OF_BYTES : 5262304859
    NUMBER_OF_BYTES-eng: 5262304859
    encoder : Lavc57.15.100 libx264
    Stream #0:1(eng): Audio: aac, 0 channels, 128 kb/s (default)
    Metadata:
    _STATISTICS_WRITING_APP: mkvmerge v7.9.0 ('Birds') 64bit
    _STATISTICS_WRITING_APP-eng: mkvmerge v7.9.0 ('Birds') 64bit
    _STATISTICS_WRITING_DATE_UTC: 2015-09-25 05:38:23
    _STATISTICS_WRITING_DATE_UTC-eng: 2015-09-25 05:38:23
    _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    BPS : 640000
    BPS-eng : 640000
    DURATION : 02:05:43.008000000
    DURATION-eng : 02:05:43.008000000
    NUMBER_OF_FRAMES: 235719
    NUMBER_OF_FRAMES-eng: 235719
    NUMBER_OF_BYTES : 603440640
    NUMBER_OF_BYTES-eng: 603440640
    encoder : Lavc57.15.100 libvo_aacenc
    Stream mapping:
    Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
    Stream #0:1 -> #0:1 (ac3 (native) -> aac (libvo_aacenc))
    Error while opening encoder for output stream #0:1 - maybe incorrect parameters
    such as bit_rate, rate, width or height

    我是單純的使用

    ffmpeg -i 1.mkv 1.mp4

    回覆刪除
    回覆
    1. 因為輸入的聲音是杜比(這是從原始來源沒有壓縮過的),所以可能有下列情況:
      1. FFmpeg 不知道要如何映射聲道,可以先下 ffmpeg -i i.mkv -ac 2 o.mp4 試看看
      2. FFmpeg 不知道要如何重新採樣,可以試看看 ffmpeg -i i.mkv -filter:a "aresample=matrix_encoding=dplii" -ac 2 o.mp4 或是 ffmpeg -i i.mkv -filter:a "aresample=44100" -ac 2 o.mp4
      3. FFmpeg 沒有辦法處理現在的杜比聲道,但機率很低

      可以的話試著不要轉成 libvo_aacenc ,那個音質真的很差

      刪除
    2. ffmpeg -i i.mkv -ac 2 o.mp4 可以了!謝謝大大唷!因為投影機沒有辦法放杜比跟acc3。所以要轉成acc檔嚕!謝謝大大

      刪除
  10. 作者已經移除這則留言。

    回覆刪除
  11. 看您的文章很享受,很快就入門ffmpeg了, 順便想請教一下,ffmpeg是否可以將幾張照片組合成影片,另外加上字幕及背景音樂,字幕用您說的FontConfig 指令, 可以加上去嗎? 拜託老大有空回覆一下了~ 感恩~

    回覆刪除
  12. 非常感謝回覆,因在下是要寫在 web上,做成網站的功能的,所以只能借助ffmpeg方便的指令功能,另外想請教不曉得有沒有將聲音 fade fadeout功能呢 ?您所指的特效是影片轉場的特效嗎?

    回覆刪除
  13. 感謝回覆 因目的是想做成影片檔放在網站上這樣可以有個節點 好方便分享到社群網站當中… 請教一下 js不是前端的語言嗎?他有辦法在伺服器上頭產生影片檔嗎?感謝您熱心的解答~

    回覆刪除
    回覆
    1. JavaScript 沒有辦法在伺服器後端產生影片
      聽你的需求可能要讓使用者自訂照片、字幕和聲音
      這些直接找看有沒有別人寫好的套件會比較快
      自己弄會浪費時間

      刪除
    2. 沒問題的
      https://www.npmjs.com/package/ffmpeg

      刪除
    3. 後來我的做法是把使用者上傳的照片、選定的音樂、字幕統一收集到server端,再用exec的方式執行ffmpeg做成投影片的檔案供使用者下載分享,大大提供的方法是用Node.js 直接在前端就可以處理掉了?若不需要存檔留底的話,省事很多的感覺....^^

      刪除
    4. Node.js 也是後端的東西喔
      而且去寫一個類似 exec 的東西也不會比較麻煩
      如果真的有要使用 Node.js 再考慮使用會比較好

      刪除
    5. 原來如此, 看到js code, 我還以為是前端的@@

      刪除
  14. 作者已經移除這則留言。

    回覆刪除
  15. 你好,感謝豐富的教學
    想請問使用FFmpeg 可以將一個檔案重覆的轉檔嗎?
    謝謝

    回覆刪除
    回覆
    1. 可以啊
      ffmpeg -i in.mp4 out.mp4
      del in.mp4
      move out.mp4 in.mp4

      另外這裡有人把聲音檔轉 100 次的結果
      可以看一看

      刪除
  16. 您好, 想請問有從影片轉成frame的經驗嗎?
    我有個疑惑是透過ffmpeg轉影片到frame, 輸出的數量與quicktime player上看到的卻不一致
    不知道是不是ffmpeg 會補frmae?...
    ffmpeg -i video.mp4 %d.jpg

    回覆刪除
  17. 您好,寫的很棒。
    請教,我有一個早期的vcd光碟,裡面有二段影片,影片開始有二個小圖作選單。
    想把二段影片分割成單獨的檔案。
    但只能取出第一段的影片,第二段即使設好開始的時間,及擷取的時間,但只有出現第一段的最後一張圖片。
    即使我先把全部都轉成mp4檔,也出現上述狀況。
    請問能給個建議嗎?謝謝。

    回覆刪除
    回覆
    1. VCD 基本上只要複製原始影片就好

      刪除
  18. 大大您好, 請問 我下如下這段code,想看quick syncquick sync的狀況, ffmpeg.exe -i file_example_MP4_1920_18MG.mp4 -c:v hevc_qsv-c:a copy -quality quality -b:v 3M -bufsize 16M -maxrate 6M outputhevcIntel.mp4
    得到的結果是 frame= 901 fps= 37 q=-0.0 Lsize= 10881kB time=00:00:30.52 bitrate=2919.9kbits/s speed=1.27x
    請問 q, Lsize speed是個別代表甚麼意思呢 為什麼我使用不同的編碼器 都會得到不同的結果呢 像speed都會不一樣, 1.27x 是代表甚麼意思呢
    感謝!

    回覆刪除
  19. 不好意思 假如我想改函示庫 需要怎麼改 我想想添加下面的isom.c
    1 { AV_CODEC_ID_HEVC , MKTAG ('h', 'v', 'c', '2') }, /* HEVC / H.265 coded
    with gpac */
    2 { AV_CODEC_ID_HEVC , MKTAG ('h', 'v', 't', '1') }, /* HEVC / H.265 coded
    with gpac */

    回覆刪除
  20. 高手在上,請收下我膝蓋

    回覆刪除

定時會整理。