[FFmpeg-user] ffmpeg cutting movies into multiple parts

blubee blubeeme gurenchan at gmail.com
Mon Jun 6 11:26:18 CEST 2016


That last email had a few issues, I sorted them out and here's the script:

#!/bin/bash
DIR="/../../../*" #directory where the movie files are located
OUT_DIR="/../../../../" #directory where the processed movie files will be
exported
OUTPUT_FILE=""

file_duration_flat=0
file_duration_int=0
working_file_duration=0
default_chunk_size=600 #video length in seconds (10 minutes)
chunk_size=600 #video length in seconds (10 minutes)
video_pieces=0
video_pieces_hum_re=0
video_pieces_hum_re_cnt=0
counter=0
chunk_start_time=0
chunk_end_time=0
tt=10
end=10
iteration=0

#extract simple metadata from files
for f in $DIR
do
echo $f
file_duration_float=$(ffprobe -i "$f" -show_format -v quiet | sed -n
's/duration=//p')
file_duration_int=$( echo "($file_duration_float+0.5)/1" | bc )
working_file_duration_int=$file_duration_int
working_file_duration=$(expr $file_duration_int - $chunk_size )
echo $file_duration_int

#---------------------------------------------
# get the count of pieces to cut the file into
#---------------------------------------------
# echo $working_file_duration_int
while [ "$working_file_duration_int" -ge "$chunk_size" ]
do
working_file_duration_int=$(($working_file_duration_int - chunk_size))
video_pieces=$((video_pieces + 1 ))
video_pieces_hum_re=$((video_pieces + 1 ))
video_pieces_hum_re_cnt=$video_pieces_hum_re

# echo "cut video into $video_pieces pieces"
# echo "cut video into human readable $video_pieces_hum_re pieces"
# echo "cut video human readable c $video_pieces_hum_re_cnt pieces"
done
#---------------------------------------------

#---------------------------------------------
# determine the start and end time of each clip
#---------------------------------------------
while [ $working_file_duration_int -gt -1 ]
do
filename=$(basename "$f")
input_file="$filename"
filename=${filename::-4}" "
file_extension=${f: -3}
input_file_dir=$(dirname "$f")"/"


if [ $iteration -eq 0 ]
then
working_file_duration_int=$((file_duration_int - chunk_size))
chunk_start_time=0
chunk_end_time=$(($default_chunk_size))

echo "iteration $iteration start: $chunk_start_time end: $chunk_end_time
duration: $default_chunk_size video length left $working_file_duration_int"

