获取特定流的 codec_name

Get the codec_name of a specific stream

我需要提取视频文件的第二个视频流(插图)的 codec_name

所以我这样做了:

$ ffprobe -hide_banner -v error -show_streams -of json Resurrection_Sunday_Online_Experience_12_April_2020_5.30pm_New_Creation_Church.mp4  | jq . > ffmpeg_output.json

json 文件如下所示:

$  cat ffmpeg_output.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": "1411877/84712500",
      "codec_tag_string": "avc1",
      "codec_tag": "0x31637661",
      "width": 854,
      "height": 480,
      "coded_width": 864,
      "coded_height": 480,
      "has_b_frames": 0,
      "sample_aspect_ratio": "1:1",
      "display_aspect_ratio": "427:240",
      "pix_fmt": "yuv420p",
      "level": 31,
      "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": "30/1",
      "avg_frame_rate": "42356250/1411877",
      "time_base": "1/90000",
      "start_pts": 0,
      "start_time": "0.000000",
      "duration_ts": 677700960,
      "duration": "7530.010667",
      "bit_rate": "387395",
      "bits_per_raw_sample": "8",
      "nb_frames": "225900",
      "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": {
        "language": "und",
        "handler_name": "VideoHandler"
      }
    },
    {
      "index": 1,
      "codec_name": "aac",
      "codec_long_name": "AAC (Advanced Audio Coding)",
      "profile": "-1",
      "codec_type": "audio",
      "codec_time_base": "1/48000",
      "codec_tag_string": "mp4a",
      "codec_tag": "0x6134706d",
      "sample_fmt": "fltp",
      "sample_rate": "48000",
      "channels": 2,
      "channel_layout": "stereo",
      "bits_per_sample": 0,
      "r_frame_rate": "0/0",
      "avg_frame_rate": "0/0",
      "time_base": "1/48000",
      "start_pts": 0,
      "start_time": "0.000000",
      "duration_ts": 361441280,
      "duration": "7530.026667",
      "bit_rate": "125374",
      "max_bit_rate": "129296",
      "nb_frames": "352970",
      "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": {
        "language": "und",
        "handler_name": "SoundHandler"
      }
    },
    {
      "index": 2,
      "codec_name": "mjpeg",
      "codec_long_name": "Motion JPEG",
      "profile": "192",
      "codec_type": "video",
      "codec_time_base": "0/1",
      "codec_tag_string": "[0][0][0][0]",
      "codec_tag": "0x0000",
      "width": 1280,
      "height": 720,
      "coded_width": 1280,
      "coded_height": 720,
      "has_b_frames": 0,
      "sample_aspect_ratio": "1:1",
      "display_aspect_ratio": "16:9",
      "pix_fmt": "yuvj420p",
      "level": -99,
      "color_range": "pc",
      "color_space": "bt470bg",
      "chroma_location": "center",
      "refs": 1,
      "r_frame_rate": "90000/1",
      "avg_frame_rate": "0/0",
      "time_base": "1/90000",
      "start_pts": 0,
      "start_time": "0.000000",
      "duration_ts": 677702430,
      "duration": "7530.027000",
      "bits_per_raw_sample": "8",
      "disposition": {
        "default": 0,
        "dub": 0,
        "original": 0,
        "comment": 0,
        "lyrics": 0,
        "karaoke": 0,
        "forced": 0,
        "hearing_impaired": 0,
        "visual_impaired": 0,
        "clean_effects": 0,
        "attached_pic": 1,
        "timed_thumbnails": 0
      }
    }
  ]
}

我试过了,但它没有正确提取 codec_name

$ cat ffmpeg_output.json | jq '[select(.streams[].codec_type=="video")][1].codec_name' 
null

我还注意到它选择了所有流:

$ cat ffmpeg_output.json | jq '[select(.streams[].codec_type=="video")][1]' | grep codec_type      
      "codec_type": "video",
      "codec_type": "audio",
      "codec_type": "video",

你能帮帮我吗?

对于这种特殊情况,您不需要 JQ。

$ ffprobe -hide_banner -v error -of compact=nk=1:p=0 -select_streams v:1 -show_entries stream=codec_name video.mp4
h264

您的 jq 过滤器完全不正确。你的 select() 表达式是错误的。记住 select() 表达式 returns 一个布尔值,你的条件 .streams[].codec_type=="video" 被断言 true 对于两个提供的输入对象,即 streams"index": 0"index": 2,并且对于这些真实条件中的每一个,过滤器打印所有 3 个对象,即复制整个 JSON,因为 select() 处于顶层。 您需要在 .streams

之后制作 select()
.streams[] | select(.codec_type=="video").codec_name

要选择特定索引处的对象,请使用标准数组表示法 .[0].[1]

[ .streams[] | select(.codec_type=="video") ][1] | .codec_name