Computer >> Hướng Dẫn Máy Tính >  >> Phần Mềm >> Phần Mềm

Làm chủ ffmpeg: Hướng dẫn chỉnh sửa đa phương tiện hoàn chỉnh

Quay nhiều năm, đã có nhiều dịp tôi cần làm某种形式的多媒体编辑。音频、视频,随你叫。无论是为YouTube频道制作那些不好笑的片段,提取或转换音乐,嵌入字幕,一次又一次,我发现自己在命令行使用ffmpeg,并总是享受这个过程,同时对这个看似不起眼的程序的能力感到微妙的惊叹。

所以我以为,也许我应该写一份更全面的ffmpeg指南,列出各种任务和功能,然后用真实案例和用例包装它们。虽然我在2008年的Flash编辑教程中第一次愤怒地提到ffmpeg,但现在是时候写一篇新的、更新的文章了。它将是命令行,将是极客风,但也应该好玩。跟我来。

Cơ bản (Basics)

Ffmpeg có sẵn trong hầu như tất cả mọi distro Linux, và cũng có build cho Windows và Mac. Nếu bạn muốn biết nó làm được gì, bạn có thể kiểm tra khả năng bằng cách chạy ffmpeg không tham số hoặc với cờ -hide_banner tùy chọn. Bạn cũng có thể dùng tùy chọn help cho chương trình chính cũng như bất kỳ sub-command nào trong nhiều sub-command của nó. Mảng tính năng rực rỡ có thể gây ngợp, vì vậy chúng ta sẽ tiến hành từ từ nhưng chắc chắn. Đừng quên tài liệu thực tế, nó khá gọn gàng.

Chuyển đổi và Transcoding (Conversion and transcoding)

Một trong những tác vụ phổ biến nhất là chuyển đổi file từ định dạng này sang định dạng khác. Nhớ ví dụ của tôi cách trích xuất file âm thanh từ clip FLV? Cái giống. Nhưng bạn có thể muốn chuyển video quay từ camera sang MP4, hoặc chuyển file OGG sang MP3, hoặc tương tự. Có vô vàn kịch bản, và số lượng mode và định dạng hỗ trợ trong ffmpeg cũng vô tận như nhau. Thông thường, bạn sẽ làm:

  • Chỉ định file đầu vào.
  • Chỉ định codec video và audio mong muốn.
  • Chỉ định file đầu ra.

Nếu bạn không muốn thao tác luồng video, bạn có thể dùng codec copy. Tương tự cho audio. Bạn có thể dùng tùy chọn này nếu muốn đổi container, như từ MOV sang MP4 mà không thay đổi encoding thực tế.

ffmpeg -i MVI_1348.MOV -c:v copy -c:a copy new.mp4

Lưu ý: không phải định dạng nào cũng hỗ trợ tất cả codec và tùy chọn, nên không nhất thiết chạy được mọi trường hợp. Như:

[mp4 @ 0x55a21519fb20] Could not find tag for codec vp8 in stream #0, codec not currently supported in container
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Last message repeated 1 time

Nếu bạn chỉ muốn trích xuất một luồng nhất định - âm thanh, video, phụ đề, hoặc dữ liệu - bạn có thể bỏ qua xử lý các luồng khác (để tiết kiệm thời gian và chu kỳ CPU cần thiết cho thao tác). Ví dụ, nếu bạn chỉ muốn âm thanh từ file media kết hợp âm thanh-video, bạn có thể dùng tùy chọn -vn (no video).

ffmpeg -i MVI_1348.MOV -vn -ar 44100 -ab 192k sound-only.mp3

Tiện ích tuyệt vời này cho bạn rất nhiều sự linh hoạt trong cách bạn làm việc. Ví dụ, codec:v, vcodec và c:v là giống hệt nhau, và bạn có thể dùng bất kỳ cái nào bạn muốn. Nếu bạn chỉ muốn output âm thanh, như trên, ffmpeg sẽ đoán và giả định bạn cũng có ý -vn. Bạn cũng có thể dùng cờ -f để ép định dạng output, nhưng công cụ sẽ cố gắng đoán kết quả cuối từ lệnh của bạn. Ví dụ, bạn có thể dùng -f mp3 hoặc acodec mp3.

Codec khác nhau sẽ có tùy chọn khác nhau. Ví dụ, cho file âm thanh, bạn có thể chỉ định tỷ lệ lấy mẫu âm thanh và bitrate âm thanh, số kênh, và hơn thế. Nếu bỏ qua một số tùy chọn, lệnh có thể fail, hoặc mặc định sẽ được dùng.

Scale (tỷ lệ) và chất lượng (quality)

