【问题标题】:Parse csv into variables and execute ffmpeg command in loop将csv解析成变量并循环执行ffmpeg命令
【发布时间】:2018-09-26 23:25:27
【问题描述】:

我正在尝试使用 bash 脚本执行批处理操作以从多个视频文件中提取特定帧并保存为 PNG。我希望通过在 bash 脚本中使用 ffmpeg 来做到这一点,并辅以一个 csv 文件,该文件包含输入视频的名称、要从输入视频中提取的特定帧号以及 PNG 文件的输出名称。

视频文件和 csv 文件都将放在同一个文件夹中。如果需要,脚本也可以放在那里。

我的 csv - 称为“select.csv” - 当前采用以下格式(输入、输出、帧):

mad0.m4v,mad0_out1,9950
mad0.m4v,mad0_out2,4500
mad1.m4v,mad1_out1,3200

我当前的脚本 - 称为“frame.sh” - 采用以下形式:

#!/bin/bash
OLDIFS=$IFS
IFS=“,”
SDIR=/Users/myuser/Desktop/f-input/

cd $SDIR;
while read input output frame
do
   echo "$input"
   echo "$output"
   echo "$frame"
   input1=$input
   output1=$output
   frame1=$frame
   ffmpeg -i "$input1" -vf select='eq(n\,'"$frame1"')' -vsync 0 
"$output1".png
done < $1
IFS=$OLDIFS

这应该允许我运行./frame.sh select.csv,然后处理我桌面上“f-input”文件夹中的所有相关文件并提取指定的帧。

我最终回显了从 csv 读取的变量,以便它们实际上可以用作变量并在 ffmpeg 命令中循环,因为仅在读取操作之后直接使用 $input、$frame 和 $output 执行 ffmpeg 命令在 csv 的第一行完成了该过程,没有进一步进展。

基本上我希望以下内容真正循环遍历每个 csv 条目,而不仅仅是第一行:

#!/bin/bash
OLDIFS=$IFS
IFS=“,”
SDIR=/Users/myuser/Desktop/f-input/

cd $SDIR;
while read input output frame
do
   ffmpeg -i "$input" -vf select='eq(n\,'"$frame"')' -vsync 0 "$output".png
done < $1
IFS=$OLDIFS

感谢所有建议!

非常感谢

【问题讨论】:

  • 同意 dbl-quote 解决方案。你在路上,继续!检查您在shellcheck.net 的代码,以加快您的开发周期。祝你好运!

标签: bash loops csv


【解决方案1】:

IFS=“,” 替换为IFS=","

【讨论】:

  • 谢谢 - 我没有记下语音标记。但是,通过这种更改,我仍然无法遍历每一行,我只能解析 csv 中的第一行。还有其他想法吗?
  • &lt;/dev/null附加到您的ffmpeg行的末尾。
  • 赛勒斯 - 谢谢你的回答。完成这项任务无济于事。对于那些想要理解的人——如果我理解正确的话——添加 /null 允许进程执行它的下一个操作,而不会影响现有文件/权限或其他任何东西(输出为空),并且进程可以继续到下一个阶段。
【解决方案2】:

我写了一个类似的脚本,通过 ffmpeg 读取 csv 和处理电影。 它在 csv 的第一行上运行良好,但在第二行之后失败。

我发现 ffmpeg 在一个循环中似乎会影响“读取”命令并修剪第二行之后的行的第一个字符。

所以我最终在 csv 的最左侧添加了额外的“垃圾”列,并让 ffmpeg 修剪它。

我的 csv 是这样的:

101,movie1.mp4
102,movie2.mp4
103,movie3.mp4
...

和(简化的)脚本是这样的:

while IFS="," read id movie; do
  ffmpeg -v quiet -s 1280x720 -i "$movie" "$id-$movie" </dev/null
done

它为 csv 的第一行生成“101-movie1.mp4”,就像我期望的那样 但在第二行之后它会生成 "02-movie1.mp4" "03-movie3.mp4" 等等,因为 ffmpeg(似乎已经)修剪了行的第一个字符。

我像这样在第一列添加了一个垃圾列

x,101,movie1.mp4
x,102,movie2.mp4
x,103,movie3.mp4

并修复脚本:

while IFS="," read garbage id movie; do
  ffmpeg -v quiet -s 1280x720 -i "$movie" "$id-$movie" </dev/null
done

这对我有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-05
    • 2012-11-02
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-19
    相关资源
    最近更新 更多