2

This is a question that is raised here How to split video or audio by silent parts or here How can I split an mp4 video with ffmpeg every time the volume is zero?

So I was able to come up with a straightforward bash script that works on my Mac.

Here it is (only argument is the name of the video to be cut, it will generate a file start_timestamps.txt with the list of silence starts if the file does not exist and reuse it otherwise):

#!/bin/bash

INPUT=$1

filename=$(basename -- "$INPUT")
extension="${filename##*.}"
filename="${filename%.*}"

SILENCE_DETECT="silence_detect_logs.txt"
TIMESTAMPS="start_timestamps.txt"

if [ ! -f $TIMESTAMPS ]; then
    echo "Probing start timestamps"
    ffmpeg -i "$INPUT" -af "silencedetect=n=-50dB:d=3" -f null - 2> "$SILENCE_DETECT"
    cat "$SILENCE_DETECT"| grep "silence_start: [0-9.]*" -o| grep -E '[0-9]+(?:\.[0-9]*)?' -o > "$TIMESTAMPS"
fi

PREV=0.0
number=0

cat "$TIMESTAMPS"| ( while read ts
do
    printf -v fname -- "$filename-%02d.$extension" "$(( ++number ))"
    DURATION=$( bc <<< "$ts - $PREV")
    ffmpeg -y -ss "$PREV" -i "$INPUT" -t "$DURATION" -c copy "$fname"
    PREV=$ts
done
printf -v fname -- "$filename-%02d.$extension" "$(( ++number ))"
ffmpeg -y -ss "$PREV" -i "$INPUT" -c copy "$fname" )

Unfortunately it does not seem to work:

I have a video that is basically a collection of clips, each clip being introduced by a ~5 second silence with a static frame with a title on it. So I want to cut the original video so that each chunk is the 5 seconds "introduction" + video until the next introduction. Hope it's clear.

Anyway, in my script I first find all silence_start using ffmpeg silencedetect plugin. I get a start_timestamps.txt that read:

141.126
350.107
1016.07
etc.

Then for example I would call (I don't need to transcode again the video), knowing that (1016.07 - 350.107) = 665.963

ffmpeg -ss 350.107 -i Some_video.mp4 -t 665.963 -c copy "Some_video02.mp4"

The edge cases being the first chunk that has to go from 0 to 141.126 and the last chunk that has to go from last timestamp to end of the video.

Anyway the start_timestamps seem legit. But my output chunks are completely wrong. Sometimes the video does not even play anymore in Quicktime. I don't even have my static frame with the title in any of the videos...

Hope someone can help. Thanks.

EDIT Ok as explained in the comments, if I echo $PREV while commenting out the ffmpeg command I get a perfectly legit list of values:

0.0
141.126
350.107
1016.07
etc.

With the ffmpeg command I get:

0.0
141.126
50.107
016.07
etc.

bash variable changes in loop with ffmpeg shows why.

I just need to append < /dev/null to the ffmpeg command or add -nostdin argument. Thanks everybody.

fricadelle
  • 511
  • 1
  • 8
  • 26
  • Turn on debugging with `set -x` so you can see what values are being used in your variables (you want to confirm you've got the right values going in, right?) (`set +x` will turn off that feature). Good luck. – shellter Feb 09 '20 at 16:38
  • Thanks. If I comment out the ffmpeg command and print out PREV it is fine. With the ffmpeg PREV is being messed up and shows weird values (I am not kidding). Probably some bash weirdness with the decimal point or space in filename? – fricadelle Feb 09 '20 at 17:59
  • As shown here https://stackoverflow.com/questions/52374260/bash-variable-changes-in-loop-with-ffmpeg I need to append < /dev/null at the end of my ffmpeg command... – fricadelle Feb 09 '20 at 21:13
  • Please don't make us guess what is the weirdness. Add a line like `echo ffmpeg -y -ss $PREV -i "$INPUT" -t $DURATION -c copy "$fname"` AND then update your Q above whith that output so we can see the actual values. You also want to "guard" those variables so we'll know if there are any white spaces chars causing problems, i.e. `echo ffmpeg -y -ss [$PREV] -i "[$INPUT]" -t [$DURATION] -c copy "[$fname]"` AND finally, its always good to dbl-quote usages of all variables unless there is a special case. You should tell us if you really need to leave `$PREV` and `$DURATION` un-quoted and whyGoodLuck – shellter Feb 10 '20 at 00:49
  • dbl-quote usage was not the issue. With "echo ffmpeg..." the commands are perfectly fine. I provided the explanation in the EDIT and in the comment above. Thanks! – fricadelle Feb 11 '20 at 10:35
  • Glad you got a solution. I am messing with `ffmpeg` ocasionally, and hopefully I'll remember this too! Good luck. – shellter Feb 11 '20 at 17:19

0 Answers0