Lấy thông tin video bằng FFmpeg như thế nào và lấy để làm gì?
Do là gần đây có nhiều bạn hỏi mình về việc cắt ghép video. Mà bạn ấy hay bị lỗi khi ghép nhiều video với nhau.
Nguyên nhân gây lỗi là do các file video đó không tương đồng nhau (về định dạng, framerate, bitrate,…). Mà chuyện tương đồng là cần thiết nếu bạn muốn ghép chúng lại thành một.
Vì vậy, việc lấy thông tin của video trước khi ghép là vô cùng cần thiết. Qua đó, bạn sẽ biết mình phải xử lý video như thế nào trước khi ghép chúng lại với nhau.
Để lấy thông tin video bằng FFmpeg có hai cách là: sử dụng ffmpeg.exe và sử dụng ffprobe.exe (đây là 2 trong 3 công cụ có được sau khi cài đặt FFmpeg).

Cách lấy thông tin video sử dụng FFmpeg
Để lấy được thông tin video bằng FFmpeg bạn có thể sử dụng câu lệnh sau:
ffmpeg -i input.mp4 -hide_banner
Trong đó:
- -i là cờ dùng để xác định file input, sau đó là tên của file đầu vào (input.mp4)
- -hide_banner là cờ dùng để bỏ qua thông tin liên quan đến phiên bản, các thư viện mà FFmpeg sử dụng,…
Ví dụ khi mình lấy thông tin của video bằng FFmpeg như sau:

