3 điểm bởi GN⁺ 2023-07-31 | 1 bình luận | Chia sẻ qua WhatsApp
  • ffmprovisr là một trang hỗ trợ tạo lệnh dành cho người dùng gặp khó khăn khi viết lệnh FFmpeg, nơi họ có thể chọn tác vụ để xem lệnh ví dụ và phần giải thích theo từng cờ
  • Các recipe tập trung vào ffmpeg, ffplay, ffprobe, phân tách và trình bày các thành phần như tệp đầu vào, codec, filter, stream mapping và container đầu ra
  • Phạm vi bao quát khá rộng, từ remux/transcode đến cắt·ghép, phụ đề·watermark, thumbnail·GIF, tệp kiểm thử, metadata·checksum·báo cáo QCTools
  • Dù không có tìm kiếm tích hợp, trang hướng dẫn cách mở toàn bộ recipe rồi dùng tìm kiếm của trình duyệt để tìm từ khóa cần thiết
  • Ngoài FFmpeg, trang còn đề cập đến các công cụ như CDDA ripping, ImageMagick và flac, nên có thể dùng như một bộ sưu tập lệnh thực tế cho quy trình bảo tồn số

ffmprovisr cung cấp gì

  • ffmprovisr cung cấp các lệnh ví dụ theo từng tác vụ cùng phần giải thích tùy chọn, giúp giảm gánh nặng phải tự ghép lệnh FFmpeg
  • Người dùng có thể nhấn nút tác vụ để chuyển đến một lệnh đơn hoặc danh sách các lệnh liên quan, rồi xem lệnh mẫu và cách hoạt động của từng cờ
  • Bản thân trang không có chức năng tìm kiếm, và hướng dẫn mở tất cả recipe rồi dùng ctrl+f hoặc cmd+f để tìm bằng trình duyệt
  • Tài liệu tham khảo cơ bản được liên kết gồm trang web chính thức của FFmpeg, installation instructions của Reto Kromer, Command Line Crash Course, và explainshell.com
  • Giấy phép là Creative Commons Attribution 4.0 International License

Cách cơ bản để đọc lệnh FFmpeg

  • Sau khi cài đặt, FFmpeg được gọi bằng cách nhập ffmpeg trong command prompt
  • Lệnh thường được cấu thành từ các cặp cờ và giá trị
    • Trong -i input_file.ext, -i là cờ chỉ định tệp đầu vào, còn input_file.ext là tệp mục tiêu
    • Trong -c:v prores, -c:v là cờ chỉ định mã hóa stream video, còn prores là codec sẽ dùng
  • Tên tệp đầu ra nằm ở cuối lệnh và được chỉ định bằng chính tên tệp, không cần cờ đầu ra riêng
  • ffmpeg lưu video, còn ffplay có thể phát video được tạo ra mà không lưu lại
    • Ví dụ lưu SMPTE bars là ffmpeg -f lavfi -i smptebars=size=640x480 -t 5 output_file
    • Ví dụ phát SMPTE bars là ffplay -f lavfi smptebars=size=640x480
    • Ví dụ FFmpeg cần -i, thời lượng ghi -t 5 và tệp đầu ra, nhưng ví dụ FFplay không cần -i

Các điểm kiểm tra để giảm lỗi

  • Cần xác nhận tệp đầu ra có mở được, phát được và hiển thị/phát âm thanh đúng như mong muốn hay không
  • Phần mở rộng đầu ra phải khớp với codec dự định dùng, và một số phần mở rộng sẽ dẫn đến codec mặc định cụ thể trong FFmpeg
    • Ví dụ, .mp4 có thể được mặc định thiết lập thành mã hóa H.264
  • "Error: No such file or directory" có thể xuất hiện do sai thư mục, lỗi gõ, thiếu khoảng trắng hoặc gắn cờ sai chỗ
    • Trên macOS, có thể dùng cd $HOME/Downloads để chuyển vào thư mục Downloads
    • Nếu lệnh sao chép-dán trông vẫn đúng nhưng vẫn lỗi, nên thử gõ lại trực tiếp trên dòng lệnh
  • "Could not find tag for codec" xuất hiện khi cố remux một tệp có codec audio/video không tương thích với phần mở rộng đầu ra
    • Có thể transcode trước sang codec phù hợp, hoặc bỏ -c copy nếu chắc chắn phần mở rộng sẽ tự động mã hóa bằng codec đúng
  • "Killed" có thể xuất hiện khi tệp vượt quá dung lượng bộ nhớ của máy chủ
    • Trên máy chủ từ xa, có thể khắc phục bằng cách tăng dung lượng bộ nhớ
    • Trên máy chủ cục bộ, nên giữ FFmpeg ở phiên bản mới nhất và tránh chạy đồng thời với các chương trình khác dùng nhiều bộ nhớ
  • Nếu đang dùng filter mà gặp "Error splitting argument list: option not found", cần kiểm tra việc dùng dấu ngoặc kép và định dạng filtergraph
  • Filter yêu cầu mã hóa lại stream, nên có thể phát sinh vấn đề nếu dùng cùng -c copy, vốn sao chép trực tiếp stream của tệp

Filtergraph, stream mapping và codec mặc định

  • Khi chạy tác vụ batch FFmpeg trong vòng lặp, có thể đặt -nostdin trước đầu vào để ghi đè hành vi mặc định tương tác qua standard input
    • Ví dụ: ffmpeg -nostdin -i input_file ...
  • FFmpeg tự động thiết lập codec và tham số codec mặc định theo định dạng tệp đầu ra
    • .avi: audio mp3, video mpeg4
    • .mkv: audio ac3, video H.264
    • .mov: audio AAC, video H.264
    • .mp4: audio AAC, video H.264
    • .mpg: audio mp2, video mpeg1video
    • .mxf: audio pcm_s16le, video mpeg2video
    • .wav: audio pcm_s16le
  • Filtergraph là tổ hợp tên filter và tùy chọn đứng sau -vf hoặc -af
    • -vf là bí danh của -filter:v
    • Ví dụ filter video là hflip, ví dụ filter audio là amerge
    • Nhiều filter được nối bằng dấu phẩy, còn nhiều chuỗi filter được phân tách bằng dấu chấm phẩy
    • -vf "fieldmatch,yadif,decimate" là một chuỗi filter dùng cho xử lý inverse telecine
    • Nếu có nhiều hơn một đầu vào hoặc đầu ra, cần dùng -filter_complex thay cho -vf
    • Phải dùng dấu ngoặc kép thẳng, tránh dùng dấu ngoặc kép cong
  • Stream mapping xác định những stream nào trong tệp đầu vào như video, audio, phụ đề, dữ liệu và tệp đính kèm sẽ được đưa vào đầu ra
    • FFmpeg nhận diện các loại stream a, v, s, d, t
    • -map 0:v chọn toàn bộ stream video của tệp đầu vào thứ nhất
    • -map 0:3 chọn stream thứ tư của tệp đầu vào thứ nhất
    • -map 0:a:2 chọn stream audio thứ ba của tệp đầu vào thứ nhất
    • Nếu không chỉ định mapping, mặc định với tệp video là chỉ lấy 1 video và 1 audio sang đầu ra
    • Để map toàn bộ stream, dùng -map 0
    • Nếu thêm ? như -map 0:a?, quá trình batch vẫn có thể tiếp tục mà không lỗi với các tệp không có audio

Thay đổi container và chuyển mã

  • Có thể remux tệp bằng ffmpeg -i input_file.ext -c copy -map 0 output_file.ext
    • Chuyển sang định dạng container khác mà không thay đổi dữ liệu video, âm thanh, phụ đề bên trong
    • Remux còn được gọi là remuxing hoặc re-multiplexing
    • Cần dùng -map 0 để giữ lại mọi stream như nhiều track âm thanh
    • Một số container chỉ chứa được các kiểu mã hóa stream nhất định, nên có thể không remux được nếu không tái mã hóa
  • Tạo Broadcast WAV bằng -write_bext 1-metadata field_name='Content' để ghi BEXT chunk và metadata liên quan
    • Các trường thường dùng là description, originator, originator_reference, origination_date, origination_time, coding_history, IARL
    • Các trường metadata BWF có giới hạn số ký tự, và OriginatorReference tối đa 32 ký tự
  • Khi remux video codec DV sang tệp .dv, dùng -f rawvideo -c:v copy để tránh việc metadata nguồn trong stream DV bị xóa ngoài ý muốn
  • Ví dụ chuyển mã sang Apple ProRes LT là -c:v prores -profile:v 1 -vf yadif -c:a pcm_s16le
    • Hồ sơ ProRes 422 được phân thành 0 Proxy, 1 LT, 2 Standard, 3 HQ
    • Container ProRes được FFmpeg hỗ trợ gồm QuickTime .mov, Matroska .mkv, MXF .mxf
  • Ví dụ chuyển mã H.264 là -c:v libx264 -pix_fmt yuv420p -c:a aac
    • Mặc định của libx264 là preset medium và CRF 23
    • -pix_fmt yuv420p chỉ định chroma subsampling 4:2:0 để tương thích với QuickTime và phần lớn trình phát không dựa trên FFmpeg
    • Để tối ưu cho streaming, thêm -movflags +faststart
    • Ví dụ chất lượng cao hơn là -preset veryslow -crf 18, và CRF 18 thường được xem là “gần như không suy hao về mặt thị giác”
  • Mã hóa H.264/H.265 dựa trên GPU Nvidia dùng h264_nvenc hoặc hevc_nvenc
    • Phần cứng chức năng cố định của Nvidia có thể nhanh gấp 10 lần mã hóa bằng CPU, nhưng để tối ưu chất lượng ở bitrate thấp thì cần nhiều tham số hơn
    • HEVC được mô tả là codec hiệu quả hơn, được GPU hỗ trợ từ khoảng sau năm 2015
  • Chuyển mã H.265/HEVC dùng -c:v libx265 -pix_fmt yuv420p -c:a copy
    • Mặc định của libx265 là preset medium và CRF 28
    • CRF 28 của H.265 tương ứng với CRF 23 của H.264, và kích thước tệp có thể chỉ còn khoảng một nửa
  • Ví dụ lossless để lưu trữ là lệnh đưa FFV1 Version 3 vào container Matroska và đồng thời tạo framemd5 cho đầu vào
    • -map 0 ánh xạ mọi stream
    • -dn loại bỏ các data stream mà Matroska không cho phép
    • -slicecrc 1 thêm thông tin CRC để decoder có thể phát hiện các slice bị hỏng
    • -f framemd5 -an tạo checksum MD5 cho từng khung hình video

Thay đổi thuộc tính hình ảnh và âm thanh

  • Công thức thay đổi tỷ lệ khung hình dùng bộ lọc padding
    • Khi chuyển 4:3 sang 16:9 thì áp dụng pillarbox
    • Khi chuyển 16:9 sang 4:3 thì áp dụng letterbox
    • Với video không có tiếng, có thể dùng -an thay cho -c:a copy
  • Ví dụ chuyển SD sang HD dùng ba bộ lọc colormatrix=bt601:bt709, scale=1440:1080:flags=lanczos, pad=1920:1080:240:0
    • Thay đổi hệ số độ chói từ Rec. 601 sang Rec. 709
    • Lanczos scaling chậm hơn bilinear mặc định nhưng cho kết quả tốt hơn
    • Với nguồn interlaced, hướng dẫn dùng yadif để deinterlace trước khi scale
  • Có thể thay đổi tỷ lệ hiển thị ở cấp container bằng tùy chọn như -aspect 4:3
    • Khi dùng cùng -c:v copy, nó tác động đến tỷ lệ khung hình được lưu trong container chứ không phải tỷ lệ trong các khung hình đã mã hóa
  • Chuyển đổi không gian màu dùng bộ lọc colormatrix=src:dst
    • Các giá trị cho phép gồm bt601, smpte170m, bt470bg, bt709, bt2020
    • Nhúng metadata không gian màu dùng -color_primaries, -color_trc, -colorspace
    • Cần cẩn thận vì cũng có thể gắn thẻ Rec.709 cho tệp thực chất là Rec.601
    • Các thẻ metadata được libx264 hoặc libx265 ghi, nên không thể thêm nếu không tái mã hóa
  • Thay đổi tốc độ dùng kết hợp setptsatempo
    • Ví dụ là tạo một bản sao theo cách tiếp cận PAL, đổi 24fps thành 25fps mà vẫn giữ nguyên cao độ âm thanh
  • Xử lý fade dùng các bộ lọc fadeafade, và vì có dùng filter nên phải tái mã hóa video và âm thanh
  • Trích xuất âm thanh dùng -c:a copy -vn để lấy stream âm thanh không suy hao mà không có video
  • Gộp hai track âm thanh dùng amerge-filter_complex
    • Có thể hữu ích cho các quy trình xử lý tiếp theo chỉ mong đợi một track âm thanh, như phụ đề tự động của YouTube
    • Khuyến nghị chạy ffprobe trước khi viết script để xác định đúng track mong muốn
  • Phân tích và chuẩn hóa âm lượng dùng bộ lọc loudnorm
    • Đầu ra JSON có thể dùng làm giá trị đầu vào cho chuẩn hóa 2-pass
    • Mặc định được mô tả là khá khớp với mức âm lượng mục tiêu do PBS khuyến nghị
    • 1-pass nhanh hơn nhưng kém chính xác hơn 2-pass
  • Cũng bao gồm các công thức cho CD pre-emphasis, RIAA equalization, resampling âm thanh, và diễn giải cưỡng bức WAV 192kHz thành 96kHz