Một tác vụ phổ biến khác là thay đổi kích thước video (độ phân giải) và chất lượng luồng. Ffmpeg cho phép bạn làm điều này theo nhiều cách. bạn có thể ép tỷ lệ (và phá vỡ tỷ lệ khung hình mặc định), hoặc bảo toàn nó bằng cách chỉ định giá trị dọc hoặc ngang cộng với một qualifier ma thuật. Bạn có thể cắt viền video (crop), và bạn có thể re-encode luồng. Ví dụ là cần thiết ở giai đoạn này.

ffmpeg -i input.avi -c:v mpeg4 -vtag xvid -qscale:v 3 -c:a libmp3lame -qscale:a 4 output.avi

Chúng ta có gì ở đây? Chúng ta đang transcoding file AVI đầu vào bằng cách dùng luồng video MPEG4 với chất lượng đặt là 3 (qscale). Với một số codec, chất lượng dao động từ 1-31, với 1 là cao nhất. Tôi test trên một vài file đầu vào chung, và chất lượng cao nhất thường dẫn đến kích thước gấp đôi, trong khi 3 hoặc 4 cho giảm khoảng 20-30%. Vtag xvid là tùy chọn đặc thù MPEG-4. Tương tự, chúng ta dùng LAME cho âm thanh.

ffmpeg -i MVI_1348.MOV -vfilters scale=1280:-1 -c:a copy scaled.mp4

Ví dụ này cho thấy video scaling (bạn có thể dùng -vf hoặc -vfilters), với tỷ lệ khung hình được bảo toàn qua qualifier -1. Chúng ta không thay đổi chất lượng luồng. Luồng âm thanh đơn giản được copy vào container output. Nếu video gốc có độ phân giải cao hơn giá trị nêu, bạn sẽ downscale, và nếu thấp hơn, bạn sẽ upscale.

Trích xuất hình ảnh, kết hợp, GIFs

Ffmpeg cũng có thể thao tác hình ảnh, mặc dù nó là tiện ích media. Nhưng hey, hình ảnh là media, và về bản chất, video là những hình ảnh chuyển động, phải không! Một số tác vụ bạn muốn - trích xuất frame từ video để tạo thumbnail (chất lượng cao) thay vì tạm dừng video thủ công hoặc chụp màn hình hỗn loạn. Bạn cũng có thể làm ngược lại - kết hợp ảnh tĩnh thành video stopmotion - hoặc video đầy đủ. Bạn cũng có thể chuyển video thành GIF động, có thể tiện cho dank memeism trên Web. Một lần nữa, chúng ta sẽ demo với một số... ví dụ dank.

ffmpeg -i input.mp4 -r 1 -f image2 thumb-%3d.png

Chúng ta chỉ định file đầu vào, chỉ định rate (trong trường hợp này chúng ta muốn 1 ảnh mỗi 1 giây video), chỉ định format (image2), và chỉ định định dạng output. Trong trường hợp này, chúng ta làm một việc thông minh. Nếu bạn từng thấy code ngôn ngữ C, điều này sẽ quen thuộc. Chúng ta muốn chuỗi số cho thumbnail có ba chữ số. Bạn có thể chọn bất kỳ số lượng chữ số, nhưng lý tưởng, bạn muốn nhiều hơn số ảnh trích xuất dự kiến.

Làm chủ ffmpeg: Hướng dẫn chỉnh sửa đa phương tiện hoàn chỉnh

Sau đó, kết hợp ảnh thành video rất tương tự:

ffmpeg -f image2 -i thumb-%3d.png stopmotion.mp4

Bạn cũng có thể chỉ định rate (bạn muốn video của bạn khoảng 24 hoặc 30 FPS), nhưng chúng ta sẽ chạm đến này nhiều hơn sau trong hướng dẫn, khi nói về làm video playback chậm hơn và/hoặc nhanh hơn. Và vì chúng ta nói về hình ảnh, bạn cũng có thể resize chúng:

ffmpeg -i thumb-004.png -vf scale=400:-1 test.png

Animated GIFs rất thú vị. Cũng khá đơn giản để tạo. Chỉ cần chỉ định file đầu vào và đặt output có đuôi gif. Ffmpeg sẽ tự đoán phần còn lại và tạo GIF động chất lượng cao, đẹp cho bạn.

ffmpeg -i MVI_6654.MOV test.gif

Làm chủ ffmpeg: Hướng dẫn chỉnh sửa đa phương tiện hoàn chỉnh

Cuối cùng, ngược lại của GIFs, bạn cũng có thể muốn video bao gồm một hình ảnh đơn lẻ - một preview hằng số nhưng sau đó có thứ như nhạc hoặc podcast chơi ở background. Ffmpeg cho phép bạn làm điều này với một thủ thuật thông minh.

