0

假设我在目录中有一堆视频,/home/user/videos/awaiting_conversion我将如何使用 cron 运行与此类似的脚本以将每个视频批量转换为不同的格式?

/bin/sh -c $'nice /usr/bin/ffmpeg -i \044'\'$'/home/user/videos/awaiting_conversion/video_file_1.mp4'\'$' -s \044'\'$'480x320'\'$' -vcodec libx264 -acodec libmp3lame -ab \044'\'$'64k'\'$' -vpre fast -crf \044'\'$'30'\'$' -ar \044'\'$'22050'\'$' -f flv -y \044'\'$'/home/user/videos/converted/video_file_1.flv'\'$''

上面的脚本适用于单次转换,但是:

  1. 它假定视频的名称是静态/已知的(批量转换时不会出现这种情况)。
  2. 它假设只有一个视频要转换(可能是也可能不是),即没有“循环”。
  3. 它将原始文件留在原处而不是删除它(这是我希望发生的事情以防止重复转换)。

最终的问题是如何为其中存在的每个视频运行该脚本/home/user/videos/awaiting_conversion,并将文件名作为变量传递?

4

2 回答 2

4

尝试这样做:

#!/bin/bash

checkFile(){
    [[ -s $1 && -f $1 ]] && return 0 || return 1
}

mp42flv(){
    for arg; do
        checkFile "$arg" || continue
        /usr/bin/ffmpeg \
            -i "$arg" \
            -s '480x320' \
            -vcodec libx264 \
            -acodec libmp3lame \
            -ab '64k' \
            -vpre fast \
            -crf '30' \
            -ar '22050' \
            -f flv \
            -y "${arg%.*}.flv" ||
                echo >&2 "Error treating $arg"
    done
}

if [[ -t 0 ]]; then
    mp42flv "$@"
else
    while IFS= read -r a; do
        checkFile "$a" || continue
        mp42flv "$a"
    done
fi

用法

  • 带着一团./script.sh /home/user/videos/converted/video_file*.mp4
  • 带有文件名./script.sh /home/user/videos/converted/video_file_01.mp4
  • 通过管道find /home/user/videos/converted -type f -name '*video*mp4' |./script.sh(脚本检测使用STDIN
于 2013-03-28T00:32:58.003 回答
1

在这种情况下,basename命令是你的朋友。你可以使用模式...

VIDEOS = /home/user/videos
for srcfile in ${VIDEOS}/awaiting_conversion/*.mp4 ; do
    dstfile=${VIDEOS}/converted/`basename ${srcfile} .mp4`.flv
    convertcommand ${srcfile} ${dstfile}
done

basename 从 srcfile 中删除目录并删除后缀。然后,您只需添加新路径并附加新后缀。

自动删除旧的 srcfile 时要小心。您可能可以检查一些事情,例如 a) ffmpeg 返回码,b) dstfile 的文件大小是一定大小或更大,也许 c) 让它自动为您播放新文件,以便您可以快速查看它然后控制 - c 如果质量不正确,则退出转换或其他内容。如果您只是想防止重复转换,最好将文件移动到另一个目录,然后在确认其一切正常后将其删除。

于 2013-03-28T00:49:56.207 回答