Cắt, nối, phân đoạn

  • Khi nối các tệp có cùng thông số kỹ thuật, dùng concat demuxer
    • ffmpeg -f concat -i mylist.txt -c copy output_file
    • Các tệp cần ghép phải có cùng codec và thông số kỹ thuật, và bắt buộc phải xem trước tệp kết quả
    • Muốn dùng đường dẫn tuyệt đối thì thêm -safe 0
  • Khi nối các tệp có định dạng hoặc codec khác nhau, dùng bộ lọc concat-filter_complex
    • Các tệp đầu vào có thể khác nhau về container, codec, chroma subsampling, framerate, v.v.
    • Ví dụ cơ bản chỉ hoạt động đúng khi cùng độ phân giải
    • Nếu framerate khác nhau thì đầu ra có thể trở thành variable framerate
    • Nếu độ phân giải khác nhau thì căn bằng scale trước khi concat, và khi ghép SD với HD có thể xử lý SD bằng pillarbox
  • Chia tệp được xử lý bằng segment muxer
    • -segment_time 60 tạo các segment tối đa 60 giây
    • %03d tạo tên tệp bằng số có đệm 0 đủ 3 chữ số
  • Cắt không tái mã hóa dùng -ss, -to, -t, -c copy, -map 0
    • Các codec liên khung như H.264 có thể bắt đầu ở điểm gần nhất theo i-frame
    • -sseof -5 là cách sao chép từ 5 giây trước cuối tệp
  • Loại bỏ im lặng ở đầu tệp âm thanh dùng silenceremove=start_threshold=-57dB:start_duration=1:start_periods=1
    • -57dB được đưa ra như mức phù hợp để tính đến nhiễu hiss analog
    • Vì dùng filter nên âm thanh sẽ được tái mã hóa
  • Loại bỏ im lặng ở cuối tệp âm thanh được xử lý theo thứ tự areverse, silenceremove, areverse
    • silenceremove phù hợp hơn để loại bỏ im lặng ở phần đầu nên âm thanh được đảo ngược rồi đảo lại

Xử lý video interlace

  • Khi tạo tệp truy cập HD H.264 từ nguồn SD NTSC, thường dùng kết hợp yadif, scale, pad, format=yuv420p
    • yadif là bộ lọc khử đan xen
    • scale=1440:1080:flags=lanczos điều chỉnh hình ảnh về 1440x1080
    • pad=1920:1080:(ow-iw)/2:(oh-ih)/2 thêm đệm để đầu vào 4:3 khớp với khung đầu ra 16:9
  • Ví dụ khử đan xen thông thường là -vf "yadif,format=yuv420p"
    • format=yuv420p chỉ định chroma subsampling 4:2:0 để tương thích phát lại H.264
    • Ngoài yadif, FFmpeg còn có các deinterlacer bwdif, w3fdif, kerndeint, nnedi
  • Khử đan xen bằng cách tách field thành frame dùng idet,bwdif,format=yuv420p
    • Được ưa dùng để giữ nguyên cadence hình ảnh của nguồn trong video interlace có nhiều chuyển động
    • idet phát hiện thứ tự field
    • bwdif mặc định xuất ra một frame cho mỗi field
  • Inverse telecine dùng fieldmatch,yadif,decimate
    • Hoàn tác 3:2 pulldown để khôi phục video interlace 29.97fps về tốc độ khung hình 24fps của nguồn phim gốc
    • Khi áp dụng cho tệp 29.97i, tốc độ khung hình đầu ra thực tế sẽ là 23.976fps
  • Thay đổi thứ tự field dùng setfield=tff hoặc setfield=bff
    • Vì dùng bộ lọc video nên không thể dùng -c copy và cần mã hóa lại
  • Có thể kiểm tra mẫu interlace bằng ffmpeg -i input_file -filter:v idet -f null - để phân tích mà không tạo tệp đầu ra

Watermark, phụ đề, thumbnail, GIF

  • Watermark văn bản được tạo bằng bộ lọc drawtext
    • Chỉ định các tùy chọn fontfile, fontsize, text, fontcolor, alpha, x, y
    • x=(w-text_w)/2:y=(h-text_h)/2 đặt ở giữa bất kể kích thước video
  • Watermark hình ảnh có thể đặt ở góc trên bên phải bằng overlay=main_w-overlay_w-5:5
  • Timecode burn-in dùng các tùy chọn timecode, box, boxcolor, rate của drawtext
    • Timecode bắt đầu có định dạng hh:mm:ss[:;.]ff
  • Nhúng tệp phụ đề dùng -i subtitles_file -c copy -c:s mov_text
    • mov_text hoạt động trong container MP4 và MOV
    • Các định dạng được chấp nhận trong container MKV là ASS, SRT, SSA
  • Có thể trích một thumbnail bằng -ss 00:00:20 -vframes 1 thumb.png
  • Để tạo thumbnail mỗi phút, dùng -vf fps=1/60 out%d.png
  • Khi tạo GIF từ chuỗi ảnh, dùng image2, -framerate, -pattern_type glob, scale
  • GIF chất lượng cao được tạo theo hai bước
    • Lệnh đầu tiên tạo palette tùy chỉnh bằng palettegen
    • Lệnh thứ hai áp dụng palette bằng paletteuse
    • Cách đơn giản hơn là dùng -vf "fps=10,scale=500:-1", nhưng dithering sẽ dễ thấy hơn và kích thước tệp nhỏ hơn