OUTPUT_FILE="$OUT_DIR$filename$iteration.mkv"
$(ffmpeg -hide_banner -loglevel panic -i "$f" -ss $chunk_start_time -t
$chunk_end_time [you're desired encoding] "$OUTPUT_FILE")
iteration=$((iteration+1))
fi
if [ $working_file_duration_int -le $chunk_size ]
then
# echo "break early because time is $working_file_duration_int"
chunk_size=$working_file_duration_int
working_file_duration_int=$((working_file_duration_int - chunk_size))
chunk_start_time=$(($chunk_start_time+$chunk_end_time))
chunk_end_time=$(($chunk_size))

# echo "early chunk size: $chunk_size iteration $iteration video length
left $working_file_duration_int start: $chunk_start_time end:
$chunk_end_time"
echo "early chunk size: $chunk_size iteration $iteration start:
$chunk_start_time end: $((chunk_start_time+chunk_end_time)) duration:
$chunk_end_time video length left $working_file_duration_int "

OUTPUT_FILE="$OUT_DIR$filename$iteration.mkv"
$(ffmpeg -hide_banner -loglevel panic -i "$f" -ss $chunk_start_time -t
$chunk_end_time [you're desired encoding] "$OUTPUT_FILE")
iteration=0
chunk_size=$default_chunk_size
break
else
chunk_start_time=$(($chunk_start_time+$chunk_end_time))
chunk_end_time=$(($chunk_size))
working_file_duration_int=$((working_file_duration_int - chunk_size))
echo "iteration $iteration start: $chunk_start_time end:
$((chunk_start_time+chunk_end_time)) duration: $chunk_end_time video length
left $working_file_duration_int "

OUTPUT_FILE="$OUT_DIR$filename$iteration.mkv"
$(ffmpeg -hide_banner -loglevel panic -i "$f" -ss $chunk_start_time -t
$chunk_end_time [you're desired encoding] "$OUTPUT_FILE")
iteration=$((iteration+1))
fi
done
done



On Mon, Jun 6, 2016 at 3:26 PM, blubee blubeeme <gurenchan at gmail.com> wrote:

> Hi
>
> Thanks for the reply but It seemed like I was just going about things all
> wrong with my last attempt at the script. I totally rewrote the whole thing
> from scratch using ffprobe to get the length and cut the video up into a
> max of 10 minute chunks but also handle the cases where if the video was
> less than 10 minutes long it would stop instead of just writing out junk
> data.
>
> Here's the code, there's probably excess variable declarations and stuff
> but I can clean that up later, I am just glad that the whole program works
> as expected on linux systems.
>
> #!/bin/bash
> DIR="/../../../*" #directory where the movie files are located
> OUT_DIR="/../../../../" #directory where the processed movie files will be
> exported
> OUTPUT_FILE=""
>
> file_duration_flat=0
> file_duration_int=0
> working_file_duration=0
> default_chunk_size=600 #video length in seconds (10 minutes)
> chunk_size=600 #video length in seconds (10 minutes)
> video_pieces=0
> video_pieces_hum_re=0
> video_pieces_hum_re_cnt=0
> counter=0
> chunk_start_time=0
> chunk_end_time=0
> tt=10
> end=10
> iteration=0
>
> #extract simple metadata from files
> for f in $DIR
> do
> echo $f
> file_duration_float=$(ffprobe -i "$f" -show_format -v quiet | sed -n
> 's/duration=//p')
> file_duration_int=$( echo "($file_duration_float+0.5)/1" | bc )
> working_file_duration_int=$file_duration_int
> working_file_duration=$(expr $file_duration_int - $chunk_size )
> echo $file_duration_int
>
> #---------------------------------------------
> # get the count of pieces to cut the file into
> #---------------------------------------------
> # echo $working_file_duration_int
> while [ "$working_file_duration_int" -ge "$chunk_size" ]
> do
> working_file_duration_int=$(($working_file_duration_int - chunk_size))
> video_pieces=$((video_pieces + 1 ))
> video_pieces_hum_re=$((video_pieces + 1 ))
> video_pieces_hum_re_cnt=$video_pieces_hum_re
>
> # echo "cut video into $video_pieces pieces"
> # echo "cut video into human readable $video_pieces_hum_re pieces"
> # echo "cut video human readable c $video_pieces_hum_re_cnt pieces"
> done
> #---------------------------------------------
>
> #---------------------------------------------
> # determine the start and end time of each clip
> #---------------------------------------------
> while [ $working_file_duration_int -gt -1 ]
> do
> filename=$(basename "$f")
> input_file="$filename"
> filename=${filename::-4}" "
> file_extension=${f: -3}
> input_file_dir=$(dirname "$f")"/"
>
>
> if [ $iteration -eq 0 ]
> then
> working_file_duration_int=$((file_duration_int - chunk_size))
> chunk_start_time=$(($iteration * $chunk_size))
> chunk_end_time=$(($chunk_start_time + $chunk_size))
>
> echo "iteration $iteration video length left $working_file_duration_int
> start time: $chunk_start_time end time: $chunk_end_time"
>
> OUTPUT_FILE="$OUT_DIR$filename$iteration.mkv"
> $(ffmpeg -hide_banner -loglevel panic -i "$f" -ss $chunk_start_time -t
> $chunk_end_time [you're desired encoding] "$OUTPUT_FILE")
> iteration=$((iteration+1))
> fi
> if [ $working_file_duration_int -le $chunk_size ]
> then
> # echo "break early because time is $working_file_duration_int"
> chunk_size=$working_file_duration_int
> working_file_duration_int=$((working_file_duration_int - chunk_size))
> chunk_start_time=$chunk_end_time
> chunk_end_time=$(($chunk_start_time + $chunk_size))
>
> echo "early chunk size: $chunk_size iteration $iteration video length left
> $working_file_duration_int start: $chunk_start_time end: $chunk_end_time"
>
> OUTPUT_FILE="$OUT_DIR$filename$iteration.mkv"
> $(ffmpeg -hide_banner -loglevel panic -i "$f" -ss $chunk_start_time -t
> $chunk_end_time [you're desired encoding] "$OUTPUT_FILE")
> iteration=0
> chunk_size=$default_chunk_size
> break
> else
> chunk_start_time=$chunk_end_time
> chunk_end_time=$(($chunk_start_time + $chunk_size))
> working_file_duration_int=$((working_file_duration_int - chunk_size))
> echo "iteration $iteration video length left $working_file_duration_int
> start: $chunk_start_time end: $chunk_end_time"
>
> OUTPUT_FILE="$OUT_DIR$filename$iteration.mkv"
> $(ffmpeg -hide_banner -loglevel panic -i "$f" -ss $chunk_start_time -t
> $chunk_end_time [you're desired encoding] "$OUTPUT_FILE")
> iteration=$((iteration+1))
> fi
> done
> done
>
> I've thrown a few different file types at this and it works, even with
> blank spaces in the name. I've left out my fffmpeg function because that's
> specific to the user. It could be as simple as just a straight copy or a
> total re-encode.
>
> On Sun, Jun 5, 2016 at 11:39 PM, Moritz Barsnick <barsnick at gmx.net> wrote:
>
>> On Sun, Jun 05, 2016 at 11:56:52 +0800, blubee blubeeme wrote:
>> > The line above "$OUT_DIR" doesn't work and throws a cryptic error.
>>
>> It may be cryptic to you, but if it comes from ffmpeg, it most likely
>> has a meaning. And it's one of the two things you didn't tell us. ;-)
>>
>> More precisely: Please post the full command line (unscripted) and the
>> complete, uncut console output.
>>
>> When running a bash script, you can dump the actually used command line
>> by running with "bash -x".
>>
>> Moritz
>> _______________________________________________
>> ffmpeg-user mailing list
>> ffmpeg-user at ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/ffmpeg-user
>>
>> To unsubscribe, visit link above, or email
>> ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".
>
>
>


More information about the ffmpeg-user mailing list