1

Okay so I've written a function which loops through all files in a folder (only to a depth of 1) and compresses them to a smaller file size.

EDIT: CHECK MY EDIT AT THE BOTTOM

function compressMP4batch()  {
for fname in *.mp4
do

#take off the mp4
pathAndName=${fname%.mp4}

#take off the path from the file name
videoname=${pathAndName##*/}

#take off the file name from the path
videopath=$pathAndName:h

#create new folder for converted icons to be placed in
mkdir -p ${videopath}/compressed/

ffmpeg -y -r 30  -i ${fname} -vcodec libx265 -crf 18 -acodec mp3 -movflags +faststart ${videopath}/compressed/${videoname}-compressed.mp4



echo "\033[1;33m compressed ${videoname}\n \033[0m"
done

}

I'm currently ripping VHS tapes using OBS, and I was hoping I could set a watch function to run every time a new file is added.

I've seen in other threads that inotifywait can be used for this but I don't quite get how it's syntax is set up etc.

For instance I saw in this thread this script:

#!/bin/bash
dir=BASH
inotifywait -m "$dir" -e close_write --format '%w%f' |
    while IFS=' ' read -r fname
    do
        [ -f "$fname" ] && chmod +x "$fname"
    done

So the first problem is if I just et my current function in there then I think it will just end up trying to compress all the files every single time a new file is is added.

So instead, I could take out my for loop and instead just run the ffmpeg command

but what does the inotifywait command return? does it return just the file name of the file which has been changed?

EDIT: Okay, so I was kind of mulling over stuff and then I checked the manpage and I think I figured it out except that my events are getting triggered twice by OBS, and not at the very end when OBS actually finalizes making the file

## Requires ffmpeg and inotify-tools

# testing with this: inotifywait -m . -e create  --format '%w%f' | cat

# inotifywait --monitor . --event create --event move_to --event modify  --format '%w%f'

function compressMP4watch()  {
 inotifywait --monitor . --event create  --format '%w%f' |

 while read -r fname
    do

    #take off the mp4
    pathAndName=${fname%.mp4}

    #take off the path from the file name
    videoname=${pathAndName##*/}

    #take off the file name from the path
    videopath=$pathAndName:h

    mkdir -p ${videopath}/compressed/

    ffmpeg -y -r 30  -i ${fname} -vcodec libx265 -crf 18 -acodec mp3 -movflags +faststart ${videopath}/compressed/${videoname}-compressed.mp4

    echo "\033[1;33m compressed ${videoname}\n \033[0m"

    done

}

1

This is my proposal:

#!/bin/bash
# dir to whatch
dir=~/your_dir/

# trigger when a file is moved to the dir
inotifywait -m $dir -e moved_to | \
while read -r i; do 
  # get the file name
  file_name=$(echo "$i" | grep -o "MOVED_TO.*" | sed 's/MOVED_TO //')
  # file name plus dir = full path
  file="$dir$filename"
  # apply your function (not the loop) to the file, you can pass the file as parameter
  your_function "$file"
done

I figure there are fancier ways to do this. Test if it works.

  • Hey thanks. I actually tried to come up with my own attempt but it's not working because I can't figure out the right way to handle the --event flag. I tried using create but OBS creates the file when it first starts the vhs recording process before the file actually has any data, so that won't work. I also tried close_write but that just triggers it multiple times also – David A. French Jun 29 at 1:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.