FFMPEG - 将FFPROBE的持续时间输出存储为变量

3

我希望使用视频的长度在“enable='between(t,0,0)”字段中,每次确保我在视频的1/3处放置一个图像。

根据FFMPEG网站上的信息,我需要使用以下内容:

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4

它确实返回了一个值,但我似乎不能将其设置为可用的变量,我已经尝试使用

set duration=ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4

我尝试通过%duration%进行引用,但不成功。

有没有什么方法可以做到这一点,或者我做错了什么?

感谢您的帮助。


2个回答

8
用于处理控制台应用程序输出的命令是FOR
可以使用类似下面的批处理文件代码来捕获ffprobe的输出并将其赋值给环境变量。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
if not exist input.mp4 goto :EOF
for /F "delims=" %%I in ('ffprobe.exe -v error -show_entries format^=duration -of default^=noprint_wrappers^=1:nokey^=1 input.mp4 2^>^&1') do set "duration=%%I"
echo Duration is: %duration%
endlocal

命令FOR选项/F解释被包含在'中的字符串作为要执行的命令,其输出写入STDOUT应逐行处理。为此,FORcmd.exe会在后台启动一个额外的命令进程,使用%ComSpec% /c和位于'之间的命令行作为附加参数,并捕获所有写入到额外启动的后台命令进程的STDOUT句柄的内容。
Windows命令处理器cmd.exe处理批处理文件时,空格、逗号,、分号;、等号=和OEM编码的不换行空格 (十进制代码值为255)都被视为参数分隔符。因此,在传递给在后台启动的cmd.exe的命令行中,需要使用^转义每个=,以便让cmd.exe处理批处理文件的等号被解释为字面字符而不是参数分隔符。

2>&1 将输出写入到 STDERR(标准错误)的内容重定向到处理 STDOUT(标准输出)的句柄,由 FOR 处理。在这里,需要使用 ^ 对运行 ffprobe 时的操作符 >& 进行转义,以便将此重定向应用于解析 FOR 命令行时而不是已经解释的重定向。请参阅 Microsoft 文章 Using command redirection operators。如果 ffprobe 在正确使用时将所请求的信息输出到 STDOUT,则此将 STDERR 重定向到 STDOUT 可能是不必要的。但如果 ffprobe 将数据输出到 STDERR,那么这可能很重要。

因此,在安装了 Windows 的 C:\Windows 中后台执行以下操作:

C:\Windows\System32\cmd.exe /c ffprobe.exe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4 2>&1

这是根据运行Windows 命令提示符窗口中的cmd /?输出所解释的语法,对Windows命令处理器的绝对有效执行。

/F后面用双引号括起来的选项delims=禁止将捕获的行分割为多个标记(字符串),使用空格和水平制表符作为字符串分隔符,因为它定义了一个空的字符串分隔符列表。"delims="可能对使用的命令行的ffprobe输出不是必需的。但是我没有安装ffprobe,并且在问题中没有发布它的输出。

要理解所用命令及其工作原理,请打开一个命令提示符窗口,在其中执行以下命令,并完整和仔细地阅读每个命令显示的帮助页面。

  • 回显 /?
  • 结束本地环境 /?
  • 循环 /?
  • 跳转 /?
  • 条件语句 /?
  • 设置变量 /?
  • 启用本地环境 /?

1

我发现这个解决方案对我来说是最好的,可以从ffprobe中提取信息位到变量中。

也许它能帮助其他人: 从ffprobe获取信息的Bash脚本

示例:

INPUT='C:\Users\tl\Downloads\f18\MyWork\test.mov'
eval $(ffprobe -v quiet -show_format -of flat=s=_ -show_entries stream=height,width,nb_frames,duration,codec_name $INPUT);
width=${streams_stream_0_width};
height=${streams_stream_0_height};
bitrate=$((${format_bit_rate}/1000));
echo $width,$height,$bitrate;
read

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接