如何使用 FFmpeg 获得视频的本机帧速率?
How to get native frame rate of vide with FFmpex?
背景
我有一个 .mp4
视频,我需要获取视频的帧速率。使用 ffmepg(在 Linux 中)我知道我可以通过以下命令获取此信息:
ffprobe -v 0 -of compact=p=0 -select_streams 0 -show_entries stream=r_frame_rate 'MyVideoFIle.mp4'
哪个returns:
r_frame_rate=24000/1001
FFmpex
在 bash 中这样做很好,但我真正想要的是在我的 Elixir 应用程序中使用它。为此我查了一下ffmpex
.
首先我尝试使用 FFprobe
:
> FFprobe.format("Devil May Cry 5 Bury the Light LITTLE V COVER.mp4")
{:ok,
%{
"bit_rate" => "611784",
"duration" => "482.999000",
"filename" => "Devil May Cry 5 Bury the Light LITTLE V COVER.mp4",
"format_long_name" => "QuickTime / MOV",
"format_name" => "mov,mp4,m4a,3gp,3g2,mj2",
"nb_programs" => 0,
"nb_streams" => 2,
"probe_score" => 100,
"size" => "36936415",
"start_time" => "0.000000",
"tags" => %{
"compatible_brands" => "isomiso2avc1mp41",
"encoder" => "Lavf58.19.102",
"major_brand" => "isom",
"minor_version" => "512"
}
}}
这给了我一些信息,但不是帧速率。
我的下一个尝试是使用命令选项:
command =
FFmpex.new_command()
|> add_input_file("Devil May Cry 5 Bury the Light LITTLE V COVER.mp4")
|> add_video_option(???)
但这里的问题是我无法在文档中找到 获取 本机帧速率所需的视频选项。我只找到 vframe
用于 设置 视频帧率。
问题
- 如何使用
ffmpex
获取视频的原生 fps?
我不使用 FFmpex,但通过快速查看 Github 上的源代码:
看到 第 71 行 ffmpex/lib/ffprobe.ex
是设置传递给 FFprobe 的选项:
cmd_args = ["-v", "quiet", "-print_format", "json", "-show_format", file_path]
所以也许将该行调整为:
cmd_args = ["-v", "quiet", "-print_format", "json", "-show_format", "-show_entries stream=r_frame_rate", file_path]
有可能上面写成:
cmd_args = ["-v", "quiet", "-print_format", "json", "-show_format", "-show_entries", "stream=r_frame_rate", file_path]
按照@VC.One的建议并查看源代码,我找到了FFprobe.streams("filename")
.
此函数将 return 流列表及其 avg_frame_rate
,这是来自 shell 的本机命令所做的:
FFprobe.streams("Devil May Cry 5 Bury the Light LITTLE V COVER.mp4")
{:ok,
[
%{
"refs" => 1,
"avg_frame_rate" => "24000/1001",
"level" => 31,
"nb_frames" => "11579",
"is_avc" => "true",
"coded_height" => 720,
"index" => 0,
"display_aspect_ratio" => "16:9",
"r_frame_rate" => "24000/1001",
"nal_length_size" => "4",
"has_b_frames" => 1,
"height" => 720,
"time_base" => "1/24000",
"codec_time_base" => "1001/48000",
"color_transfer" => "bt709",
"color_space" => "bt709",
"codec_tag_string" => "avc1",
"pix_fmt" => "yuv420p",
"bits_per_raw_sample" => "8",
"bit_rate" => "478071",
"codec_tag" => "0x31637661",
"profile" => "Main",
"sample_aspect_ratio" => "1:1",
"chroma_location" => "left",
"color_primaries" => "bt709",
"coded_width" => 1280,
"width" => 1280,
"codec_type" => "video",
"codec_long_name" => "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
"start_time" => "0.000000",
"duration" => "482.940792",
"duration_ts" => 11590579,
"codec_name" => "h264",
"start_pts" => 0,
"tags" => %{
"handler_name" => "ISO Media file produced by Google Inc.",
"language" => "und"
},
"color_range" => "tv",
"disposition" => %{
"attached_pic" => 0,
"clean_effects" => 0,
"comment" => 0,
"default" => 1,
"dub" => 0,
"forced" => 0,
"hearing_impaired" => 0,
"karaoke" => 0,
"lyrics" => 0,
"original" => 0,
...
}
},
%{
"avg_frame_rate" => "0/0",
"bit_rate" => "127999",
"bits_per_sample" => 0,
"channel_layout" => "stereo",
"channels" => 2,
"codec_long_name" => "AAC (Advanced Audio Coding)",
"codec_name" => "aac",
"codec_tag" => "0x6134706d",
"codec_tag_string" => "mp4a",
"codec_time_base" => "1/44100",
"codec_type" => "audio",
"disposition" => %{
"attached_pic" => 0,
"clean_effects" => 0,
"comment" => 0,
"default" => 1,
"dub" => 0,
"forced" => 0,
"hearing_impaired" => 0,
"karaoke" => 0,
"lyrics" => 0,
"original" => 0,
"timed_thumbnails" => 0,
"visual_impaired" => 0
},
"duration" => "482.998277",
"duration_ts" => 21300224,
"index" => 1,
"max_bit_rate" => "127999",
"nb_frames" => "20801",
"profile" => "LC",
"r_frame_rate" => "0/0",
"sample_fmt" => "fltp",
"sample_rate" => "44100",
"start_pts" => 0,
"start_time" => "0.000000",
"tags" => %{
"handler_name" => "ISO Media file produced by Google Inc.",
"language" => "und"
},
"time_base" => "1/44100"
}
]}
这回答了我的问题。 FFprobe.format/1
从来都不是解决方案,它是 FFprobe.streams/1
!
背景
我有一个 .mp4
视频,我需要获取视频的帧速率。使用 ffmepg(在 Linux 中)我知道我可以通过以下命令获取此信息:
ffprobe -v 0 -of compact=p=0 -select_streams 0 -show_entries stream=r_frame_rate 'MyVideoFIle.mp4'
哪个returns:
r_frame_rate=24000/1001
FFmpex
在 bash 中这样做很好,但我真正想要的是在我的 Elixir 应用程序中使用它。为此我查了一下ffmpex
.
首先我尝试使用 FFprobe
:
> FFprobe.format("Devil May Cry 5 Bury the Light LITTLE V COVER.mp4")
{:ok,
%{
"bit_rate" => "611784",
"duration" => "482.999000",
"filename" => "Devil May Cry 5 Bury the Light LITTLE V COVER.mp4",
"format_long_name" => "QuickTime / MOV",
"format_name" => "mov,mp4,m4a,3gp,3g2,mj2",
"nb_programs" => 0,
"nb_streams" => 2,
"probe_score" => 100,
"size" => "36936415",
"start_time" => "0.000000",
"tags" => %{
"compatible_brands" => "isomiso2avc1mp41",
"encoder" => "Lavf58.19.102",
"major_brand" => "isom",
"minor_version" => "512"
}
}}
这给了我一些信息,但不是帧速率。
我的下一个尝试是使用命令选项:
command =
FFmpex.new_command()
|> add_input_file("Devil May Cry 5 Bury the Light LITTLE V COVER.mp4")
|> add_video_option(???)
但这里的问题是我无法在文档中找到 获取 本机帧速率所需的视频选项。我只找到 vframe
用于 设置 视频帧率。
问题
- 如何使用
ffmpex
获取视频的原生 fps?
我不使用 FFmpex,但通过快速查看 Github 上的源代码:
看到 第 71 行 ffmpex/lib/ffprobe.ex 是设置传递给 FFprobe 的选项:
cmd_args = ["-v", "quiet", "-print_format", "json", "-show_format", file_path]
所以也许将该行调整为:
cmd_args = ["-v", "quiet", "-print_format", "json", "-show_format", "-show_entries stream=r_frame_rate", file_path]
有可能上面写成:
cmd_args = ["-v", "quiet", "-print_format", "json", "-show_format", "-show_entries", "stream=r_frame_rate", file_path]
按照@VC.One的建议并查看源代码,我找到了FFprobe.streams("filename")
.
此函数将 return 流列表及其 avg_frame_rate
,这是来自 shell 的本机命令所做的:
FFprobe.streams("Devil May Cry 5 Bury the Light LITTLE V COVER.mp4")
{:ok,
[
%{
"refs" => 1,
"avg_frame_rate" => "24000/1001",
"level" => 31,
"nb_frames" => "11579",
"is_avc" => "true",
"coded_height" => 720,
"index" => 0,
"display_aspect_ratio" => "16:9",
"r_frame_rate" => "24000/1001",
"nal_length_size" => "4",
"has_b_frames" => 1,
"height" => 720,
"time_base" => "1/24000",
"codec_time_base" => "1001/48000",
"color_transfer" => "bt709",
"color_space" => "bt709",
"codec_tag_string" => "avc1",
"pix_fmt" => "yuv420p",
"bits_per_raw_sample" => "8",
"bit_rate" => "478071",
"codec_tag" => "0x31637661",
"profile" => "Main",
"sample_aspect_ratio" => "1:1",
"chroma_location" => "left",
"color_primaries" => "bt709",
"coded_width" => 1280,
"width" => 1280,
"codec_type" => "video",
"codec_long_name" => "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
"start_time" => "0.000000",
"duration" => "482.940792",
"duration_ts" => 11590579,
"codec_name" => "h264",
"start_pts" => 0,
"tags" => %{
"handler_name" => "ISO Media file produced by Google Inc.",
"language" => "und"
},
"color_range" => "tv",
"disposition" => %{
"attached_pic" => 0,
"clean_effects" => 0,
"comment" => 0,
"default" => 1,
"dub" => 0,
"forced" => 0,
"hearing_impaired" => 0,
"karaoke" => 0,
"lyrics" => 0,
"original" => 0,
...
}
},
%{
"avg_frame_rate" => "0/0",
"bit_rate" => "127999",
"bits_per_sample" => 0,
"channel_layout" => "stereo",
"channels" => 2,
"codec_long_name" => "AAC (Advanced Audio Coding)",
"codec_name" => "aac",
"codec_tag" => "0x6134706d",
"codec_tag_string" => "mp4a",
"codec_time_base" => "1/44100",
"codec_type" => "audio",
"disposition" => %{
"attached_pic" => 0,
"clean_effects" => 0,
"comment" => 0,
"default" => 1,
"dub" => 0,
"forced" => 0,
"hearing_impaired" => 0,
"karaoke" => 0,
"lyrics" => 0,
"original" => 0,
"timed_thumbnails" => 0,
"visual_impaired" => 0
},
"duration" => "482.998277",
"duration_ts" => 21300224,
"index" => 1,
"max_bit_rate" => "127999",
"nb_frames" => "20801",
"profile" => "LC",
"r_frame_rate" => "0/0",
"sample_fmt" => "fltp",
"sample_rate" => "44100",
"start_pts" => 0,
"start_time" => "0.000000",
"tags" => %{
"handler_name" => "ISO Media file produced by Google Inc.",
"language" => "und"
},
"time_base" => "1/44100"
}
]}
这回答了我的问题。 FFprobe.format/1
从来都不是解决方案,它是 FFprobe.streams/1
!