运行 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
- 是的,输入目录中的所有文件或拖放文件(但所有文件
在目录中似乎更容易)
- 我想修改脚本
- 输出文件的名称后缀为“_preview”
- 如果有后缀,相同的输入文件夹即可,
- 视频文件(mkv、mp4、avi、..)
- 一些文件名有 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 脚本文件。
我找到了这个脚本,但它需要输入文件名和输出文件名才能工作
我是 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
- 是的,输入目录中的所有文件或拖放文件(但所有文件 在目录中似乎更容易)
- 我想修改脚本
- 输出文件的名称后缀为“_preview”
- 如果有后缀,相同的输入文件夹即可,
- 视频文件(mkv、mp4、avi、..)
- 一些文件名有 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 脚本文件。