运行 bash 文件夹中每个文件的脚本

run bash script for each files in folder

我找到了这个脚本,但它需要输入文件名和输出文件名才能工作

我是 windows 用户,所以我不知道如何为文件夹

中的每个文件运行 此脚本

我想要的是:

sourcefile=$1 -> 这应该是输入目录
destfile=$2 -> 输出目录或 originalfilename_preview

所以当我尝试执行脚本时,它将运行通过输入目录中的文件并在其中执行两个 ffmpeg 脚本

第一个 ffmpeg 脚本会将视频拆分为临时文件夹中的多个文件
第二个 ffmpeg 将这些文件合并到临时文件夹中,并使用输出文件夹或 originalfilename_preview

完成整个过程

-> 循环下一个文件直到完成

sourcefile=
destfile=

# Overly simple validation
if [ ! -e "$sourcefile" ]; then
  echo 'Please provide an existing input file.'
  exit
fi

if [ "$destfile" == "" ]; then
  echo 'Please provide an output preview file name.'
  exit
fi

# Get video length in seconds
length=$(ffprobe $sourcefile  -show_format 2>&1 | sed -n 's/duration=//p' | awk '{print int([=12=])}')

# Start 20 seconds into the video to avoid opening credits (arbitrary)
starttimeseconds=20

# Mini-snippets will be 2 seconds in length
snippetlengthinseconds=2

# We'll aim for 5 snippets spread throughout the video
desiredsnippets=5

# Ensure the video is long enough to even bother previewing
minlength=$(($snippetlengthinseconds*$desiredsnippets))

# Video dimensions (these could probably be command line arguments)
dimensions=640:-1

# Temporary directory and text file where we'll store snippets
# These will be cleaned up and removed when the preview image is generated
tempdir=snippets
listfile=list.txt

# Display and check video length
echo 'Video length: ' $length
if [ "$length" -lt "$minlength" ]
then
  echo 'Video is too short.  Exiting.'
  exit
fi

# Loop and generate video snippets
mkdir $tempdir
interval=$(($length/$desiredsnippets-$starttimeseconds))
for i in $(seq 1 $desiredsnippets)
do
    # Format the second marks into hh:mm:ss format
    start=$(($(($i*$interval))+$starttimeseconds))
    formattedstart=$(printf "%02d:%02d:%02d\n" $(($start/3600)) $(($start%3600/60)) $(($start%60)))
    echo 'Generating preview part ' $i $formattedstart
    # Generate the snippet at calculated time
    ffmpeg -i $sourcefile -vf scale=$dimensions -preset fast -qmin 1 -qmax 1 -ss $formattedstart -t $snippetlengthinseconds -threads $(nproc) $tempdir/$i.mp4
done

# Concat videos
echo 'Generating final preview file'

# Generate a text file with one snippet video location per line
# (https://trac.ffmpeg.org/wiki/Concatenate)
for f in $tempdir/*; do echo "file '$f'" >> $listfile; done

# Concatenate the files based on the generated list
ffmpeg -f concat -safe 0 -i $listfile -threads $(nproc) -an -tune zerolatency -x264opts bitrate=2000:vbv-maxrate=2000:vbv-bufsize=166 -vcodec libx264 -f mpegts -muxrate 2000K -y $destfile.mp4

echo 'Done!  Check ' $destfile '.mp4!'

# Cleanup
rm -rf $tempdir $listfile

来源:https://davidwalsh.name/video-preview

@Christopher Hoffman wsl已经安装好了,当然,我已经运行这个脚本没问题了,但是我需要手动input/output文件名

./preview.sh input.mp4 out

@Renaud Pacalet

  1. 是的,输入目录中的所有文件或拖放文件(但所有文件 在目录中似乎更容易)
  2. 我想修改脚本
  3. 输出文件的名称后缀为“_preview”
  4. 如果有后缀,相同的输入文件夹即可,
  5. 视频文件(mkv、mp4、avi、..)
  6. 一些文件名有 unicode 字符,所以我认为输入文件将 里面“”

最简单的方法可能是保持脚本原样并使用 bash 循环来处理输入目录中的所有文件。让我们假设:

  • 输入目录为/my/video/files,
  • 您想将所有输出存储在目录 /some/where
  • 您显示的脚本在/else/where/myscript.sh,
  • 您要处理输入目录中的所有个文件。

只需打开一个终端,其中 bash 是交互式 shell 并输入:

shopt -s nullglob
chmod +x /else/where/myscript.sh
mkdir -p /some/where
cd /my/video/files
for f in *; do
  /else/where/myscript.sh "$f" "/some/where/$f"
done
shopt -u nullglob

解释:

  • shopt -s nullglob 启用 nullglob 选项。如果没有这个,如果输入目录中根本没有文件,仍然会使用 f=* 进行一次循环迭代。 shopt -u nullglob 完成后禁用它。
  • chmod +x /else/where/myscript.sh 使您的脚本可执行,以防万一它还没有。
  • mkdir -p /some/where 创建输出目录,以防它不存在。
  • cd /my/video/files 将当前目录更改为您拥有视频文件的输入目录。
  • for f in *; do 遍历当前目录中的所有文件(这就是 * 所代表的意思)。在每个迭代变量 f 中分配当前文件名。
  • /else/where/myscript.sh "$f" "/some/where/$f" 使用两个参数执行您的脚本:输入文件的名称和输出文件的名称,均用双引号引起来以防止分词。

注意:如果所有文件都不是视频文件,您可以更具体:

for f in *.mkv *.mp4 *.avi; do
  ...

当然,为了方便复用,您也可以创建一个新的 shell 脚本文件。