-
-
Save jlnbxn/edd16f23a521bed42d9ac1ae461f312b to your computer and use it in GitHub Desktop.
Bash script to merge all mp4 videos in current directory (recursively 2 levels). It also updates the chapter marks to retain the folder/filename of source dir
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
#!/bin/bash | |
#http://redsymbol.net/articles/unofficial-bash-strict-mode/ | |
set -euo pipefail | |
IFS=$'\n\t' | |
## Script to merge all mp4 videos in current directory (recursively 2 levels) | |
## And update chapter marks to retain the folder/filename | |
## Script for merging videos | |
temp_dir=$(mktemp -d) | |
function finish { | |
rc=$? | |
if [[ $rc != 0 ]]; then | |
echo | |
echo "FAILED!" | |
fi | |
echo -n "Cleaning up " | |
rm -rf "${temp_dir}" | |
echo "..........[ DONE ]" | |
exit $rc | |
} | |
trap finish EXIT | |
current_dir=$(pwd) | |
bname=$(basename ${current_dir}) | |
final_mp4=${bname}.mp4 | |
input_list=${temp_dir}/${bname}-input_list.txt | |
file_list=${temp_dir}/${bname}-file_list | |
meta_file=${temp_dir}/${bname}-metadata.txt | |
#Hopefully this will work for either BSD or GNU sed | |
extended_match="-r" | |
echo "" | sed ${extended_match} 's|foo|bar|' 2>/dev/null || extended_match="-E" | |
if [ -e "${final_mp4}" ]; then | |
echo "${final_mp4} already exists, please remove it." | |
exit 1 | |
fi | |
echo -n "Generating file lists " | |
find . -maxdepth 2 -type f -iname '*.mp4' | sort -V | | |
sed -e "s|^./||" | | |
tee "${file_list}" | | |
sed -e "s;';'\\\'';g" | # Escape single quotes in filenames | |
awk "{printf \"file '${current_dir}/%s'\n\", \$0}" > "${input_list}" | |
echo "..........[ DONE ]" | |
cat -n "${file_list}" | |
## chapter marks | |
#Do this first so we fail early | |
#TODO: Test (‘=’, ‘;’, ‘#’, ‘\’) are escaped | |
ts=0 | |
echo -n "Generating chapter marks " | |
echo -n "" | |
ffmpeg -i "$(head -1 "${file_list}")" -f ffmetadata "${meta_file}" -v quiet | |
cat "${file_list}" | while read file | |
do | |
ds=$(ffprobe -v quiet -of csv=p=0 -show_entries format=duration "${file}") | |
# echo "$ds" | |
escaped_title=$(echo ${file} | sed ${extended_match} -e 's|([=;#])|\\\1|g' -e 's|.[Mm][Pp]4$||' ) | |
echo "[CHAPTER]" >> "${meta_file}" | |
echo "TIMEBASE=1/1" >> "${meta_file}" | |
echo "START=${ts}" >> "${meta_file}" | |
ts=$(awk "BEGIN {print ${ts}+${ds}; exit}") | |
echo "END=${ts}" >> "${meta_file}" | |
echo "TITLE=${escaped_title}" >> "${meta_file}" | |
done | |
echo "..........[ DONE ]" | |
# input_list=$(sed -e "s/file '/'bar'/g" "${input_list}" ) | |
cat -n "${input_list}" | |
echo -n "Merging the files " | |
ffmpeg -f concat -safe 0 -i "${input_list}" -i "${meta_file}" -map_metadata 1 -codec copy "${final_mp4}" -v quiet | |
echo "..........[ DONE ]" | |
echo "Job Completed." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment