i found this script but it need input filename and output filename to work
i'm windows user so i dont know how to run this script for each files in folder
what i want is :
sourcefile=$1 -> this should be input directory
destfile=$2 -> output directory or just originalfilename_preview
so when i'm try to excute script, it will run through files in input directory and excute two ffmpeg script inside
the first ffmpeg script will split video into multiple files in temp folder
the second ffmpeg merge those files in temp folder and complete the whole process with output folder or originalfilename_preview
-> loop for next files until completed
sourcefile=$1
destfile=$2
# 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($0)}')
# 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 "d:d:d\n" $(($start/3600)) $(($start600/60)) $(($start`)))
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
source: https://davidwalsh.name/video-preview
@Christopher Hoffman wsl already installed, of course, i'm already run this script without problem but i need to manual input/output filename
./preview.sh input.mp4 out
@Renaud Pacalet
- yes, all files in input directory or drag&drop files (but all files in directory seem like easier)
- i think modify script
- output file have suffix in name "_preview"
- if it have suffix, same input folder is ok,
- video files (mkv,mp4,avi,..)
- some files name have unicode character so i think input file will inside " "
CodePudding user response:
The easiest is probably to keep the script as it is and to use a bash loop to process all files in the input directory. Let's assume:
- the input directory is
/my/video/files, - you want to store all outputs in directory
/some/where, - the script you show is in
/else/where/myscript.sh, - you want to process all files in the input directory.
Just open a terminal where bash is the interactive shell and type:
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
Explanations:
shopt -s nullglobenables thenullgloboption. Without this, if there are no files at all in the input directory, there would still be one iteration of the loop withf=*.shopt -u nullglobdisables it when we are done.chmod x /else/where/myscript.shmakes your script executable, just in case it was not already.mkdir -p /some/wherecreates the output directory, just in case it did not exist yet.cd /my/video/fileschanges the current directory to the input directory in which you have your video files.for f in *; doloops over all files in the current directory (this is what the*stands for). In each iteration variablefis assigned the current file name./else/where/myscript.sh "$f" "/some/where/$f"executes your script with two parameters: the name of the input file and the name of the output file, both quoted with double quotes to prevent word splitting.
Note: if all files are not video files you can be more specific:
for f in *.mkv *.mp4 *.avi; do
...