Bạn có thể thấy video mà mình thử nghiệm ở đây có thời lượng (duration) là 00:02:34.18 (tức ~ 2 phút 34 giây) và bitrate là 1880 kb/s.
Ngoài ra, bạn cũng thấy rằng file này có 2 stream (hay gọi là 2 kênh cho dễ hiểu). Kênh 1 ứng với Stream #0:0 và kênh 2 ứng với Stream #0:1.
Trong đó:
- Kênh 1 (video) được encode theo chuẩn h264 với profile level là High; mỗi frame ảnh có định dạng yuv420p; kích thước video là 1920×1080 (với width=1920 và height=1080); bitrate của kênh video là 1741 kb/s (dĩ nhiên sẽ nhỏ hơn bitrate tổng của cả video); tỉ lệ framerate là 59.94 fps;
- Kênh 2 (audio) có chuẩn aac; sample rate là 44100 Hz; âm thanh dạng stereo; bitrate là 128 kb/s.
Đây là những thông tin của video mà bạn cần phải biết. Ngoài ra, nếu muốn biết thêm nhiều thông tin hơn nữa thì bạn có thể sử dụng công cụ ffprobe.exe như sau.
Cách lấy thông tin video sử dụng ffprobe.exe
Câu lệnh cơ bản sử dụng ffprobe.exe để lấy thông tin video là:
ffprobe -v error -show_format -show_streams input.mp4
Kết quả hiển thị khá dài:
[STREAM] index=0 codec_name=h264 codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 profile=Main codec_type=video codec_time_base=38946407/1867560000 codec_tag_string=avc1 codec_tag=0x31637661 width=854 height=480 coded_width=854 coded_height=480 has_b_frames=2 sample_aspect_ratio=0:1 display_aspect_ratio=0:1 pix_fmt=yuv420p level=30 color_range=tv color_space=bt709 color_transfer=bt709 color_primaries=bt709 chroma_location=left field_order=unknown timecode=N/A refs=1 is_avc=true nal_length_size=4 id=N/A r_frame_rate=24000/1001 avg_frame_rate=933780000/38946407 time_base=1/90000 start_pts=0 start_time=0.000000 duration_ts=116839221 duration=1298.213567 bit_rate=990486 max_bit_rate=N/A bits_per_raw_sample=8 nb_frames=31126 nb_read_frames=N/A nb_read_packets=N/A DISPOSITION:default=1 DISPOSITION:dub=0 DISPOSITION:original=0 DISPOSITION:comment=0 DISPOSITION:lyrics=0 DISPOSITION:karaoke=0 DISPOSITION:forced=0 DISPOSITION:hearing_impaired=0 DISPOSITION:visual_impaired=0 DISPOSITION:clean_effects=0 DISPOSITION:attached_pic=0 DISPOSITION:timed_thumbnails=0 TAG:creation_time=2013-03-21T04:50:31.000000Z TAG:language=und TAG:encoder=JVT/AVC Coding [/STREAM] [STREAM] index=1 codec_name=aac codec_long_name=AAC (Advanced Audio Coding) profile=LC codec_type=audio codec_time_base=1/44100 codec_tag_string=mp4a codec_tag=0x6134706d sample_fmt=fltp sample_rate=44100 channels=2 channel_layout=stereo bits_per_sample=0 id=N/A r_frame_rate=0/0 avg_frame_rate=0/0 time_base=1/44100 start_pts=0 start_time=0.000000 duration_ts=57250816 duration=1298.204444 bit_rate=127986 max_bit_rate=185256 bits_per_raw_sample=N/A nb_frames=55909 nb_read_frames=N/A nb_read_packets=N/A DISPOSITION:default=1 DISPOSITION:dub=0 DISPOSITION:original=0 DISPOSITION:comment=0 DISPOSITION:lyrics=0 DISPOSITION:karaoke=0 DISPOSITION:forced=0 DISPOSITION:hearing_impaired=0 DISPOSITION:visual_impaired=0 DISPOSITION:clean_effects=0 DISPOSITION:attached_pic=0 DISPOSITION:timed_thumbnails=0 TAG:creation_time=2013-03-21T04:50:31.000000Z TAG:language=eng [/STREAM] [FORMAT] filename=input.mp4 nb_streams=2 nb_programs=0 format_name=mov,mp4,m4a,3gp,3g2,mj2 format_long_name=QuickTime / MOV start_time=0.000000 duration=1298.213567 size=182308296 bit_rate=1123441 probe_score=100 TAG:major_brand=mp42 TAG:minor_version=0 TAG:compatible_brands=mp42isomavc1 TAG:creation_time=2013-03-21T04:50:31.000000Z TAG:encoder=HandBrake rev4860 2012121899 [/FORMAT]
Có khá nhiều thông tin ở đây mà mình nghĩ là rất khó để có thể giải thích hết ở đây được (bạn thông cảm nhé).
Dĩ nhiên, với yêu cầu sử dụng FFmpeg cơ bản thì mình nghĩ rằng bạn không cần thiết phải biết hết những thông tin này.
Cái nào cần thì mình tra thôi. Nhưng, biết đâu đấy, sau này cần phải dùng thì sao nhỉ?
À mà ffprobe.exe còn hỗ trợ việc lấy ra thông tin video dạng JSON hoặc XML. Khi đó, bạn có thể sử dụng kết quả ở nhiều nơi khác nữa (khi lập trình hoặc viết script chạy tự động,…).
Cách lấy thông tin video dạng JSON
Để thực hiện việc này bạn chỉ cần thêm cờ -print_format với giá trị json.
Khi đó, câu lệnh trên trở thành:
ffprobe -v error -print_format json -show_format -show_streams input.mp4
Kết quả dạng JSON:
{ "streams": [ { "index": 0, "codec_name": "h264", "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10", "profile": "Main", "codec_type": "video", "codec_time_base": "38946407/1867560000", "codec_tag_string": "avc1", "codec_tag": "0x31637661", "width": 854, "height": 480, "coded_width": 854, "coded_height": 480, "has_b_frames": 2, "sample_aspect_ratio": "0:1", "display_aspect_ratio": "0:1", "pix_fmt": "yuv420p", "level": 30, "color_range": "tv", "color_space": "bt709", "color_transfer": "bt709", "color_primaries": "bt709", "chroma_location": "left", "refs": 1, "is_avc": "true", "nal_length_size": "4", "r_frame_rate": "24000/1001", "avg_frame_rate": "933780000/38946407", "time_base": "1/90000", "start_pts": 0, "start_time": "0.000000", "duration_ts": 116839221, "duration": "1298.213567", "bit_rate": "990486", "bits_per_raw_sample": "8", "nb_frames": "31126", "disposition": { "default": 1, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaired": 0, "visual_impaired": 0, "clean_effects": 0, "attached_pic": 0, "timed_thumbnails": 0 }, "tags": { "creation_time": "2013-03-21T04:50:31.000000Z", "language": "und", "encoder": "JVT/AVC Coding" } }, { "index": 1, "codec_name": "aac", "codec_long_name": "AAC (Advanced Audio Coding)", "profile": "LC", "codec_type": "audio", "codec_time_base": "1/44100", "codec_tag_string": "mp4a", "codec_tag": "0x6134706d", "sample_fmt": "fltp", "sample_rate": "44100", "channels": 2, "channel_layout": "stereo", "bits_per_sample": 0, "r_frame_rate": "0/0", "avg_frame_rate": "0/0", "time_base": "1/44100", "start_pts": 0, "start_time": "0.000000", "duration_ts": 57250816, "duration": "1298.204444", "bit_rate": "127986", "max_bit_rate": "185256", "nb_frames": "55909", "disposition": { "default": 1, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaired": 0, "visual_impaired": 0, "clean_effects": 0, "attached_pic": 0, "timed_thumbnails": 0 }, "tags": { "creation_time": "2013-03-21T04:50:31.000000Z", "language": "eng" } } ], "format": { "filename": "input.mp4", "nb_streams": 2, "nb_programs": 0, "format_name": "mov,mp4,m4a,3gp,3g2,mj2", "format_long_name": "QuickTime / MOV", "start_time": "0.000000", "duration": "1298.213567", "size": "182308296", "bit_rate": "1123441", "probe_score": 100, "tags": { "major_brand": "mp42", "minor_version": "0", "compatible_brands": "mp42isomavc1", "creation_time": "2013-03-21T04:50:31.000000Z", "encoder": "HandBrake rev4860 2012121899" } } }
Cách lấy thông tin video dạng XML
Tương tự, để lấy thông tin video dạng XML, bạn chỉ cần thêm cờ -print_format với giá trị là xml.
Khi đó, câu lệnh trên trở thành:
ffprobe -v error -print_format xml -show_format -show_streams input.mp4
Kết quả dạng XML:
<?xml version="1.0" encoding="UTF-8"?> <ffprobe> <streams> <stream index="0" codec_name="h264" codec_long_name="H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10" profile="Main" codec_type="video" codec_time_base="38946407/1867560000" codec_tag_string="avc1" codec_tag="0x31637661" width="854" height="480" coded_width="854" coded_height="480" has_b_frames="2" sample_aspect_ratio="0:1" display_aspect_ratio="0:1" pix_fmt="yuv420p" level="30" color_range="tv" color_space="bt709" color_transfer="bt709" color_primaries="bt709" chroma_location="left" refs="1" is_avc="true" nal_length_size="4" r_frame_rate="24000/1001" avg_frame_rate="933780000/38946407" time_base="1/90000" start_pts="0" start_time="0.000000" duration_ts="116839221" duration="1298.213567" bit_rate="990486" bits_per_raw_sample="8" nb_frames="31126"> <disposition default="1" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0" timed_thumbnails="0"/> <tag key="creation_time" value="2013-03-21T04:50:31.000000Z"/> <tag key="language" value="und"/> <tag key="encoder" value="JVT/AVC Coding"/> </stream> <stream index="1" codec_name="aac" codec_long_name="AAC (Advanced Audio Coding)" profile="LC" codec_type="audio" codec_time_base="1/44100" codec_tag_string="mp4a" codec_tag="0x6134706d" sample_fmt="fltp" sample_rate="44100" channels="2" channel_layout="stereo" bits_per_sample="0" r_frame_rate="0/0" avg_frame_rate="0/0" time_base="1/44100" start_pts="0" start_time="0.000000" duration_ts="57250816" duration="1298.204444" bit_rate="127986" max_bit_rate="185256" nb_frames="55909"> <disposition default="1" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0" timed_thumbnails="0"/> <tag key="creation_time" value="2013-03-21T04:50:31.000000Z"/> <tag key="language" value="eng"/> </stream> </streams> <format filename="input.mp4" nb_streams="2" nb_programs="0" format_name="mov,mp4,m4a,3gp,3g2,mj2" format_long_name="QuickTime / MOV" start_time="0.000000" duration="1298.213567" size="182308296" bit_rate="1123441" probe_score="100"> <tag key="major_brand" value="mp42"/> <tag key="minor_version" value="0"/> <tag key="compatible_brands" value="mp42isomavc1"/> <tag key="creation_time" value="2013-03-21T04:50:31.000000Z"/> <tag key="encoder" value="HandBrake rev4860 2012121899"/> </format> </ffprobe>
Lời kết
Trên đây là 2 cách để lấy thông tin video bằng FFmpeg. Nếu có gì sai sót, bạn vui lòng góp ý cho mình biết trong phần bình luận phía dưới nhé!
Xin chào và hẹn gặp lại các bạn trong bài viết tiếp theo, thân ái!
Tham khảo thêm