Mình nhận vơ một sản phẩm của dự án “khủng” như thế nào?

Long Đào HữuĐào Hữu Long

Sản phẩm này của mình nó lạ lắm, câu chuyện bắt đầu từ một ngày đẹp trời, mình nhận được một yêu cầu khá lạ và hơi khoai như sau:

  • Giảm kích thước hình ảnh của hơn 20 video từ 1920×1080 xuống 1336×750
  • … đồng thời đảm bảo file dưới 5MB
  • … đồng thời chất lượng phải ở mức “chấp nhận được”, nghĩa là không vỡ hình hay mờ hình

Giảm độ phân giải

Mình kiểu “Ủa, cái độ phân giải này cho cái gì vậy :/”, rồi còn đảm bảo file dung lượng thấp, nhưng hình ảnh chất lượng phải cao. Nếu bạn không biết, với công cụ nén video mất dữ liệu thông thường, việc giữ đồng đều chất lượng và đồng đều dung lượng giữa các video là không thể thực hiện được. Vậy, làm sao để cân bằng giữa cả hai?

Thôi thì bắt đầu với ý đầu tiên, theo toán học, 1920×1080=1336*…

Ủa cái tỷ lệ

Như vậy, để video vừa vào khung 1336×750, ta buộc phải cắt 2 pixel trên dưới hoặc co hình lại 1.5 pixel. Mình chọn phương án cắt hình vì nó không làm biến đổi tỷ lệ hình ảnh.

Dung lượng dưới 5MB

Vậy là giải quyết xong vấn đề đầu tiên. Vấn đề tiếp theo là làm sao để tất cả các file đều dưới 5MB. Do giới hạn cứng dung lượng nên việc sử dụng phương pháp nén đồng chất lượng (constant rate factor, constant quantization parameter) bị bỏ qua ngay vì tính không ổn định về dung lượng của nó. Mình chấp nhận không đồng đều về chất lượng và một lần nữa lại sử dụng toán học.

Trong tất cả các file, file dài nhất có độ dài 38 giây, không có âm thanh. Với dung lượng đầu ra là 5MB, ta tính được…

5MB/38s=1078kbps

Như vậy, với lượng dữ liệu mỗi giây là 1078 kb, tất cả video sẽ dưới 5MB. Mình chọn 1024 kbps (1 Mbps) để đề phòng dung lượng dôi ra trong quá trình nén. Như vậy, nhờ vào toán học, mình đã giải quyết xong hai vấn đề đầu tiên. Tuy nhiên, yêu cầu “chất lượng chấp nhận được” mới thực sự quái vật.

“Chấp nhận được”

Với dung lượng thấp như trên, việc sử dụng các bộ mã hóa tiên tiến như HEVC/H.265/x265 hay AV1 sẽ là lựa chọn hàng đầu. Tuy nhiên, các bộ mã hóa này hơi mới quá chưa chắc cho lên hệ thống có thể xử lý được. Vì vậy, để tương thích tối đa, mình chọn AVC/H.264/x264 để nén, chấp nhận hy sinh chất lượng để đổi lấy tương thích, mong khách không phát hiện ra :p .

Vậy là “dàn ý” đã lên sẵn, giờ đến bước thực thi. Khi yêu cầu này đế các bạn làm video thông thường, mình khá chắc quy trình sẽ như sau: quẳng vào Adobe Media Encoder, chọn H.264, chỉnh sửa độ phân giải, bitrate và bấm chạy. Cá nhân mình không phản đối cách làm này, nhưng với lượng dữ liệu chỉ đạt 1 Mbps, kết quả xuất ra sẽ không thể chấp nhận được.

Gốc (thu nhỏ bằng phần mềm chỉnh sửa ảnh) – Adobe Media Encoder (NVENC) – x264

Adobe Media Encoder mặc định sử dụng GPU để nén video. Cách làm này tuy hiệu quả và rất nhanh nhưng chất lượng đầu ra rất thấp. Như hình trên, một lượng lớn mưa bị “biến mất”, đồng thời xuất hiện rất nhiều ô vuông 16×16 (macroblock) do không đủ dữ liệu để nén hình. Trái lại, x264 giữ được các giọt mưa, macroblock gần như không xuất hiện.

Video minh họa (histogram luma để làm rõ mô tả trên)

Như vậy, với đề bài đưa ra, cách khả thi nhất là dùng x264. Tuy nhiên, để dùng x264 với Adobe Media Encoder, ta cần phải cài AfterCodecs – vốn không miễn phí.

Thiết lập AfterCodecs khi dùng x264 (thậm chí có tùy chọn cố định dung lượng ở 5MB)

Mình làm bằng đồ miễn phí như thế nào?

Trên thực tế, để thực hiện đề bài này, đồ miễn phí lại hiệu quả hơn rất nhiều so với đồ trả phí. Điểm trừ ở đây có lẽ là độ phức tạp của nó cũng cao hơn rất nhiều. Quy trình thực hiện sẽ như sau:

File gốc > Avisynth > Đọc file gốc > Thu nhỏ + cắt hình > x264 > Đóng gói MP4

Quy trình xử lý file

Để đơn giản hóa việc thực hiện, mình dùng StaxRip. Phần mềm này mặc định đã kiểm soát toàn bộ quy trình trên, ta chỉ việc thay đổi các tham số.

Giao diện mặc định của StaxRip

Trong khung AVS Filters, Source mình chọn DSS2. Với đa dạng các định dạng video đầu vào, mình thấy DSS2 dùng ổn định nhất. Mặc dù có cắt hình nhưng mình sẽ bỏ qua bước Crop; vì hành động này sẽ thực hiện ở bước Resize. Ở bước này ta chọn Spline36Resize để vừa đảm bảo độ chính xác của hình, vừa nét và vừa hạn chế ringing.

Nháy đúp vào dòng Resize, hộp thoại Code Editor hiện ra, ta chốt luôn độ phân giải và lượng cắt hình mong muốn:

Spline36Resize(1336,750,0,1,0,-1)
#Spline36Resize(clip clip, int target_width, int target_height [,float src_left, float src_top, float src_width, float src_height ] )
#Đổi kích thước thành 1336x750, cắt 1 pixel trên và dưới của hình
Thiết lập AVS Filter trong StaxRip

Tiếp đến, bấm vào mục encoder (mặc định x265) và chọn x264, mục container (mặc định MKV) chọn MP4 sau đó bấm Options.

StaxRip x264 Options

Mode, ta chọn Two Pass, Preset > Very Slow, Bitrate1024 và bấm OK. Phần Audio chuyển toàn bộ từ Copy/Mux sang No Audio (vì file gốc không có tiếng, đề phòng).

Thiết lập StaxRip đã xong

Cuối cùng, bấm vào trong phần Assistant (Click here to open a source file), chọn File Batch, kéo file vào, sau đó bấm OKStart.

Kết quả – x264 đang nén video

Kết

Ảnh này nhạy cảm như phim người lớn ấy

Và như vậy, quá trình nén video hoàn thành. Chất lượng video có thể không cao nhất nhưng đáp ứng đủ các tiêu chí của đề bài, đồng thời tính tương thích cũng cao. Và vì nó lên sản phẩm thực tế, nên mình có thể nói rằng tuy mình không thực hiện các bước nặng nhọc như dựng hình, render,… nhưng khi các bạn xem video trên thực tế, nó là sản phẩm mình “sản xuất” ra.