I basicly have this script:
#!/bin/bash #Asks For filname and Word echo 'Which word are you looking for?' read word echo 'What's the name of the file?' read fileName #Searches word and parses the line-numbers wordOut=$(grep -i -n -w $word $fileName.srt |cut -f1 -d:) #Sets all outputs to diffrent line numbers and saves a temp file for word in $wordOut do echo $word done >file.tmp #Parses lines to array, removes temp file mapfile -t arr <file.tmp rm file.tmp #Declares variable for the number of array entries (not used anywhere atm) ln=${#arr[@]} #Subtract all array entries with one one=1 for i in "${arr[@]}" do crc=`expr $i - $one` echo $crc done >two.tmp #Subtraction result to array2 mapfile -t arr2 <two.tmp rm two.tmp echo ${arr2[@]} #retrieve times for h in "${arr2[@]}" do line=$(sed "${h}q;d" $fileName.srt) echo $line done >three.tmp #replace all commas with decimal points sed 's/,/./g' three.tmp >four.tmp #remove temp file 3 and parse 'decimal pointed' to array rm three.tmp mapfile -t arr3 <four.tmp rm four.tmp echo ${arr3[0]} echo ${arr3[1]} # converts HH:MM:SS.sss to fractional seconds codes2seconds() ( local hh=${1%%:*} local rest=${1#*:} local mm=${rest%%:*} local ss=${rest#*:} printf "%s" $(bc <<< "$hh * 60 * 60 + $mm * 60 + $ss") ) # converts fractional seconds to HH:MM:SS.sss seconds2codes() ( local seconds=$1 local hh=$(bc <<< "scale=0; $seconds / 3600") local remainder=$(bc <<< "$seconds % 3600") local mm=$(bc <<< "scale=0; $remainder / 60") local ss=$(bc <<< "$remainder % 60") printf "%02d:%02d:%06.3f" "$hh" "$mm" "$ss" ) subtracttimes() ( local t1sec=$(codes2seconds "$1") local t2sec=$(codes2seconds "$2") printf "%s" $(bc <<< "$t2sec - $t1sec") ) for range in "${arr3[@]}" do mod=$(sed 's/[^0-9]//g' <<< $range) duration=$(subtracttimes "${range%% -->*}" "${range##*--> }") printf "%s\n" "ffmpeg -i $fileName.mp4 -ss ${range%% -->*} -t $duration -async 1 $word.$mod.$fileName.cut.mp4" done >final.tmp sudo chmod 755 final.tmp ./final.tmp rm final.tmp
Which works perfectly fine. What it does: it searches the srt file, which has the same name has the mp4 file for a keyword, then finds the timestamp which matches this keyword, and cuts away the video from the starting point to the end point.
SRT file, for example:
**video.srt** 1 00:00:00,000 --> 00:00:04,950 welkom bij eerste toekomst reizen dus 2 00:00:02,639 --> 00:00:05,670 onderdeel aan de achterhoekse toekomst 3 00:00:04,950 --> 00:00:07,290 stoere 4 00:00:05,670 --> 00:00:11,250 mijn heren nu al heel veel dingen
So basically if you're looking for the keyword "toekomst", it will output two mp4's, one which originally started at 00:00:00,000
and ended at 00:00:04,950
, and one which started at 00:00:02,639
and ended at 00:00:05,670
.
I have multiple MP4's in the same directory, all with an corresponding .srt file with the same name as the mp4, which all need to be run through this script. So I want to build a script extensions which looks for all the files with the same names, and runs it through the script.
So I wrote this piece of code to test this:
#!/bin/bash cd "`dirname "$0"`" for file in *.srt do fileName="$( basename "$file" .srt)" echo $fileName echo $fileName.mp4 echo $fileName.srt done >temp
and it indeed gives the output of all the .mp4 files and .srt files in the directory:
h h.mp4 h.srt r r.mp4 r.srt
So then I build this for loop around the existing code as follows:
#!/bin/bash cd "`dirname "$0"`" #Asks For filname and Word echo 'Which word are you looking for?' read word for file in *.srt do fileName="$( basename "$file" .srt)" #Searches word and parses the line-numbers wordOut=$(grep -i -n -w $word $fileName.srt |cut -f1 -d:) #Sets all outputs to diffrent line numbers and saves a temp file for word in $wordOut do echo $word done >file.tmp #Parses lines to array, removes temp file mapfile -t arr <file.tmp rm file.tmp #Declares variable for the number of array entries (not used anywhere atm) ln=${#arr[@]} #Subtract all array entries with one one=1 for i in "${arr[@]}" do crc=`expr $i - $one` echo $crc done >two.tmp #Subtraction result to array2 mapfile -t arr2 <two.tmp rm two.tmp echo ${arr2[@]} #retrieve times for h in "${arr2[@]}" do line=$(sed "${h}q;d" $fileName.srt) echo $line done >three.tmp #replace all commas with decimal points sed 's/,/./g' three.tmp >four.tmp #remove temp file 3 and parse 'decimal pointed' to array rm three.tmp mapfile -t arr3 <four.tmp rm four.tmp echo ${arr3[0]} echo ${arr3[1]} # converts HH:MM:SS.sss to fractional seconds codes2seconds() ( local hh=${1%%:*} local rest=${1#*:} local mm=${rest%%:*} local ss=${rest#*:} printf "%s" $(bc <<< "$hh * 60 * 60 + $mm * 60 + $ss") ) # converts fractional seconds to HH:MM:SS.sss seconds2codes() ( local seconds=$1 local hh=$(bc <<< "scale=0; $seconds / 3600") local remainder=$(bc <<< "$seconds % 3600") local mm=$(bc <<< "scale=0; $remainder / 60") local ss=$(bc <<< "$remainder % 60") printf "%02d:%02d:%06.3f" "$hh" "$mm" "$ss" ) subtracttimes() ( local t1sec=$(codes2seconds "$1") local t2sec=$(codes2seconds "$2") printf "%s" $(bc <<< "$t2sec - $t1sec") ) for range in "${arr3[@]}" do mod=$(sed 's/[^0-9]//g' <<< $range) duration=$(subtracttimes "${range%% -->*}" "${range##*--> }") printf "%s\n" "ffmpeg -i $fileName.mp4 -ss ${range%% -->*} -t $duration -async 1 $word.$mod.$fileName.cut.mp4" done >final.tmp sudo chmod 755 final.tmp ./final.tmp rm final.tmp done
and for the first run, with the first file it gives the correct output mp4's but after that it shuffles the variables in some way that I can't get the proper output.