Hướng dẫn cách lấy thông tin video bằng FFmpeg

Lấy thông tin video bằng FFmpeg như vậy nào & lấy để làm gì?

Do là gần đây có nhiều bạn hỏi chính 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.

Lý do 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à thiết yếu nếu bạn mong muốn ghép chúng lại thành một.

Chính vì thế, việc lấy thông tin của video trước khi ghép là vô cùng thiết yếu. Qua đó, bạn sẽ biết mình phải giải quyết video như vậy 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 & sử dụng ffprobe.exe (đây là 2 trong 3 dụng cụ có được sau khoảng thời gian thiết lập FFmpeg).

Cách lấy thông tin video bằng 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 số đó:

  • -i là cờ dùng để xác nhận file input, sau này 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,…

Chẳng hạn 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 ở giai đoạn này có thời lượng (duration) là 00:02:34.18 (tức ~ 2 phút 34 giây) & bitrate là 1880 kb/s.

không chỉ thế, 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 & kênh 2 ứng với Stream #0:1.

Trong số đó:

  • Kênh 1 (video) được encode theo chuẩn h264 với profile level là High; mỗi frame ảnh có định dạng yuv420pkích cỡ video là 1920×1080 (với width=1920 & height=1080); bitrate của kênh video là 1741 kb/s (hẳn nhiên sẽ bé 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; tiếng động dạng stereo; bitrate là 128 kb/s.
Xem Thêm  Primer CSS Box Shadow Remove - css loại bỏ bóng hộp

Đây là những thông tin của video mà bạn cần phải biết. không chỉ thế, nếu mong muốn biết thêm nhiều thông tin hơn nữa thì bạn có thể sử dụng dụng cụ ffprobe.exe như sau.

Cách lấy thông tin video sử dụng ffprobe.exe

Câu lệnh căn 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=Н.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=Ռ/?
    refs=1
    is_avc=true
    nal_length_size=4
    id=Ռ/?
    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=Ռ/?
    bits_per_raw_sample=8
    nb_frames=31126
    nb_read_frames=Ռ/?
    nb_read_packets=Ռ/?
    DISPOSITION_default=1
    DISPOSITION_dub=0
    DISPOSITION_original=0
    DISPOSITION:phản hồi=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=Ռ/?
    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=Ռ/?
    nb_frames=55909
    nb_read_frames=Ռ/?
    nb_read_packets=Ռ/?
    DISPOSITION_default=1
    DISPOSITION_dub=0
    DISPOSITION_original=0
    DISPOSITION:phản hồi=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ó hơi nhiều thông tin ở giai đoạn này mà mình nghĩ là rất khó để có thể giải thích hết ở giai đoạn này được (bạn thông cảm nhé).

Hiển nhiên, với yêu cầu sử dụng FFmpeg căn bản thì mình cho rằng bạn không thiết yếu phải biết hết những thông tin này.

Xem Thêm  Kết nối chuỗi trong Python - nối các biến trong python

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 khiến cho 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 auto,…).

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 đương, để 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.

Xem Thêm  Hướng dẫn về nút CSS: Cách viết mã các nút trong 5 bước đơn giản - cách thiết kế nút trong css

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"?>
    <ffprobevàgt;
        <streamsvàgt;
            <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" phản hồi="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"/>
            </streamvàgt;
            <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" phản hồi="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"/>
            </streamvàgt;
        </streamsvàgt;

        <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"/>
        </formatvàgt;
    </ffprobevàgt;

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 phản hồi cho mình biết trong phần comment phía dưới nhé!

Xin chào & hẹn tái ngộ các bạn trong nội dung kế tiếp, thân ái!

Đọc thêm

Viết một bình luận