我有一个文本文件,其中包含逐行的帧编号,我使用bash脚本和ffmpeg循环遍历每一行并尝试打印出每个帧的缩略图。
每次我在终端中运行bash脚本时都会因创建第一个缩略图时出错而停止。似乎没有给缩略图一个唯一的名称。我做错了什么?
我的bash脚本:
#!/bin/bash
source text.txt
while read name
do
ffmpeg -i result.mp4 -vf "setpts=N+1,select='eq(n,$name)'" -vframes 1 frames-$i.jpg
done <text.txt
错误:
File 'frames-.jpg' already exists. Overwrite ? [y/N] Not overwriting - exiting
答案 0 :(得分:1)
尝试定义$i
:
i=0
while read name
do
((i++))
ffmpeg -i result.mp4 -vf "setpts=N+1,select='eq(n,$name)'" -vframes 1 frames-$i.jpg
done <text.txt
答案 1 :(得分:1)
首先,我猜你不需要source
脚本中的文件text.txt。当文件由source filename
或. filename
提供时,文件中的代码行将被执行,就好像它们是在命令行中打印一样。因此,我删除了您脚本的这一部分。
其次,正如其他人所说,您没有定义或更新$i
变量。这样的修改可能适合您:
#!/bin/bash
i="0"
while read -r name || [[ -n "${name}" ]]; do # allows for last line with no newline
ffmpeg -i result.mp4 -vf "setpts=N+1,select='eq(n,${name})'" -vframes 1 frames-${i}.jpg
if [ "$?" -eq "0" ]; then
printf -- 'ffmpeg succeeded - creating frames-%s.jpg for %s\n' "${i}" "${name}"
else
printf -- 'ffmpeg failed - was unable to create frames-%s.jpg for %s\n' "${i}" "${name}"
fi
let i+="1"
done <text.txt
上述脚本的一些附加说明:
建议-r
使用read
来禁用数据读取中反斜杠转义和行继续的解释。如果你的输入有bash
个可逃避的字符,这可以让你免受问题的困扰。
我在while条件中添加了|| [[ -n "${name}" ]]
,以允许输入文件中的最后一行没有换行符作为最后一个字符。否则标准读取过程将忽略最后一行,因为它需要每行末尾的换行符。
我添加了对bash内置变量$?
的检查。上一个命令的返回值存储在$?
中。 0
表示成功,其他表示错误。
编辑
如果您想帮助解决ffmpeg正在做的事情,可以尝试以下修改后的脚本:
#!/bin/bash
set -x # activate bash debugging output
while read -r frame_number || [[ -n "${frame_number}" ]]; do # allows for last line with no newline
ffmpeg -i result.mp4 -vf "setpts=N+1,select='eq(n,${frame_number})'" -vframes 1 frames-${frame_number}.jpg
if [ $? -eq 0 ]; then
printf -- 'ffmpeg succeeded - creating frames-%s.jpg\n' "${frame_number}"
else
printf -- 'ffmpeg failed - was unable to create frames-%s.jpg\n' "${frame_number}"
fi
done <text.txt
编辑内容包括:
bash
启用set -x
调试。使用上面修改过的脚本,您应该能够在每次运行时看到ffmpeg
的所有输出。我的模拟测试显示所有应该按照您期望的结果正确运行。你能再次测试并报告你的发现吗?