Created
December 30, 2020 11:37
-
-
Save heikomat/8b26b825679693562d7cbdcbdc41549d to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
ROOT_FOLDER="${1}" | |
SOURCE_FOLDER="${ROOT_FOLDER}/${2}" | |
CACHE_FOLDER="${ROOT_FOLDER}/${3}" | |
TARGET_FOLDER="${ROOT_FOLDER}/${4}" | |
TARGET_BITRATE="${5}" | |
# abort, if there is a lock file | |
LOCKFILE="${ROOT_FOLDER}/converting.lock" | |
if [ -f "${LOCKFILE}" ]; then | |
LOCKFILE="${ROOT_FOLDER}/converting2.lock" | |
fi | |
if [ -f "${LOCKFILE}" ]; then | |
LOCKFILE="${ROOT_FOLDER}/converting3.lock" | |
fi | |
if [ -f "${LOCKFILE}" ]; then | |
exit 0; | |
fi | |
if [ -z "${TARGET_BITRATE}" ]; then | |
TARGET_BITRATE="4000" | |
fi | |
TARGET_BUFSIZE=$(bc -l <<< "${TARGET_BITRATE} * 2") | |
function findFirstUnconvertedMovie { | |
# find all mkv, mp4 and avi files in SOURCE_FOLDER and its subfolders | |
for file in ${SOURCE_FOLDER}/{**/*,**/**/*,*}.{mkv,mp4,avi,m2ts}; do | |
[ -e "$file" ] || continue # if glob doesn't match, continue | |
relative_file_path=$(realpath --no-symlinks --relative-to="${SOURCE_FOLDER}" "${file}") | |
[ -f "${CACHE_FOLDER}/${relative_file_path}.txt" ] && continue # if the file has been converted before, continue | |
echo "$relative_file_path" | |
return 0 | |
done | |
} | |
function convertMovie { | |
target_folder=$(dirname "${CACHE_FOLDER}/${1}") | |
mkdir --parents "${target_folder}" | |
base_filename=${1%.*} | |
color_space=$(mediainfo "${SOURCE_FOLDER}/${1}" --Inform="Video;%colour_primaries%") | |
video_filter="zscale=width='min(1920,iw)':height=-2:filter=lanczos" | |
if [ "$color_space" = "BT.2020" ]; then | |
# this is an HDR video, apply tone mapping | |
video_filter="${video_filter},zscale=transfer=linear:npl=140,tonemap=tonemap=hable:desat=5.0,zscale=primaries=bt709:transfer=bt709:matrix=bt709:range=limited:dither=ordered,format=yuv420p" | |
fi | |
nice -19 \ | |
ffmpeg -probesize 100000000 `# prevent the probing of the video info from failing by allowing a larger portion of it to be probed` \ | |
-analyzeduration 100000000 `# prevent the analyzing of the video info from failing by allowing a larger portion of it to be analyzed` \ | |
-i "${SOURCE_FOLDER}/${1}" \ | |
-map 0:V:0 `# take first non-picture video stream` \ | |
-map 0:a `# take all audio streams` \ | |
-map 0:d? `# take all data streams` \ | |
-map 0:s? `# take all subtitle streams` \ | |
-crf 17 \ | |
-c:a copy \ | |
-c:s copy \ | |
-vf "${video_filter}" `# apply 1080p-scaling and possibly colorspace mapping` \ | |
-threads 12 \ | |
-preset veryslow `# get the best possible quality out of the available bitrate` \ | |
-profile:v high `# "high10" is not supported everywhere, "main" and "baseline" don't allow for 1080p, so "high" it is` \ | |
-level:v 4.0 `# older devices don't support levels > 4.1, see https://support.plex.tv/articles/204377253-what-media-formats-are-supported/` \ | |
-pix_fmt yuv420p `# force color depths of 8-bit` \ | |
-movflags faststart `# move metadata of the video to the start for faster playback starting` \ | |
-max_muxing_queue_size 4000 `# prevent "Too many packets buffered for output"` \ | |
-maxrate "${TARGET_BITRATE}"k \ | |
-bufsize "${TARGET_BUFSIZE%.*}"k \ | |
"${CACHE_FOLDER}/${base_filename}.mkv"\ | |
2> "${CACHE_FOLDER}/${1}.txt" | |
} | |
target_movie=$(findFirstUnconvertedMovie) | |
echo "$target_movie" | |
if [ -z "${target_movie}" ]; then | |
# There is no more movie that needs converting, lift the lock and exit | |
exit 0 | |
fi | |
# create the lock file, so no one else tries converting while we are | |
touch "${LOCKFILE}" | |
convertMovie "$target_movie" | |
# copy the converted movie to the destination folder | |
target_folder=$(dirname "${TARGET_FOLDER}/${target_movie}") | |
target_filename="${target_movie%.*}.mkv" | |
mkdir --parents "${target_folder}" | |
mv --force "${CACHE_FOLDER}/${target_filename}" "${TARGET_FOLDER}/${target_filename}" | |
# lift the lock | |
rm "${LOCKFILE}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment