Khám phá các nguyên tắc video hình ảnh âm thanh và FFmpeg

Nội dung bài viết

Trong thời đại mà video ngắn phổ biến như tiktok, facebook hay trên Piepme, là một lập trình viên, bạn phải hiểu: các nguyên tắc và kỹ thuật đằng sau việc chỉnh sửa video. Bài viết này mô tả ngắn gọn thành phần của các nguyên tắc của video và các công cụ chỉnh sửa video phổ biến, cũng như cách sử dụng FFmpeg trong NodeJS. 

Để hiểu nguyên lý của video, trước tiên bạn nên bắt đầu với nguyên lý của hình ảnh và đầu tiên chúng ta sẽ nói đến Pixel.


Pixel là gì?

Sử dụng ffmpeg trong nodejs

Pixel là gì? Hình ảnh là một khối màu đơn vị nhỏ nhất trong hình ảnh được biểu thị bằng một dãy số, được gọi là pixel (pixel / px). Kích thước hình ảnh mà chúng ta đang nói đến 1920*1080 đề cập đến các pixel chiều dài và chiều rộng là 19201080 pixel, do đó 1920*1080, tổng số pixel trong một bức ảnh là: 1920*1080 = 2073600 pixel.


Làm thế nào để tính toán kích thước của hình ảnh?


Công thức tính một hình ảnh sẽ là Số lượng pixel * kích thước pixel = kích thước hình ảnh. Màu sắc RGB thực sự có thể được thể hiện 256×256×256= 16,777,216 là những gì chúng ta thường thấy. 

Về độ sâu của pixel thì RGB có mấy loại bit sau đây: 1bit, 4bit, 8bit, 16bit, 24bit, 32bit. Ví dụ người ta nói hình ảnh 8bit thì hiểu nôm na là (đề cập đến rgb mỗi màu chiếm 8 bit) do đó 1 px = 3 * 8bit = 24bit, nó thường được gọi là hình ảnh 24 bit. Bạn không cần hiểu sâu về những khái niệm này nhưng về cơ bản cũng phải hiểu và từng đó cũng đủ gây dựng cho bạn một sự hiểu biết nhất định về pixel.


Thông tin cơ bản về video


Video là hình ảnh của một sản phẩm được ghép lại với nhau, thậm chí FPS càng cao càng trông trôi chảy và mượt mà hơn, với tốc độ khung hình (số hình ảnh trên giây là FPS phát) để đo độ trôi chảy mượt mà của video. 

Sau đó, kích thước video có thể được tính toán theo thuật toán của kích thước hình ảnh. Công thức tính kích thước của video: 

Kích thước của video = thời lượng (giây) * tốc độ khung hình (FPS) * kích thước hình ảnh; 

Chính vì vậy để hiểu video thì một số khái niệm bạn cần biết cơ bản là như thế này:

  • Khung: Ảnh tĩnh, đơn vị nhỏ nhất của video.
  • Tốc độ khung hình (FPS): Số lượng hình ảnh được phát mỗi giây.
  • Tốc độ bit: Luồng dữ liệu được tệp video sử dụng trong một đơn vị thời gian xác định chất lượng và kích thước của video và đơn vị là kb / s hoặc Mb / s.

Nói chung, ở cùng độ phân giải, dòng mã của tệp video càng lớn, tỷ lệ nén càng nhỏ và chất lượng hình ảnh càng cao. Luồng mã càng lớn thì tốc độ lấy mẫu trên một đơn vị thời gian càng lớn, luồng dữ liệu càng cao và độ chính xác càng cao và tập tin đã xử lý sẽ càng gần với tập tin gốc, càng tốt, chất lượng hình ảnh càng rõ nét và khả năng giải mã của thiết bị phát càng lớn. 

Ba chế độ tốc độ bit phổ biến: 

- CBR

      - Tốc độ bit ổn định trong suốt 

      - Kích thước tệp có thể đoán trước 

      - Áp lực mã hóa thấp, thường được sử dụng trong phát sóng trực tiếp livestream 

- VBR

     - Tốc độ bit thay đổi 

     - Tỷ lệ mã thấp trong các cảnh đơn giản, tốc độ mã cao trong các cảnh phức tạp 

- CRF

     - Chế độ chất lượng cố định 

     - Giá trị CRF càng thấp, video trông càng cao

Định dạng đóng gói video


Các định dạng đóng gói phổ biến MP4, AVI, FLV, mov, RMVB, MKV, WMV, 3GP, ASF.


Định dạng mã hóa video


Mã hóa video là mô tả về việc sử dụng các thuật toán nén video để chuyển đổi một định dạng video này thành một định dạng video khác và mã hóa âm thanh cũng giống như vậy. 

Mã hóa video phổ biến AC-1 định dạng: MPEG2/H.262, VP8, MPEG4, VP9, H.261, H.263, H.264,H.265 ... 

Âm thanh phổ biến mã hóa WMA định dạng: MP3, AC-3, AAC, APE, FLAC,WAV ...


Nguyên tắc nén video


 Mục đích chính là nén dữ liệu pixel video (RGB, YUV, v.v.) thành luồng video, do đó giảm lượng dữ liệu video, tức là xử lý pixel. 


YUV và RGB là một định dạng được mã hóa màu, so với RGB việc nén có lợi hơn. Trong số đó, "Y" đại diện cho độ sáng (Lumina hoặc Luma), là giá trị thang độ xám; và "U" và "V" đại diện cho sắc độ (Chrominance hoặc Chroma), được sử dụng để mô tả màu sắc và độ bão hòa của hình ảnh. Màu của pixel được chỉ định. 


Ở đây chúng ta chỉ nói khái hiệm cơ bản còn bạn muốn hiểu sâu hơn về "Làm thế nào nén video và âm thanh" thì chúng ta có thể tìm đọc trên trang của bạn tôi đó là Mr. Google.


FFmpeg là gì?


 FFmpeg là một tập hợp các thư viện và công cụ để xử lý nội dung đa phương tiện như âm thanh, video, phụ đề và siêu dữ liệu liên quan. Nói một cách đơn giản, nó là một chương trình xử lý video đa nền tảng. 


Nguyên lý của FFmpeg


 Về cơ bản có thể nói toàn bộ quá trình: phân kênh => giải mã => mã hóa => ghép kênh.


Hình gif sử dụng ffmpeg


Cài đặt FFmpeg


FFmpeg được chia thành 3 phiên bản: Static, Shared, Dev 

Cài đặt MacBook: 

brew install ffmpeg

 Cài đặt khác vui lòng tham khảo web chính thức của ffmpeg


Sử dụng FFmpeg


 Nó có thể mã hóa từng thành phần của video riêng biệt và hỗ trợ các định dạng mã hóa âm thanh và video toàn diện hơn. 

Ví dụ: chuyển đổi vùng chứa video, nén âm thanh và video, quay video, ảnh chụp màn hình, bộ lọc, trích xuất âm thanh ... phải công nhận ffmpeg rất mạnh mẽ. 


Cú pháp dòng lệnh ffmpeg


ffmpeg [tham số toàn cục] [tham số tệp đầu vào] -i [tệp đầu vào] [thông số tệp đầu ra] [tệp đầu ra]


Lấy thông tin video sử dụng ffmpeg

//thông tin video
ffmpeg -i input.mp4

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input2.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf58.29.100
    description     : Packed by Bilibili XCoder v2.0.2
  Duration: 00:08:24.45, start: 0.000000, bitrate: 2180 kb/s  
    Stream #0:0(und): Video: hevc (Main) (hev1 / 0x31766568), yuv420p(tv), 1920x1080 [SAR 1:1 DAR 16:9], 2046 kb/s, 25 fps, 25 tbr, 16k tbn, 25 tbc (default)  
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default) // 
    Metadata:
      handler_name    : SoundHandler

Chuyển đổi tốc độ bit sử dụng ffmpeg

ffmpeg -i input.mp4 -b:v 64k -bufsize 64k output.mp4

Chuyển đổi tỷ lệ khung hình với ffmpeg

ffmpeg -i input.mp4 -r 5 output.mp4

Chuyển đổi độ phân giải:

ffmpeg -i input.mp4 -vf scale=480:-1 output.mp4 // 1080p * 480p

Tốc độ video

ffmpeg -i test1 "setpts=PTS/5" test4.mp4 // Tốc độ chuyển đổi video gấp 5 lần
fmpeg -i input.mp4 -filter:a "atempo=2.0" 4s.mp4 // Phát lại tốc độ âm thanh gấp 2 lần
ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" -vn 4s.mp4 //Tốc độ âm thanh và video cùng lúc gấp 2 lần

Trích xuất âm thanh và video

ffmpeg -i input.mp4 -an output.mp4 //video
ffmpeg -i input.mp4 -vn output.mp3 //âm thanh

Chuyển đổi tỷ lệ video:

ffmpeg -i input.mp4 -aspect 21:9 output.mp4

Chuyển đổi vùng chứa video:

ffmpeg -i input.mp4 output.avi

Ảnh chụp màn hình video:

ffmpeg -ss 00:00:05 -i input.mp4 -vframes 1 -q:v 5 -f image2 pic-%03d.jpeg
// -ss 00:00:05 Bắt đầu từ giây thứ năm -vframe 1 chỉ chụp 1 khung hình -q: v 5 chất lượng hình ảnh 1-5

Quay video:

ffmpeg -ss 00:00:02 -i input.mp4 -t 6.5 -c copy cut.mp4
ffmpeg -ss 00:00:02 -i input.mp4 -to 00:00:10 -c copy cut.mp4

Hình ảnh hoặc video liên tục tạo ra hình ảnh gif sử dụng ffmpeg

ffmpeg -i output.mp4 -to 10 -r 30 -vf scale=100:-1 gg.gif //Chặn một phần của video để tạo gif 100: -1 với chiều rộng được chỉ định và chiều cao duy trì tỷ lệ ban đầu

ffmpeg -r 5 -i pic-%03d.jpeg 11.gif   // tạo nhiều hình ảnh gif

// Hình ảnh cũng có thể tạo video
ffmpeg -r 20 -i pic-%03d.jpeg gif.mp4

ffmpeg -f concat -i "concat:part1.mp4|part2.mp4|3.mp4|part4.mp4" -c copy output.mp4 // Ghép nhiều video thành một

Hình ảnh hoặc video cộng với bộ lọc filter:

// filter làm mờ
ffmpeg -y -i pic-012.jpeg -vf boxblur=7 blur.jpeg
// Đổi màu
ffmpeg -i pic-012.jpeg -vf colorbalance=rm=1 colorbalance1.jpg // Điều chỉnh trọng lượng của một kích thước nhất định của rgb để đạt được sự thay đổi màu sắc.
ffmpeg -i pic-012.jpeg -vf colorchannelmixer=.3:.4:.3:0:.3:.4:.3:0:.3:.4:.3 colorchannelmixer1.jpg // Tính toán lại bốn kênh của rgba và đưa ra tỷ lệ trọng lượng tương ứng.
ffmpeg -i pic-012.jpeg -vf hue=h=30:s=1 hue1.jpg // Thay đổi tông màu, tương đương với bảng màu
ffmpeg -i pic-012.jpeg -vf lutyuv="y=negval:u=negval:v=negval" lutyuv1.jpg // lutyuv được sử dụng cho không gian màu yuv
ffmpeg -i pic-012.jpeg -vf negate=0 negate1.jpg // Đảo ngược
ffmpeg -i pic-012.jpeg -vf swapuv swapuv1.jpg  // UV Hoán đổi
ffmpeg -i pic-012.jpeg -vf crop=w=200:h=300:x=500:y=800 crop1.jpg // crop

Thêm hình mờ với ffmpeg

ffmpeg -i input.mp4 -i pic-012.jpeg -filter_complex "[1:v] scale=176:144 [logo];[0:v][logo]overlay=x=0:y=0" out.mp4 //Thêm hình mờ hình ảnh vào video