ffmpeg -loop 1 -i thumb-001.png -i sound-only.mp3 -c:v libx264 -shortest video-static-image.mp4

Chúng ta cung cấp hai input, với cái đầu tiên là ảnh set loop. Chúng ta cũng re-encode video. Nhưng vì ảnh được set loop vô hạn, chúng ta cũng cần tùy chọn shortest, để thao tác kết thúc khi clip ngắn nhất kết thúc, cái đó sẽ là video trong trường hợp này.

Tách và nối video (Splitting and joining videos)

Đây là một kịch bản hữu ích khác. Nếu bạn có một clip rất lớn, nhưng bạn chỉ cần vài phút hoặc giây, ffmpeg có thể cắt lấy các mảnh cần thiết. Tương tự, bạn có thể kết hợp nhiều file thành một luồng - cả video và âm thanh. Ffmpeg cho phép bạn chọn timestamp bắt đầu và kết thúc mong muốn, nên bạn có nhiều sự lựa chọn trong cách xử lý tác vụ.

-t duration         record or transcode "duration" seconds of audio/video
-to time_stop       record or transcode stop time
-fs limit_size      set the limit file size in bytes
-ss time_off        set the start time offset
-sseof time_off     set the start time offset relative to EOF
-seek_timestamp     enable/disable seeking by timestamp with -ss
-timestamp time     set the recording timestamp ('now' to set the
                    current time)

Vì vậy, bạn có thể muốn thử:

ffmpeg -i MVI_1348.MOV -ss 4 -t 4 spliced.mp4

Lệnh này sẽ trích xuất 4 giây từ clip đầu vào bắt đầu tại time offset 4 giây vào clip. Bạn có thể dùng ký hiệu ngắn (4 chỉ giây) hoặc dùng đầy đủ hh:mm:ss.mmm. Điều này cho độ chính xác xuống đến một millisecond, nên nhiều hơn đủ cho mọi use case thực tế.

Nối file hơi phức tạp hơn. Về mặt kỹ thuật gọi là concatenation (concat), nó hoạt động khác với tùy chọn cắt. Bạn không chỉ định các phần mong muốn nối trên dòng lệnh, bạn đặt chúng vào một file, dùng ký hiệu rất cụ thể, và đọc file đó với ffmpeg. Ví dụ:

ffmpeg -f concat -i list.txt -codec copy joined.mp4

Nội dung file list.txt sẽ là:

file 'part-1.mp4'
file 'part-2.mp4'
file 'part-3.mp4'

Lưu ý dùng từ file và dấu ngoặc đơn. Bạn có thể dùng cả đường dẫn tuyệt đối và tương đối. Nếu bạn sai format file, bạn sẽ thấy lỗi:

[concat @ 0x555ca89c38c0] Line 1: unknown keyword 'part-1.mp4'
list.txt: Invalid data found when processing input

Nếu bạn thử cung cấp danh sách file trên dòng lệnh (thay vì file text):

part-1.mp4: Invalid data found when processing input

Nhúng và trích xuất phụ đề (Embed and extract subtitles)

Nhớ bài VLC & phụ đề của tôi? Vâng, nếu bạn không bị u ám bởi dòng lệnh, bạn có thể làm cùng việc với ffmpeg. Là ví dụ trivia, giả sử bạn có file âm thanh và phụ đề riêng biệt. Không cần xử lý thêm, bạn chỉ dùng tùy chọn video filter cho việc này:

ffmpeg -i input.avi -vf subtitles=subtitle.srt output.avi

Một use case phức tạp hơn, lệnh bên dưới sẽ lấy file MP4 và phụ đề riêng biệt, và kết hợp chúng vào file output với video transcoding. Tùy chọn -map (xuất hiện hai lần, không phải lỗi) định nghĩa thứ tự luồng sẽ được map vào output. Nhưng sau đó có danh sách codec hơi thông minh và gây nhầm lẫn. Vì chúng ta có nhiều luồng, chúng ta chỉ muốn thao tác phần video - không phải âm thanh hay phụ đề.

Để làm vậy, -c copy chỉ định tất cả codec nên được copy, nhưng dùng -c:v cung cấp override cho tùy chọn này, và luồng video sẽ được transcoded. Vì chúng ta dùng codec libx264, chúng ta cũng dùng Constant Rate Factor (CRF) cho variable bitrate, đặt là 23 (dao động từ lossless 0 đến chất lượng thấp nhất 51) và preset veryfast, tạo output tương đối nhỏ.

ffmpeg -i input.mp4 -i subtitle.srt -map 0 -map 1 -c copy -c:v libx264 -crf 23 -preset veryfast output.mp4

Trích xuất phụ đề có dạng sau:

