我已经在Stackoverflow上阅读了几篇关于在FOR循环期间绑定变量的帖子。虽然我认为这里提供的大部分帮助都是针对Linux / Unix的,但我正在寻求Windows中批处理脚本的帮助。我的主要目标是使用ffmpeg(和/或ffprobe)从mp4文件中提取“创建日期”并“在我的视频上覆盖日期”。
我已经进行了很多实验,但是我最近的尝试一直试图将ffprobe的结果绑定到变量上,并在以后使用该变量。我最新最简单的尝试看起来像这样:
SETLOCAL ENABLEDELAYEDEXPANSION
for %%a in ("*.mp4") do (
for /F "tokens=*" %%G in ('ffprobe -v quiet %%a -print_format compact -show_entries format_tags=creation_time') do (
set DateC=%%G
echo !DateC!)
)
我希望能够使用该代码从ffprobe打印标记结果,但显然不是。因此,帮助我绑定该变量,以及如何在Windows中的以下代码片段中再次调用它将非常感激:
ffmpeg -i %%a -filter_complex "drawtext=fontfile=/Windows/Fonts/Arial.ttf:x=28:y=650:fontsize=45:fontcolor=white:box=1:boxcolor=black@0.4:text='!DateC!'" -c:a copy output.mp4
我还必须提到我在StackOverflow上看到了以下代码:
ffmpeg -i %%a -filter_complex "drawtext=fontfile=/Windows/Fonts/Arial.ttf:x=28:y=650:fontsize=45:fontcolor=white:box=1:boxcolor=black@0.4:text='%{metadata\:creation_time}'" -c:a copy output.mp4
但是我有同样的问题让Windows识别并打印元数据。
我确定相关文件包含此元数据。
答案 0 :(得分:1)
我建议这不是批处理文件的测试代码:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
for %%a in ("*.mp4") do (
for /F "delims=" %%G in ('ffprobe.exe -v quiet "%%a" -print_format compact -show_entries format_tags^=creation_time 2^>^&1') do (
set "DateC=%%G"
echo !DateC!
)
)
endlocal
内部 FOR 在一个单独的命令进程中运行,该进程以cmd /C
命令行开头:
ffprobe.exe -v quiet "%%a" -print_format compact -show_entries format_tags=creation_time 2>&1
"%%a"
已被当前* .mp4文件的名称替换。如果当前* .mp4文件名包含空格或其中一个字符&()[]{}^=;!'+,`~
,则必须使用双引号。
必须在参数列表中使用^
转义等号以使命令行正确传递到后台 FOR 启动的cmd.exe
。
2>&1
导致重定向输出处理 STDERR 以处理 STDOUT ,因为 FOR 仅捕获写入 STDOUT 启动的命令进程。
重定向操作符>
和&
必须使用 FOR 命令行上的插入符^
进行转义,以便在Windows命令解释程序处理时解释为文字字符执行命令 FOR 之前的此命令行,它在后台启动的单独命令进程中执行嵌入式ffprobe.exe
命令行。
我没有安装ffprobe.exe
和ffmpeg.exe
,但我认为这些控制台应用程序会写入有关文件的信息来处理 STDERR (标准错误),而不是 STDOUT (标准输出),这是使用2>&1
获取 FOR 捕获并分配给环境变量的有用信息的原因。
"tokens=*"
与"delims="
相同。两者都导致将 FOR 捕获的整行分配给循环变量G
,而不使用空格/制表符作为分隔符将其拆分为子串(标记),除了行以分号开头由于内部默认eol=;
, FOR 会完全忽略该行以进行处理。