ffmpeg -i input.mp4 -vf "drawtext=fontsize=100:fontcolor=white:alpha=0.3:text='%{localtime\:%Y\-%m\-%d %H-%M-%S}':y=h-line_h-100:x=(w-text_w)/2" output22.mp4// Thêm hình mờ văn bản

ffmpeg -i input.mp4 -i pic-012.jpeg -filter_complex "[1:v] scale=176:144 [logo];[0:v][logo]overlay=x=0:y=0" out.mp4

ffmpeg -i input.mp4 -vf drawtext="fontsize=100:text='我是水印':fontcolor=green:enable=lt(mod(t\,3)\,1)" interval-sy.mp4

Thêm phụ đề:

ffpmeg -i input.ass input.srt

// thêm phụ đề vào video. Có thể thêm nhiều phụ đề
ffmpeg -i input.mp4 -vf subtitles=input.ass output.mp4

Nén video:

ffmpeg -i input.mp3 -ab 128 output.mp3 // nén âm thanh

ffmpeg -i input.mp4 -vf scale=1280:-1 -c:v libx264 -preset veryslow -crf 24 output.mp4 // nén video

Phát trực tiếp video:

// Lưu video đã ghi cục bộ
ffmpeg -f avfoundation -i "1" -vcodec libx264 -preset ultrafast -f h264 -r 30 ~/Downloads/test.h264

// Đẩy các video đã được tải xuống vào thư mục
ffmpeg -re -i ~/Downloads/xxx.mp4  -vcodec libx264 -acodec aac -strict -2 -f flv rtmp://localhost:1935/live

// Ghi màn hình
ffmpeg -f avfoundation -i "1" -vcodec libx264 -preset ultrafast -acodec libfaac -f flv rtmp://localhost:1935/rtmplive/room

// Ghi âm máy tính để bàn và micrô
ffmpeg -f avfoundation -i "1:0" -vcodec libx264 -preset ultrafast -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost:1935/live/room

// Ghi âm máy tính để bàn và micrô và bật camera để quay
ffmpeg -f avfoundation -framerate 30 -i "1:0" \-f avfoundation -framerate 30 -video_size 640x480

Cách sử dụng FFmpeg trong Node

 Fluent-ffmpeg Fluent-ffmpeg là một module trừu tượng hóa các lệnh ffmpeg phức tạp thành NodeJS, miễn là FFmpeg được cài đặt trong hệ thống . Một số cách sử dụng đơn giản 

// Thông tin video
ffmpeg.ffprobe(input, function (err, metadata) {
  console.dir(metadata);
});

// Trích xuất âm thanh
ffmpeg(input)
  .audioCodec("libmp3lame")
  .on("error", function (err) {
    console.log("Đã xảy ra lỗi: " + err.message);
  })
  .on("end", function () {
    console.log("Trích xuất âm thanh hoàn tất 🍻🍻!");
  })
  .save(resOut);

// Trích xuất video
ffmpeg(input)
  .noAudio()
  .on("error", function (err) {
    console.log("Đã xảy ra lỗi: " + err.message);
  })
  .on("end", function () {
    console.log("Trích xuất video hoàn tất 🍻🍻!");
  })
  .save(resOut);

Tóm lại

 Bài viết trên đây giới thiệu một số kỹ năng sử dụng ffmpeg để thao tác một số lệnh cơ bản. Và qua đó bạn cũng học được những khái niệm cơ bản về âm thanh và video, hình ảnh. ffmpeg thật sự quan trọng với xu thế hiện nay. Cho nên bạn cũng bắt đầu đi là vừa rồi đấy. Nếu giúp ích cho các bạn thì bạn vui long share giúp ra cộng đồng nhé. 


Bài viết có sử dụng một số tư liệu của internet. Nếu có khiếu nại về bản quyền vui lòng liên hệ anonystick@gmail.com. Trân trọng cảm ơn. 


Có thể bạn đã bị missing