ffmpeg -txt_format text -i input.file out.srt

Tăng tốc và làm chậm video (Speed up and slow videos)

Đây là use case thú vị khác. Giống như bất kỳ con người nào, bạn có thể muốn lấy bất kỳ video nào, tăng tốc 2x rồi thêm nhạc Benny Hill, và phải có nhiều sự vui vẻ. Bạn cũng có thể làm chậm hành động, và để thêm hấp dẫn, cũng thêm smoothing (làm mượt) để chuỗi chậm không bị giật cục.

Ví dụ, chúng ta có thể có video stop motion - với chỉ 15-20 thumbnail, nó chỉ mất một giây để phát. Vì vậy bạn có thể muốn kéo nó ra thành 5 giây, nhưng điều đó nghĩa là mỗi frame sẽ hiển thị gấp 5 lần lâu. Thay vào đó bạn có thể "chèn" frame thêm để làm nó trông như slo-mo mượt. Chúng ta làm điều này với thư viện thiết kế nội thất hồi xưa. Chúng ta dùng AviSynth và VirtualDub cho tác vụ này.

Bộ lọc tốc độ video hoạt động bằng cách thay đổi presentation timestamp (PTS) của mỗi frame video. Đơn giản, giá trị phân số tăng tốc video, nhân tử lớn hơn 1 làm chậm nó. Khi bạn tăng tốc, ffmpeg sẽ drop frame, nhưng bạn có thể chỉ định framerate cao hơn. Để bảo toàn gốc, bạn có thể nhân FPS trong input với 1/PTS bạn dùng. Vì vậy nếu bạn gấp đôi tốc độ clip 24FPS, bạn nên dùng rate 48FPS.

ffmpeg -i input.mp4 -filter:v "setpts=0.5*PTS" output.mp4

ffmpeg -i input.mp4 -r 96 -filter:v "setpts=0.25*PTS" output.mp4

ffmpeg -i input.mp4 -filter:v "setpts=2*PTS" output.mp4

Làm mượt video phức tạp hơn. Tôi đã phải tham khảo tài liệu. Bản chất, cho video bị làm chậm 5 lần (và dài gấp 5 lần gốc), tôi dùng video interpolation (nội suy) để tạo hiệu ứng smoothing. Ở đây cũng, bạn cần thêm FPS, để ffmpeg có đủ dữ liệu đoán frame ở giữa. Trong ví dụ tôi, làm chậm 5x, bạn cần 5x24 FPS (tốc độ gốc), tức 120 FPS.

ffmpeg -i input.mp4 -filter:v "minterpolate='mi_mode=mci:mc_mode=aobmc:vsbmc=1:fps=120'" output.mp4

Đây là tác vụ tốn CPU, và có thể mất một lúc để xong. Tôi dùng ffplay để preview video, và thấy kết quả hợp lý, nhưng bạn không thể biến không thành có, nên trong khi nó chạy, nó chạy tốt khi lượng dữ liệu thiếu nhỏ (không phải một frame mỗi giây mỗi hai giây hoặc kiểu đó).

Cho âm thanh, bạn có thể dùng atempo. Tùy chọn này có phạm vi 0.5-2.0, nghĩa là nửa hoặc gấp đôi tốc độ tối đa, tuy nhiên, có thể chuỗi nhiều bộ lọc atempo để có thêm thay đổi tốc độ. Giống như ví dụ dưới:

ffmpeg -i input.mp4 -filter:a "atempo=2.0,atempo=2.0" -vn output.mp4

Và điều đó đưa chúng ta đến cuối tutorial này.

Kết luận

Tôi hy vọng bạn thấy hữu ích, thú vị và liên quan. Ffmpeg là con ngựa bataille - không, nó là một toàn bộ kỵ binh - của điều chỉnh âm thanh và video trong Linux, và nó có rất nhiều công cụ, tùy chọn và cấu hình thực tế khiến việc bắt đầu có thể gây nhầm lẫn và thậm chí e ngại. Những cảm xúc đó nên đã bay hơi khi bạn đọc xong hướng dẫn này.

Dù sao, chúng ta nói về chuyển đổi và transcoding, scale và chất lượng, trích xuất hình ảnh, kết hợp và tạo GIF, tách và nối video, trích xuất và nhúng phụ đề, tăng tốc và làm chậm video, và những cái khác. Điều đó sẽ giữ bạn vui vẻ và bận rộn một thời gian. Nếu bạn có bất kỳ yêu cầu hoặc câu hỏi liên quan ffmpeg, cứ phát đi, email chỉ cách một click. Hoặc cái gì đó. Cuối cùng, nếu tutorial này thực sự hữu ích, hãy cho một chút tình yêu ngược lại, vì sao không.

Chúc vui.