Trang chủ Kiến thức cơ bản

FFmpeg là gì? Cách xem video trên trình phát media cũ bằng FFmpeg

FFmpeg là gì? Bài viết sau sẽ giải thích FFmpeg là gì và hướng dẫn bạn cách xem video trên trình phát media cũ bằng FFmpeg.

FFmpeg là gì?

FFmpeg là một bộ mã nguồn mở và miễn phí, bao gồm các thư viện và chương trình để xử lý video, âm thanh, các file và luồng media.

Trên thực tế, người dùng sử dụng một ffmpeg thực thi duy nhất, thông qua rất nhiều kiểu chuyển đổi (hợp lý và nhất quán) để thực hiện các thao tác trên các file media.

FFmpeg có thể được liên kết với Libav, một nhánh mã nguồn hoạt động rất hiệu quả trong quá khứ, nhưng có vẻ như đã khai tử ở hiện tại.

Cách xử lý video trên FFmpeg

Trong kỳ nghỉ vừa qua, tôi muốn xem một số phim hoạt hình rất cũ trên máy nghe nhạc kỹ thuật số.

Trình phát đã rất cũ và không thể xử lý tập tin video (MP4 hiện đại). Do đó, đây là một dịp tốt để thực hiện cách xử lý và chuyển đổi FFmpeg.

Đôi khi bạn bị đặt vào tình huống phải xem những video ở những định dạng hiện đại ngày nay trên những phương tiện media rất cũ. Bài đăng này sẽ cung cấp một cái nhìn tổng quan về các công cụ mà FFmpeg cung cấp, cho thấy việc thực hiện chuyển đổi video/âm thanh dễ dàng như thế nào chỉ với một vài thao tác.

Tôi cũng sẽ giải thích các khái niệm chung về xử lý phương tiện, như các containers và định dạng mã hóa.

Các nội dung chính:

FFmpeg là gì (và Libav)

Lần thử đầu tiên: chuyển đổi âm thanh/video cơ bản

Phân chia các đoạn: mã hóa chế độ bitrate

Giảm dung lượng video

Chuyển lại về CBR

Mix (xuống) các kênh âm thanh

Tách tập tin

Phần kết luận

Chuyển đổi âm thanh/video cơ bản bằng FFmpeg

Chúng ta bắt đầu với một chuyển đổi sử dụng mã hóa bitrate biến đổi cho cả âm thanh và video:

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

Chi tiết:

'-i input.mp4': input file;

'output.avi': output file

FFmpeg sẽ chọn container tự động, dựa trên đuôi file, trong trường hợp này là AVI

'-c:v mpeg4': [c]odec for the [v]ideo stream

Mặc định cho mpeg là Xvid, là open source DivX competitor

'-vtag xvid': video code identifier

Được gọi là "FourCC"

'-qscale:v 4': chất lượng video

Chúng ta sử dụng các bitrate khác nhau, với quality factor 4

1.6 GiB video stream- quá mức cần thiết cho nguồn 1280x720 source

'-c:a libmp3lame': [c]odec for the [a]udio stream

LAME đề cập đến (open source) MP3 encoder

'-qscale:a 5': chất lượng audio 

Giống như mã hóa video, chúng tôi sử dụng bitrate biến đổi, với hệ số chất lượng là 5. Nhìn chung thì với bitrate là 130 kbps, đại đa số mọi người không thể phân biệt một tệp được mã hóa từ nguồn trong một bài blind test, với một bộ mã hóa tốt.

Kết quả: Tập tin không mở được. Trình phát báo rằng có giới hạn trong frame size là 800x600; vì đầu vào là 1280x720 nên chúng ta sẽ cần thay đổi kích thước.

Phân chia các đoạn: mã hóa chế độ bitrate

Khi nói đến việc mã hóa một luồng (video hoặc âm thanh), chúng ta cần chọn chiến lược phân bổ lượng dữ liệu.

Để đạt được hiệu quả tối đa (như chất lượng tối đa cho tốc độ bit trung bình nhất định), chúng ta cần chỉnh tốc độ bit cao hơn cho các phân đoạn phức tạp nhất và tốc độ bit thấp hơn cho các phân đoạn đơn giản hơn.

VBR ([V]ariable [B]it[r]ate) thực hiện nhiệm vụ này. Tất cả các codec truyền thông phổ biến nhất đều hỗ trợ nó.

Nhược điểm của cách làm này là nó không biết trước được kích cỡ output là bao nhiêu.

