Home > Blockchain >  run bash script for each files in folder
run bash script for each files in folder

Time:01-19

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

  1. yes, all files in input directory or drag&drop files (but all files in directory seem like easier)
  2. i think modify script
  3. output file have suffix in name "_preview"
  4. if it have suffix, same input folder is ok,
  5. video files (mkv,mp4,avi,..)
  6. 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 nullglob enables the nullglob option. Without this, if there are no files at all in the input directory, there would still be one iteration of the loop with f=*. shopt -u nullglob disables it when we are done.
  • chmod x /else/where/myscript.sh makes your script executable, just in case it was not already.
  • mkdir -p /some/where creates the output directory, just in case it did not exist yet.
  • cd /my/video/files changes the current directory to the input directory in which you have your video files.
  • for f in *; do loops over all files in the current directory (this is what the * stands for). In each iteration variable f is 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
  ...
  •  Tags:  
  • Related