FFmpeg 在使用 -filter_complex 和分割过滤器时提取不同数量的帧
FFmpeg extracts different number of frames when using -filter_complex together with the split filter
我在摆弄ffmpeg,从视频中提取jpg图片。我使用 -filter_complex 将输入流分成两个输出流,因为我从直接 http link 处理我的视频(VPS 上的稀缺免费 space),而且我不不想把整个视频看完两遍(流量名额也稀缺)。此外,我需要两个系列的 pitcures,一个用于应用一些过滤器(fps 更改、缩放、反锐化、裁剪、缩放),然后用肉眼从中选择,另一个系列保持不变(期望 fps 更改,并裁剪黑色边框), 从第一个系列中选择后,将它们用于进一步处理。我从 Ruby 脚本调用我的 ffmpeg 命令,因此它包含一些 #{} 形式的字符串插值/替换。我的工作命令行看起来像:
ffmpeg -y -fflags +genpts -loglevel verbose -i #{url} -filter_complex "[0:v]fps=fps=#{new_fps.round(5).to_s},split=2[in1][in2];[in1]crop=iw-#{crop[0]+crop[2]}:ih-#{crop[1]+crop[3]}:#{crop[0]}:#{crop[1]},scale=#{thumb_width}:-1:flags=lanczos,unsharp,lutyuv=y=gammaval(#{gammaval})[out1];[in2]crop=iw-#{crop[0]+crop[2]}:ih-#{crop[1]+crop[3]}:#{crop[0]}:#{crop[1]}[out2]" -f #{format} -c copy #{options} -map_chapters -1 - -map '[out1]' -f image2 -q 1 %06d.jpg -map '[out2]' -f image2 -q 1 big_%06d.jpg
#{options} 当输出为 MP4 时设置,那么它的值为“-movflags frag_keyframe+empty_moov” 所以我可以将它发送到标准输出而无需寻求功能和上传流在没有制作大量临时视频文件的地方。
所以我得到了两个系列的照片,其中一个被过滤、锐化,另一个实际上没有被修改。而且我还在标准输出上获得了视频的输出流,该输出流由 Open3.popen3 库处理,连接了其他两个命令的输入输出流。
当我想在视频中寻找给定点并忽略 STDOUT 上的流式视频输出时出现问题。我尝试在给定时间码之前应用组合搜索、快速搜索和精确时间码的慢速搜索,以浮动秒数给出:
ffmpeg -report -y -fflags +genpts -loglevel verbose -ss #{(seek_to-seek_before).to_s} -i #{url} -ss #{seek_before.to_s} -t #{t_duration.to_s} -filter_complex "[0:v]fps=fps=#{pics_per_sec},split=2[in1][in2];[in1]crop=iw-#{crop[0]+crop[2]}:ih-#{crop[1]+crop[3]}:#{crop[0]}:#{crop[1]},scale=#{thumb_width}:-1:flags=lanczos,unsharp,lutyuv=y=gammaval(#{gammaval})[out1];[in2]crop=iw-#{crop[0]+crop[2]}:ih-#{crop[1]+crop[3]}:#{crop[0]}:#{crop[1]}[out2]" -map '[out1]' -f image2 -q 1 %06d.jpg -map '[out2]' -f image2 -q 1 big_%06d.jpg
运行这个命令我得到了需要的两个系列的图片,但是它们包含不同数量的图片,233 和 484。
可以从这个内插/替换的命令行中读取实际值:
ffmpeg -report -y -fflags +genpts -loglevel verbose -ss 1619.0443599999999 -i fabf.avi -ss 50.0 -t 46.505879999999934 -filter_complex "[0:v]fps=fps=5,split=2[in1][in2];[in1]crop=iw-0:ih-0:0:0,scale=280:-1:flags=lanczos,unsharp,lutyuv=y=gammaval(0.526316)[out1];[in2]crop=iw-0:ih-0:0:0[out2]" -map '[out1]' -f image2 -q 1 %06d.jpg -map '[out2]' -f image2 -q 1 big_%06d.jpg
可以在这里找到详细的日志:http://www.filefactory.com/file/1yih17k2hrmp/ffmpeg-20160610-223820.txt
在最后一行之前它显示了 188 个重复的帧。
我也尝试传递“-vsync 0”选项,但没有帮助。当我用两个不同的命令行在两个连续的步骤中生成两个系列的图像时,就没有问题了,我当然在两个系列中得到了相同数量的图片。所以我的问题是,我如何使用后面的命令行,仅通过一次读取/解析远程视频文件来生成两个系列的图像?
您还必须为第二个输出复制 -ss
-t
选项,即
...-f image2 -q 1 %06d.jpg -map '[out2]' -ss 50 -t 46.5 -f image2 -q 1 big_%06d.jpg
每个输出选项(不在 -i
之前的选项)仅适用于紧随其后的输出。
我在摆弄ffmpeg,从视频中提取jpg图片。我使用 -filter_complex 将输入流分成两个输出流,因为我从直接 http link 处理我的视频(VPS 上的稀缺免费 space),而且我不不想把整个视频看完两遍(流量名额也稀缺)。此外,我需要两个系列的 pitcures,一个用于应用一些过滤器(fps 更改、缩放、反锐化、裁剪、缩放),然后用肉眼从中选择,另一个系列保持不变(期望 fps 更改,并裁剪黑色边框), 从第一个系列中选择后,将它们用于进一步处理。我从 Ruby 脚本调用我的 ffmpeg 命令,因此它包含一些 #{} 形式的字符串插值/替换。我的工作命令行看起来像:
ffmpeg -y -fflags +genpts -loglevel verbose -i #{url} -filter_complex "[0:v]fps=fps=#{new_fps.round(5).to_s},split=2[in1][in2];[in1]crop=iw-#{crop[0]+crop[2]}:ih-#{crop[1]+crop[3]}:#{crop[0]}:#{crop[1]},scale=#{thumb_width}:-1:flags=lanczos,unsharp,lutyuv=y=gammaval(#{gammaval})[out1];[in2]crop=iw-#{crop[0]+crop[2]}:ih-#{crop[1]+crop[3]}:#{crop[0]}:#{crop[1]}[out2]" -f #{format} -c copy #{options} -map_chapters -1 - -map '[out1]' -f image2 -q 1 %06d.jpg -map '[out2]' -f image2 -q 1 big_%06d.jpg
#{options} 当输出为 MP4 时设置,那么它的值为“-movflags frag_keyframe+empty_moov” 所以我可以将它发送到标准输出而无需寻求功能和上传流在没有制作大量临时视频文件的地方。 所以我得到了两个系列的照片,其中一个被过滤、锐化,另一个实际上没有被修改。而且我还在标准输出上获得了视频的输出流,该输出流由 Open3.popen3 库处理,连接了其他两个命令的输入输出流。
当我想在视频中寻找给定点并忽略 STDOUT 上的流式视频输出时出现问题。我尝试在给定时间码之前应用组合搜索、快速搜索和精确时间码的慢速搜索,以浮动秒数给出:
ffmpeg -report -y -fflags +genpts -loglevel verbose -ss #{(seek_to-seek_before).to_s} -i #{url} -ss #{seek_before.to_s} -t #{t_duration.to_s} -filter_complex "[0:v]fps=fps=#{pics_per_sec},split=2[in1][in2];[in1]crop=iw-#{crop[0]+crop[2]}:ih-#{crop[1]+crop[3]}:#{crop[0]}:#{crop[1]},scale=#{thumb_width}:-1:flags=lanczos,unsharp,lutyuv=y=gammaval(#{gammaval})[out1];[in2]crop=iw-#{crop[0]+crop[2]}:ih-#{crop[1]+crop[3]}:#{crop[0]}:#{crop[1]}[out2]" -map '[out1]' -f image2 -q 1 %06d.jpg -map '[out2]' -f image2 -q 1 big_%06d.jpg
运行这个命令我得到了需要的两个系列的图片,但是它们包含不同数量的图片,233 和 484。
可以从这个内插/替换的命令行中读取实际值:
ffmpeg -report -y -fflags +genpts -loglevel verbose -ss 1619.0443599999999 -i fabf.avi -ss 50.0 -t 46.505879999999934 -filter_complex "[0:v]fps=fps=5,split=2[in1][in2];[in1]crop=iw-0:ih-0:0:0,scale=280:-1:flags=lanczos,unsharp,lutyuv=y=gammaval(0.526316)[out1];[in2]crop=iw-0:ih-0:0:0[out2]" -map '[out1]' -f image2 -q 1 %06d.jpg -map '[out2]' -f image2 -q 1 big_%06d.jpg
可以在这里找到详细的日志:http://www.filefactory.com/file/1yih17k2hrmp/ffmpeg-20160610-223820.txt 在最后一行之前它显示了 188 个重复的帧。
我也尝试传递“-vsync 0”选项,但没有帮助。当我用两个不同的命令行在两个连续的步骤中生成两个系列的图像时,就没有问题了,我当然在两个系列中得到了相同数量的图片。所以我的问题是,我如何使用后面的命令行,仅通过一次读取/解析远程视频文件来生成两个系列的图像?
您还必须为第二个输出复制 -ss
-t
选项,即
...-f image2 -q 1 %06d.jpg -map '[out2]' -ss 50 -t 46.5 -f image2 -q 1 big_%06d.jpg
每个输出选项(不在 -i
之前的选项)仅适用于紧随其后的输出。