Chuỗi ảnh, scope, OCR

  • Khi tạo video không nén 10-bit từ chuỗi ảnh, dùng -f image2 -framerate 24 -i input_file_%06d.ext -c:v v210
    • Tốc độ khung hình mặc định của demuxer image2 là 25fps
    • %06d đọc tên tệp số có sáu chữ số theo thứ tự tăng dần
  • Khi kết hợp tệp ảnh và âm thanh để tạo video, dùng -loop 1, -shortest, -vf scale=1280:720
    • Có thể hữu ích khi muốn tải tệp âm thanh lên các nền tảng như YouTube
  • Có thể dùng ffplay -f lavfi và bộ lọc để trực quan hóa bit depth âm thanh, đồ thị decibel, hiển thị pixel ngoài dải phát sóng và vectorscope
  • tblend=all_mode=difference128hstack hiển thị song song khác biệt theo thời gian giữa hai video đầu vào
  • xstack được dùng để tạo cửa sổ đầu ra xếp nhiều nguồn video theo chiều dọc hoặc chiều ngang, hữu ích cho mục đích tương tự cửa sổ đầu ra dùng trong vrecord
  • Ví dụ OCR dùng bộ lọc ocrdrawtext để hiển thị văn bản được nhận diện lên trên video
  • Xuất dữ liệu OCR ra màn hình có dạng ffprobe -show_entries frame_tags=lavfi.ocr.text -f lavfi -i "movie=input_file,ocr"

Metadata, checksum, công việc bảo tồn

  • Trích xuất metadata kỹ thuật được thực hiện bằng ffprobe -i input_file -show_format -show_streams -show_data -print_format xml
    • Ngoài XML, định dạng đầu ra cũng có thể là JSON hoặc flat
  • Xóa metadata dùng -map_metadata -1 -c:v copy -c:a copy
    • Sao chép video và âm thanh nhưng không sao chép metadata
  • Xử lý hàng loạt trong Bash được thực hiện bằng tệp .sh và vòng lặp for
    • Ví dụ: for file in *.mxf; do ffmpeg -i "$file" -map 0 -c copy "${file%.mxf}.mov"; done
    • Tệp .sh và các tệp .mxf cần xử lý phải ở cùng thư mục và phải chạy trong chính thư mục đó
    • Với xử lý đệ quy, có thể dùng find input_directory -iname "*.mxf" -exec ffmpeg -i {} -map 0 -c copy {}.mov \;
  • Trên Windows, xử lý hàng loạt được thực hiện bằng script PowerShell .ps1
    • Ví dụ tạo danh sách tệp .mp4 và đổi phần mở rộng từng tệp thành .mkv để remux
    • Muốn gọi ffmpeg mà không cần đường dẫn đầy đủ thì phải cấu hình đúng
  • Kiểm tra lỗi decoder bằng ffmpeg -i input_file -f null - để giải mã mà không tạo tệp đầu ra và in lỗi ra màn hình
  • Kiểm tra fixity của FFV1 Version 3 bằng -report -i input_file -f null - để xác nhận CRC checksum mismatch
    • Frame CRC được bật mặc định trong FFV1 Version 3
  • MD5 video theo từng frame được tạo bằng -f framemd5 -an
  • MD5 theo từng nhóm mẫu âm thanh được tạo bằng asetnsamples=n=48000 -f framemd5 -vn
    • Được khuyến nghị nên khớp số nhóm mẫu với sample rate của media
    • Mặc định âm thanh sẽ được transcoding sang PCM 16-bit để tạo framemd5
  • MD5 của stream có thể được tạo bằng cách -map riêng từng stream video và âm thanh rồi dùng -c copy -f md5
    • Dùng để xác minh tính toàn vẹn của thông tin A/V độc lập với thay đổi metadata của container
  • streamhash xuất hash theo từng stream cho mọi stream
    • Hữu ích khi băm mixed born-digital material vì không cần biết có bao nhiêu stream
  • Báo cáo QCTools tạo .qctools.xml.gz bằng ffprobe -f lavfi cùng với signalstats, cropdetect, idet, psnr, ssim, ebur128, astats và các bộ lọc khác
    • Có các lệnh riêng cho tệp có âm thanh và tệp không có âm thanh
  • Trích xuất closed caption EIA-608 Line 21 dùng bộ lọc readeia608ffprobe để xuất giá trị hex ra CSV

