Sách

Thứ Hai, 4 tháng 3, 2019

[ffmpeg Tutorial] Lấy Thông Tin Video Bằng Ffmpeg

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

Câu lệnh

Để 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,…

Phân tích kết quả

Ví dụ khi mình lấy thông tin của video bằng FFmpeg như sau:



Lấy thông tin của video sử dụng ffmpeg.exe
Lấy thông tin video bằng FFmpeg sử dụng ffmpeg.exe

Bạn có thể thấy video mà mình thử nghiệm ở đây có thời lượng (duration) là 00:21:38.21 (tức ~ 21 phút 38 giây) và bitrate là 1123kb/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à Main; mỗi frame ảnh có định dạng yuv420pkích thước video là 854×480 (với width=854 và height=480); bitrate của kênh video là 990 kb/s (dĩ nhiên sẽ nhỏ hơn bitrate tổng của cả video); tỉ lệ framerate là 23.98 fps; 
  • Kênh 2 (audio) có chuẩn aac; sample rate là 44100 Hz; âm thanh dạng stereo; bitrate là 127 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.

Lấy thông tin video sử dụng ffprobe.exe

Câu lệnh cơ bản

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ó để 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,…).

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"
        }
    }
}

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, thân ái!