Đối lập với cách làm này thì có CBR ([C]onstant [B]it[r]ate). CBR sử dụng cùng một bitrate cho tất cả các phân đoạn. Rõ ràng, đây là một cách làm tối ưu: các phân đoạn phức tạp nhất có thể sẽ bị ảnh hưởng, vì chúng cần nhiều dữ liệu hơn để đạt được chất lượng mong muốn.

Trong thực tế, ngay cả CBR không phải là hằng số (vì nó như "hồ chứa bit"), nhưng nó có giới hạn.

Ưu điểm của CBR là nó biết trước được kích cỡ của output.

Một nền tảng ở giữa là ABR ([A]verage [B]it[r]ate). Ý tưởng là bộ mã hóa thay đổi bitrate trong quá trình mã hóa, trong khi vẫn giữ mức trung bình mong muốn.

ABR được hỗ trợ nhiều như VBR. Có hai cách tiếp cận:

single pass (mã hóa 1 chiều): Bộ mã hóa thực hiện một lần mã hóa duy nhất, điều chỉnh bitrate khi cần, nhưng trong giới hạn cần thiết để đạt được bitrate trung bình mong muốn cuối cùng.

2-pass (mã hóa 2 chiều): Đầu tiên bộ mã hóa thực hiện phân tích độ phức tạp của các chuỗi, sau đó thực hiện mã hóa.

Chiến lược 2-pass rõ ràng là vượt trội hơn - nó khắc phục nhược điểm của VBR và CBR (bỏ qua time required - thường sẽ cao hơn do qua thêm chiều đầu tiên).

Nhược điểm của 2-pass là không phải tất cả các bộ mã hóa đều hỗ trợ mã hóa 2 chiều.

Một lưu ý cuối cùng là ABR 1 chiều có thể không hẳn tệ hơn VBR. Nếu bộ đo VBR (bộ mã hóa) mắc lỗi trong ước tính (quá ít hoặc quá nhiều dữ liệu được phân bổ), chúng sẽ kết thúc với chất lượng dưới mức tối đa hoặc lãng phí dữ liệu. Còn ABR bị hạn chế nhiều hơn nên ít bị biến động.

Tuy nhiên, hãy nhớ rằng ngày nay VBR là tiêu chuẩn, do đó, phần lớn sự tối ưu hóa được hướng đến chế độ này.

Thu nhỏ video

Bước tiếp theo chúng ta sẽ thu nhỏ video, để nó phù hợp với bộ mã hóa. Đây là câu lệnh mới:

ffmpeg -i input.mp4 -c:v mpeg4 -vtag xvid -qscale:v 4 -vf scale=800:600 -c:a libmp3lame -qscale:a 5 output.avi

Bổ sung thêm:

'-vf scale=800:600': [v]ideo filter

như vậy là chúng ta dễ dàng thu nhỏ xuống kích thước 800x600

Có một chi tiết tôi cố tình bỏ qua là video gốc có tỷ lệ khung hình 16: 9, nhưng khung hình thực sự là 4: 3, vì vậy nó hiển thị bị méo.

FFmpeg giữ cài đặt tỷ lệ khung hình là 16: 9, ngay cả khi chúng ta mã hóa thành 800x600 (tức là 4: 3). Vậy chúng ta sẽ làm gì? Chúng ta tuỳ chọn tỷ lệ khung hình:

ffmpeg -i input.mp4 -c:v mpeg4 -vtag xvid -qscale:v 4 -vf scale=800:600 -aspect 4:3 -c:a libmp3lame -qscale:a 5 output.avi

Tùy chọn rất đơn giản:

'-aspect 4:3'

Giờ thì khung hình nhìn đã ổn hơn.

Chuyển lại về CBR

Tiếp theo chúng ta thay đổi từ VBR sang CBR. Việc này sẽ kém hiệu quả hơn, nhưng đối với video cụ thể kiểu này thì thể chấp nhận được:

ffmpeg -i input.mp4 -c:v mpeg4 -vtag xvid -b:v 1000k -vf scale=800:600 -aspect 4:3 -c:a libmp3lame -b:a 96k output.avi

Việc thay đổi khá đơn giản, chúng ta thay thế bằng:

'-qscale:v 4' -> '-b:v 1000k': [b]itrate of the [v]ideo

'-qscale:a 5' -> '-b:a 96k': [b]itrate of the [a]udio

Không ai muốn hiệu quả kém đi, nhưng chúng ta không thể làm gì khác vì tính chất của player.

Video bây giờ đã được phát chính xác. Chúng ta có thể làm tốt hơn ở phần âm thanh.