Tệp kiểm thử và các ví dụ FFmpeg khác

  • Video kiểm thử được tạo hoặc phát bằng đầu vào lavfi như mandelbrot, smptebars, testsrc, smptehdbars
    • Ví dụ Mandelbrot xuất H.264 1280x720, 25fps, dài 10 giây
    • Ví dụ SMPTE bars xuất ProRes 720x576, 25fps, dài 10 giây
    • Phát HD SMPTE bars bằng ffplay -f lavfi -i smptehdbars=size=1920x1080
    • Phát VGA SMPTE bars bằng ffplay -f lavfi -i smptebars=size=640x480
  • Âm thanh kiểm thử sóng sin tạo tệp WAV bằng sine=frequency=1000:sample_rate=48000:duration=5pcm_s16le
  • Video kiểm thử kết hợp SMPTE bars và sóng sin 1kHz dùng hai đầu vào lavfi cùng -c:v ffv1, -c:a pcm_s16le
  • Tệp kiểm thử bị hỏng cố ý làm hỏng nội dung gói bằng -bsf noise=1 -c copy nhưng không làm hỏng container
  • Conway's Game of Life được mô phỏng bằng ffplay -f lavfi life=..., và có thể lưu một đoạn bằng ffmpeg cùng -t 5
  • So sánh độ tương đồng cảm nhận của hai video dùng bộ lọc signature=detectmode=full:nb_inputs=2
  • Hàm băm cảm nhận của video đầu vào tạo tệp XML bằng signature=format=xml:filename="output.xml"
  • Chuỗi ảnh có thể phát trực tiếp mà không cần tạo video bằng ffplay -framerate 5 input_file_%06d.ext
  • Tách track âm thanh và video dùng -map 0:v:0-map 0:a:0
  • Gộp track âm thanh và video bằng -map 0:v -map 1:a -c copy, kết hợp video của tệp thứ nhất với âm thanh của tệp thứ hai
  • Tệp MPEG để tạo ISO dùng cho truy cập DVD được tạo bằng -aspect 4:3 -target ntsc-dvd output_file.mpg, và cần cài dvdauthor
  • CSV để phát hiện cảnh dựa trên YDIF xuất giá trị lavfi.signalstats.YDIF từ ffprobesignalstats
  • Có thể che head switching noise bằng cách vẽ một hộp đen ở đáy khung hình với drawbox=w=iw:h=7:y=ih-h:t=max
  • Để vừa livestream tới đích RTMP vừa ghi MP4 cục bộ cùng lúc, dùng muxer tee
    • Scale đầu vào về chiều rộng 1280px, và kết thúc stream sau thời gian chỉ định
    • Ví dụ có kèm ghi chú rằng đã được dùng hằng ngày để livestream chương trình TV thực tế trong khoảng 4 năm
  • Có thể xem thông tin về decoder, encoder, demuxer, muxer, filter cụ thể bằng ffmpeg -h type=name
    • Ví dụ gồm encoder=libx264, decoder=mp3, muxer=matroska, demuxer=mov, filter=crop

Các công cụ liên quan được giới thiệu cùng FFmpeg

  • Công cụ rip CDDA đề cập đến việc kiểm tra offset ổ CD và rip audio CD chính xác
    • Các mẫu ổ CD khác nhau có vị trí bắt đầu đọc khác nhau, nên cần hiệu chỉnh offset để xác minh checksum của cùng một nội dung
    • Có thể nhận diện ổ bằng cdda2wav -scanbus, cdda2wav, cdparanoia -vsQ
    • Tìm offset tại Accurate Rip CD drive offset list
    • Công cụ GUI cho macOS được giới thiệu là XLD
  • Rip bằng CD Paranoia dùng cdparanoia -L -B -O [Drive Offset] [Starting Track Number]-[Ending Track Number] output_file.wav
    • -B là chế độ batch tự động tách track thành các tệp riêng
  • Cdda2wav là công cụ rip audio CD chính xác sử dụng Paranoia library
    • Lệnh cài bằng Homebrew là brew install cdrtools
    • Lệnh ví dụ rip toàn bộ CD thành một WAV, tra cứu CDDB và tạo cue sheet
    • Trên macOS phải unmount CD trước khi chạy lệnh
  • CD emphasis được mô tả là phương thức giảm nhiễu có thể ảnh hưởng đến một số CD đầu thập niên 1980 và CD được ép tại Nhật
    • Có thể kiểm tra sự hiện diện bằng cdda2wav -J hoặc cdparanoia -Q
    • Để hiệu chỉnh trong lúc rip bằng Cdda2wav, thêm cờ -T
  • ImageMagick là bộ phần mềm mã nguồn mở miễn phí để hiển thị, chuyển đổi và chỉnh sửa tệp ảnh raster và vector
    • Các lệnh được gọi riêng lẻ như convert, montage, mogrify
    • So sánh ảnh bằng compare -metric ae image1.ext image2.ext null: để trả về số pixel khác nhau
    • Tạo thumbnail bằng mogrify -resize 80x80 -format jpg -quality 75 -path thumbs *.jpg
    • Lưới ảnh được tạo bằng montage @list.txt -tile 6x12 -geometry +0+0 output_grid.jpg
    • Xóa EXIF dùng mogrify -path ./stripped/ -strip *.jpg
  • Công cụ flac là công cụ chuyển mã FLAC và thao tác metadata do dự án FLAC tạo ra
    • Ưu điểm so với công cụ khác là có thể nhúng foreign metadata như BWF
    • Để chuyển từ WAV sang FLAC và giữ metadata BWF, dùng flac --best --keep-foreign-metadata --preserve-modtime --verify input.wav
    • Để tái dựng BWF gốc từ FLAC, dùng --decode thay cho --best

