-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Filipe Laborde-Basto
committed
Mar 25, 2020
1 parent
03930a2
commit 93d1c27
Showing
1 changed file
with
116 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#!/bin/sh | ||
# Written by Filipe Laborde, [email protected] | ||
# Date: March, 2020 | ||
# License: MIT | ||
# Use as you wish, all risk is yours. | ||
# Compatible with unix based systems (Mac, Ubuntu, Debian, etc.) | ||
# | ||
# Usage: ./video-joiner.sh [output.mp4] | ||
# It will prompt for the files to append together | ||
|
||
file_out=$1 | ||
if [ "${#1}" -eq 0 ]; then | ||
echo "ERROR: Please give the output filename, ex. ./video-joiner.sh output.mp4" | ||
exit | ||
fi | ||
|
||
# init | ||
starttime=`date +%s` | ||
ffmpeg_file_list="ffmpeg_list.txt" | ||
rm -f $ffmpeg_file_list | ||
touch $ffmpeg_file_list | ||
|
||
## check for dependencies - check expected paths ## | ||
dep_path=("/usr/local/bin/" "/usr/local/opt/" "/usr/bin/" "/usr/share/") | ||
has_ffmpeg=0 | ||
has_ffprobe=0 | ||
for dep in ${dep_path[*]}; do | ||
if [ -x "${dep}ffmpeg" ]; then has_ffmpeg=1; fi | ||
if [ -x "${dep}ffprobe" ]; then has_ffprobe=1; fi | ||
done | ||
|
||
if [ $has_ffmpeg -eq 0 ] || [ $has_ffprobe -eq 0 ] ; then | ||
echo "ERROR: Missing 'ffmpeg'/'ffprobe', please install, ex. (linux) apt install ffmpeg, (mac) brew install ffmpeg" | ||
exit | ||
fi; | ||
|
||
## loop through videos to join ## | ||
read -e -r -p "Join how many videos? (1) " total_files | ||
if [ -z $total_files ]; then | ||
total_files=1; | ||
fi | ||
|
||
cmd_cnt=0 | ||
file_idx=1 | ||
while [ $file_idx -le $total_files ]; do | ||
echo "..........................." | ||
|
||
read -e -r -p "$file_idx: What is the video? " filename | ||
file_ext=`echo "${filename##*.}" | tr '[:upper:]' '[:lower:]'` | ||
resolution=`ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 ${filename}` | ||
duration_time=`ffprobe ${filename} 2>&1 | grep -E '^ +Duration' | cut -d':' -f2- | cut -d, -f1- | cut -d'.' -f1` | ||
if [ -z $duration_time ]; then | ||
echo "ERROR: Sorry ${filename} an invalid video file. Quitting." | ||
exit; | ||
fi; | ||
|
||
read -e -r -p " .. info: ${resolution}, ${file_ext}, duration: ${duration_time} -- start at (default 00:00:00): " file_start_time | ||
if [ ! "${#file_start_time}" -eq 0 ] && [ ! "${#file_start_time}" -eq 8 ]; then | ||
echo "ERROR: Invalid start time (${file_start_time}) not in hh:mm:ss format." | ||
exit | ||
fi | ||
|
||
read -e -r -p " .. ok, and truncate video at? (default ${duration_time} [ie end]): " file_end_time | ||
if [ ! "${#file_end_time}" -eq 0 ] && [ ! "${#file_end_time}" -eq 8 ]; then | ||
echo "ERROR: Invalid end time (${file_end_time}) not in hh:mm:ss format." | ||
exit | ||
fi | ||
|
||
# build temp file using extracted portion of video (or codec change) | ||
if [ "${#file_start_time}" -eq 0 ] && [ "${#file_end_time}" -eq 0 ] && [ $file_ext="mp4" ]; then | ||
echo "file ${filename}" >> $ffmpeg_file_list | ||
else | ||
cmd="ffmpeg -hide_banner -loglevel panic -stats " | ||
if [ "${#file_start_time}" -eq 8 ]; then | ||
cmd+="-ss ${file_start_time} " | ||
fi | ||
cmd+="-i ${filename} " | ||
if [ "${#file_end_time}" -eq 8 ]; then | ||
cmd+="-to ${file_end_time} " | ||
fi | ||
if [ $file_ext="mp4" ]; then | ||
cmd+="-c copy " | ||
fi | ||
tmp_filename=$filename`date +"%s"`".tmp.mp4" | ||
cmd+="${tmp_filename}" | ||
|
||
cmd_list[cmd_cnt]="${cmd}" | ||
((cmd_cnt++)) | ||
tmp_file_set+=($tmp_filename) | ||
echo "file ${tmp_filename}" >> $ffmpeg_file_list | ||
fi | ||
((file_idx++)) | ||
done | ||
|
||
# final operation is a join | ||
cmd_list[cmd_cnt]="ffmpeg -hide_banner -loglevel panic -stats -f concat -i $ffmpeg_file_list -c copy ${file_out}" | ||
|
||
# now do any individual video modifications and join | ||
echo "++++++++++++++++++++" | ||
echo "Preparing video operations (have patience...)" | ||
|
||
for cmd in "${cmd_list[@]}" | ||
do | ||
$cmd | ||
done | ||
|
||
# deleting temp files | ||
for file in ${tmp_file_set[*]} | ||
do | ||
rm $file | ||
done | ||
|
||
endtime=`date +%s` | ||
runtime=$((endtime-starttime)) | ||
echo "COMPLETE! Written ${file_out} in ${runtime} s" | ||
|