Mix (down) các kênh âm thanh

Chúng ta có thể chuyển sang chế độ đơn âm, tuy nhiên một số trình phát, khi tái tạo luồng âm thanh đơn âm, chỉ phát ra trên một loa.

Để đơn giản và dễ dàng chúng ta trộn cả hai kênh và chúng ta xuất cùng một luồng thành hai kênh.

Ưu điểm là bộ mã hóa sẽ tìm thấy cùng một dữ liệu cho cả hai kênh và sẽ không cần yêu cầu thêm dữ liệu để mã hóa sự phân biệt của hai kênh. Quá trình mã hóa nhiều kênh thành một, cộng với sự phân biệt được gọi là Joint Stereo.

Câu lệnh mới:

ffmpeg -i input.mp4 -c:v mpeg4 -vtag xvid -b:v 1000k -vf scale=800:600 -aspect 4:3 -c:a libmp3lame -b:a 96k 'pan=stereo|c0<c0 c1|c1<c0 c1' output.avi

Lệnh bổ sung rất đơn giản và logic:

'-af pan=stereo|c0<c0 c1|c1<c0 c1': [a]udio [f]ilter

downmix to stereo

channel 0 (c0) sẽ là tổng của original channels 0 1 (c0 c1)

channel 1 (c1) sẽ là tổng của original channels 0 1 (c0 c1)

Phân tách file

Toàn bộ video là khoảng 90 phút; screen time là 10/15 phút mỗi ngày là đủ.

Container hiện đại hỗ trợ đánh dấu chapter, chúng ta có thể cứ sau 10 phút lại đặt một chapter.

Có một vấn đề lớn ở đây là: AVI không hỗ trợ các Chapters.

Chúng ta có thể áp dụng giải pháp đơn giản nhất: chia tách.

Về lý thuyết, có thể lấy tệp đầu vào, mở nó trong một trình editor và phân chia chính xác các tập. Đây là điều không cần thiết và nó rất thủ công.

Vì vậy, chúng ta có thể hồi quy một chút trên spectrum (phổ) và làm cho FFmpeg phân tách khi thay đổi cảnh. Điều này có thể khiến việc phát không hiệu quả, nhưng nó là cách tốt nhất chúng ta có thể làm theo kiểu tự động (không bao gồm machine learning)

Câu lệnh cuối cùng:

ffmpeg -i input.mp4 -c:v mpeg4 -vtag xvid -b:v 1000k -vf scale=800:600 -aspect 4:3 -c:a libmp3lame -b:a 96k -af 'pan=stereo|c0<c0 c1|c1<c0 c1' -segment_time 00:10:00 -reset_timestamps 1 -f segment outputd.avi

Thêm vào vài thay đổi:

'-segment_time 00:10:00': chia thành các phân đoạn, sử dụng khoảng thời gian 10 phút.

'-reset_timestamps 1': cần thiết cho lý do tương thích

'-f segment outputd.avi': định dạng tên tệp đầu ra (sử dụng định dạng printf); trong trường hợp này là số thập phân dài 2 ký tự (outputNN.avi)

Tham khảo: https://saveriomiroddi.github.io/Converting-processing-a-video-using-ffmpeg-for-viewing-on-an-digital-media-player

>> Có thể bạn quan tâm: Hiệu ứng Hover siêu đẹp cho CSS3 button

Những nỗ lực chuyển đổi từ mô hình truyền thống sang mô hình online để ứng phó kịp thời với dịch Covid-19 có thể sẽ thất bại nếu không thể đảm bảo NHANH VÀ NGAY. Áp dụng ngay các giải pháp tự động, đồng bộ, tích hợp sẵn sàng, việc triển khai có thể chỉ tính bằng PHÚT, sử dụng vài THAO TÁC đơn giản. Các giải pháp được VCCorp khuyên dùng:

1. Giải pháp Máy chủ ảo Cloud Server lưu trữ ứng dụng, phần mềm, website... khởi tạo chỉ 45 giây, giá chỉ từ 3000đ/ngày

2. Giải pháp Tăng tốc độ website tới 16 lần, không còn tình trạng trang tải chậm khi quá tải truy cập: CDN chỉ từ 800đ/GB

3. Các giải pháp mở rộng hệ thống, tăng giảm máy chủ, băng thông tự động: Load Balancer, Auto-scaling....

4. Tích hợp sẵn sàng với các công cụ quản lý, bán hàng tự động: chatbot, CRM, botbanhang, Ticket...

>>> Tìm hiểu ngay tại đây