1 bình luận

 
GN⁺ 2023-07-31
Ý kiến trên Hacker News
  • Hơi lạc đề một chút, nhưng tôi cho rằng ffmpeg là một trong những phần mềm xuất sắc nhất từng được tạo ra
    Những kỹ sư tài năng như Fabrice Bellard là món quà lớn cho cộng đồng FOSS, và ngay cả ở một kỳ lân trị giá khoảng 2 tỷ USD nơi tôi từng làm việc, một phần lớn sản phẩm cũng phụ thuộc vào ffmpeg

    • Vậy chắc họ đã quyên góp một khoản khá lớn nhỉ?
      https://ffmpeg.org/donations.html
    • Không phải “Fabian Fabrice” mà là Fabrice Bellard
      Ông cũng là người tạo ra QEMU, TCC, QuickJS, v.v.
    • Không có ai giống ông ấy cả. Không ai cùng đẳng cấp với Fabrice Bellard, và có vẻ ngay từ đầu cũng chẳng có ai đang chơi cùng một cuộc chơi :-)
      Nói nghiêm túc thì tại bất kỳ thời điểm nào, số thiết bị đang chạy mã do ông viết thực sự nhiều đến mức khó tin
    • Nhân tiện, “FF” trong “FFmpeg” nghĩa là “fast forward”
    • Tôi thích ffmpeg, nhưng hiệu năng trên ARM cần được cải thiện
  • Dòng lệnh ffmpeg, dù xem các hướng dẫn tốt, vẫn khiến người ta muốn vò đầu bứt tóc, nên tôi muốn khuyên dùng VapourSynth
    https://www.vapoursynth.com/
    Đây là công cụ lọc video kiểu Python đã được tối ưu hóa, nhưng còn nhiều hơn thế nữa: https://vsdb.top/
    Và StaxRip tận dụng rất tốt ffmpeg, VapourSynth, cùng hàng chục encoder và công cụ khác; vì nó mà tôi thậm chí còn phải khởi động lại từ Linux sang Windows: https://github.com/staxrip/staxrip

    • Chỉ cần có một wrapper cho ffmpeg với giao diện dòng lệnh tốt hơn thôi cũng đã tuyệt lắm rồi
      Nó phức tạp một cách không cần thiết; xét từ một góc độ nào đó thì cấu trúc đó có thể đều hợp lý, nhưng việc phải biết các tùy chọn như thần chú để làm những tác vụ rất phổ biến là không ổn
      Chắc tôi có hàng chục alias bash rút một lệnh ffmpeg dài 150 ký tự xuống còn hai từ
      ffprobe cũng vô lý: 99% trường hợp là chạy không đối số để nhanh chóng xem độ dài, độ phân giải, frame rate, số track audio, nhưng 99% output lại là những thứ hoàn toàn không liên quan như tùy chọn biên dịch
  • Một số tài liệu đáng xem thêm:
    https://ffmpeg.guide/ — tạo nhanh và chính xác các filter graph FFmpeg phức tạp
    https://www.hadet.dev/ffmpeg-cheatsheet/ — cắt, thêm fade in/out, scale, nối video, v.v.

    • Theo kinh nghiệm của tôi, lệnh cắt ở liên kết thứ hai không lý tưởng
      Không rõ vì sao ffmpeg hoạt động khác nhau tùy việc đặt các flag -ss-t/-to trước hay sau -i, và trong trường hợp của tôi đặt trước thì chạy tốt hơn
      Bản gốc cũng có cùng vấn đề
    • ffmpeg.guide trông rất tuyệt, nhưng tôi vẫn cảm thấy bản thân ffmpeg cần có thứ gì đó tốt hơn
      Việc ép một graph phi tuyến vào một dòng lệnh phẳng và tuyến tính thật kỳ quặc
      Chỉ cần có cấu hình JSON chi tiết hơn thôi cũng đã tốt hơn nhiều
    • ffmpeg.guide thật sự rất hay. ImageMagick có thứ gì tương tự không?
    • Cứ dùng ffmpeg-python là được
  • Rất hữu ích
    Tôi đã bắt đầu dùng ChatGPT để tạo lệnh ffmpeg, và việc tìm thứ mình cần nhanh hơn, dễ hơn nhiều
    Tôi cũng làm một công cụ nhỏ để dùng trực tiếp từ dòng lệnh: https://github.com/alexkrkn/help-cli
    Tôi cũng làm video liên quan: https://www.youtube.com/watch?v=pOda6TDBqcY

  • Gần đây khi tìm UI cho ffmpeg, tôi phát hiện Shutter Encoder; đây là phần mềm rất tốt, mã nguồn mở và hỗ trợ mac/windows
    Cuối cùng tôi đã bắt đầu nén bộ sưu tập video cá nhân 300GB trong 15 năm qua
    https://www.shutterencoder.com/
    Tôi đang nén tất cả sang H.265, và đôi khi kích thước video giảm xuống còn 1/10. Có lý do nào không nên làm vậy không? Tôi có đọc rằng phát video đã nén sẽ cần nhiều năng lực xử lý hơn, nhưng không rõ liệu về sau có thành vấn đề lớn không

    • Tôi đã thử áp dụng tự động cho một bộ sưu tập video lớn, và dù video thử nghiệm trông ổn, thiết lập CRF lại chưa đủ tốt nên chất lượng thấp hơn kỳ vọng
      Hãy xem đó là lời cảnh báo rằng nên kiểm tra nhiều video trước khi xóa bản gốc
      Dù vậy, nếu chỉ 300GB thì lưu trữ đủ rẻ, cứ giữ bản gốc cũng được
    • Một lý do tôi vẫn chọn H.264 là nhiều phần cứng cũ hoặc giá rẻ không có giải mã phần cứng H.265
      Ngoài ra, với homelab của tôi, dùng Plex mà không cần transcoding thì cách đó cũng dễ hơn
  • Hướng dẫn này khuyên dùng yadif làm filter deinterlace, nhưng với mắt tôi thì w3fdif trông tốt hơn
    Nó không theo dõi chuyển động như yadif nên khá nhanh, và tránh được các artifact khó chịu mà theo dõi chuyển động đôi khi tạo ra
    Tôi cho rằng kết quả nhất quán ở mức tàm tạm vẫn tốt hơn lúc thì xuất sắc, lúc thì tệ
    Tuy nhiên, khác với yadif chỉ nhìn hai field, w3fdif xét ba field cùng lúc nên che giấu artifact interlacing tốt hơn

    • Có bản mở rộng của nó: https://github.com/HomeOfVapourSynthEvolution/VapourSynth-Bw...
      Dù sao nếu đã re-encode thì dùng hẳn QTGMC còn tốt hơn
    • Như đã nói ở trên, w3fdif phần lớn đã được thay thế bằng bwdif
      w3fdif có thể tạo hiện tượng nhấp nháy còn yadif thì không, nên bwdif hoạt động giống yadif nhưng dùng khả năng khớp field tốt hơn của w3fdif
    • bwdifhybrid giữa yadifw3fdif
  • Rào cản lớn nhất khi tiếp cận ffmpeg có lẽ là các công cụ freemium ngoại tuyến và các frontend web
    Các trang web đã tối ưu SEO cho những cụm từ mọi người thường gõ vào Google như “avi to mp4”, “mp3 to wav”
    Mất nhiều thời gian hơn tôi tưởng để chấp nhận ứng dụng dòng lệnh, vì thế giới Windows đã dạy rằng mọi thứ đều phải có GUI

    • Tôi từng nghĩ phần lớn các trang chuyển đổi tệp kiểu đó có cấu trúc đặt ffmpeg lên trên thứ gì đó như nginx
  • Mọi người nói ffmpeg phức tạp, nhưng ngay cả khi làm thành GUI đẹp thì cũng không dễ hơn mấy. Thứ phức tạp là bản thân việc nén video
    Nếu không phải kiểu giao diện bấm chọn như HandBrake, nơi phần mềm quyết định thay bạn, thì có lẽ chẳng phần mềm nào có thể làm nó dễ hơn
    Tôi không chắc, nhưng sau khi học đủ chi tiết về mã hóa và nén video số, có lẽ việc phải làm gì trong ffmpeg cũng sẽ trở nên khá trực quan. Có ai thực sự đã thử làm vậy chưa?

    • Khoảng 17 năm trước tôi từng viết bộ lọc DirectShow cho WindowsMobile nên cũng hiểu khá rõ về codec và container
      Khi đó chưa có các định dạng như mkv hay codec như HEVC, nhưng khái niệm thao tác audio/video thông qua nhiều bộ lọc là rất hay, và hầu hết phần mềm chuyển đổi A/V đều hoạt động theo cách đó
      Khi bắt đầu xem trang manual của FFmpeg, tôi thấy được các mối liên hệ, và sau khoảng một ngày vọc thử thì đã có thể dùng được
      Có thể việc tôi thích dòng lệnh và hay đọc trang man đã giúp ích
  • ffmpeg mạnh nên tôi dùng thường xuyên, nhưng cấu trúc API vẫn không vào đầu được. Giá mà có một frontend LLM thì tốt

  • Ý tưởng hay. Bắt FFmpeg làm đúng việc mình muốn luôn là chuyện khá áp lực
    ChatGPT có giúp ích, nhưng không hoàn hảo

    • Nhờ ChatGPT, việc dùng đối số và tùy chọn của nhiều công cụ dòng lệnh đã dễ hơn nhiều
      Tôi luôn thấy khó nhớ các tùy chọn và đối số của OpenSSL, giờ thì chỉ dùng GPT
    • Nhờ ChatGPT, ffmpeg thực sự trở nên dễ tiếp cận hơn
      Tuy vậy, các khác biệt tinh tế giữa từng hệ điều hành vẫn còn là một vấn đề nhỏ