From 46dd851ef09fcb3c7b68ba2278b7ce443c72a8e0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Paul=20H=C3=A4nsch?= Date: Thu, 28 Oct 2021 16:11:12 +0200 Subject: [PATCH] transcoding when uploading --- page_video.sh | 5 +- transcoding.sh | 144 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+), 1 deletion(-) create mode 100755 transcoding.sh diff --git a/page_video.sh b/page_video.sh index 9e49a6f..7fda30f 100755 --- a/page_video.sh +++ b/page_video.sh @@ -6,6 +6,7 @@ includepage_video="$0" . "$_EXEC/db_channel.sh" . "$_EXEC/db_video.sh" . "$_EXEC/upload.sh" +. "$_EXEC/transcoding.sh" read_channel "$channel" read_video "$video" @@ -36,7 +37,8 @@ read_video "$video" elif [ "$(POST delconfirm)" != confirm ]; then REDIRECT "${_BASE}/channel/$CHANNEL_ID/$VIDEO_ID/#ERROR_NOT_CONFIRMED" elif delete_video "$VIDEO_ID"; then - rm -f -- "$VIDEO_FILE" "$VIDEO_THUMB" "$VIDEO_MP4" "$VIDEO_WEBM" + rm -f -- "$VIDEO_FILE" "$VIDEO_THUMB" "$VIDEO_MP4" "$VIDEO_WEBM" \ + "${VIDEO_MP4%.mp4}".*.mp4 "${VIDEO_WEBM%.webm}".*.webm REDIRECT "${_BASE}/channel/$CHANNEL_ID/#DELETE_CONFIRM" else REDIRECT "${_BASE}/channel/$CHANNEL_ID/$VIDEO_ID/#ERROR_UPDATE_NOLOCK" @@ -52,6 +54,7 @@ if [ "$REQUEST_METHOD" = POST -a "$CHANNEL_ID" -a "$VIDEO_ID" ]; then head -c "$CONTENT_LENGTH" >/dev/null REDIRECT "${_BASE}/channel/$CHANNEL_ID/$VIDEO_ID/#ERROR_UPLOAD_NOCLOBBER" elif UPLOAD "$VIDEO_FILE"; then + transcode "$VIDEO_FILE" REDIRECT "${_BASE}/channel/$CHANNEL_ID/$VIDEO_ID/edit" fi fi diff --git a/transcoding.sh b/transcoding.sh new file mode 100755 index 0000000..70e6be3 --- /dev/null +++ b/transcoding.sh @@ -0,0 +1,144 @@ +#!/bin/sh + +. "${_EXEC}"/cgilite/storage.sh + +transq="$_DATA/transcoding.queue" +tpid="$_DATA/transcoding.pid" + +transcode(){ + local file="$1" + if LOCK "$transq"; then + printf %s\\n "$file" >>"$transq" + RELEASE "$transq" + fi + ( exec >"$_DATA/debug" 2>&1; "$_EXEC/transcoding.sh" run & ) & +} + +transcode_resolutions(){ + local width="$1" height="$2" + resNative='' res1080='' res720='' res480='' res240='' + + if [ $width -lt 426 -a $height -lt 240 ]; then + resNative="${width}x${height}" + elif [ $width -lt 852 -a $height -lt 480 -a \( $width -gt 460 -o $height -gt 260 \) ]; then + resNative="${width}x${height}" + elif [ $width -lt 1280 -a $height -lt 720 -a \( $width -gt 920 -o $height -gt 520 \) ]; then + resNative="${width}x${height}" + elif [ $width -lt 1920 -a $height -lt 1080 -a \( $width -gt 1400 -o $height -gt 790 \) ]; then + resNative="${width}x${height}" + elif [ $width -gt 2200 -o $height -gt 1200 ]; then + resNative="${width}x${height}" + fi + if [ $width -ge 1920 -o $height -ge 1080 -a $((1080 * width / height)) -gt 2048 ]; then + res1080="1920x$((1920 * height / width))" + [ $((${res1080#*x} % 2)) -eq 1 ] && res1080="${res1080%x*}x$((${res1080#*x} + 1))" + elif [ $width -ge 1920 -o $height -ge 1080 ]; then + res1080="$((1080 * width / height))x1080" + [ $((${res1080%x*} % 2)) -eq 1 ] && res1080="$((${res1080%x*} + 1))x${res1080#*x}" + fi + if [ $width -ge 1280 -o $height -ge 720 -a $((720 * width / height)) -gt 1280 ]; then + res720="1280x$((1280 * height / width))" + [ $((${res720#*x} % 2)) -eq 1 ] && res720="${res720%x*}x$((${res720#*x} + 1))" + elif [ $width -ge 1280 -o $height -ge 720 ]; then + res720="$((720 * width / height))x720" + [ $((${res720%x*} % 2)) -eq 1 ] && res720="$((${res720%x*} + 1))x${res720#*x}" + fi + if [ $width -ge 852 -o $height -ge 480 -a $((480 * width / height)) -gt 854 ]; then + res480="854x$((854 * height / width))" + [ $((${res480#*x} % 2)) -eq 1 ] && res480="${res480%x*}x$((${res480#*x} + 1))" + elif [ $width -ge 852 -o $height -ge 480 -a $((480 * width / height)) -ge 850 ]; then + res480="854x480" + elif [ $width -ge 852 -o $height -ge 480 ]; then + res480="$((480 * width / height))x480" + [ $((${res480%x*} % 2)) -eq 1 ] && res480="$((${res480%x*} + 1))x${res480#*x}" + fi + if [ $width -ge 426 -o $height -ge 240 -a $((240 * width / height)) -gt 426 ]; then + res240="426x$((426 * height / width))" + [ $((${res240#*x} % 2)) -eq 1 ] && res240="${res240%x*}x$((${res240#*x} + 1))" + elif [ $width -ge 426 -o $height -ge 240 ]; then + res240="$((240 * width / height))x240" + [ $((${res240%x*} % 2)) -eq 1 ] && res240="$((${res240%x*} + 1))x${res240#*x}" + fi +} + +transcode_run(){ + local file="$1" meta width height cli + resNative='' res1080='' res720='' res480='' res240='' + + meta="$(echo; ffprobe -show_entries stream=width,height "$file" 2>&-)" + width="${meta#*width=}"; width="${width%%${BR}*}" + height="${meta#*height=}"; height="${height%%${BR}*}" + + transcode_resolutions "$width" "$height" + + file="$(printf %s "$file" |sed "s;';'\\\\'';g")" + cli="-y -nostdin -i '$file'" + [ "$resNative" ] && cli="$cli \\ + -c:v libx264 -vf scale=$resNative -crf 21 -maxrate 20M -c:a aac -q:a 4 '${file%.upload.*}'.native.mp4 \\ + -c:v libvpx -vf scale=$resNative -crf 30 -b:v 0 -c:a libvorbis -q:a 7 '${file%.upload.*}'.native.webm" + [ "$res1080" ] && cli="$cli \\ + -c:v libx264 -vf scale=$res1080 -crf 21 -maxrate 12M -c:a aac -q:a 4 '${file%.upload.*}'.1080p.mp4 \\ + -c:v libvpx -vf scale=$res1080 -crf 30 -b:v 0 -c:a libvorbis -q:a 7 '${file%.upload.*}'.1080p.webm" + [ "$res720" ] && cli="$cli \\ + -c:v libx264 -vf scale=$res720 -crf 20 -maxrate 7M -c:a aac -q:a 3 '${file%.upload.*}'.720p.mp4 \\ + -c:v libvpx -vf scale=$res720 -crf 28 -b:v 0 -c:a libvorbis -q:a 6 '${file%.upload.*}'.720p.webm" + [ "$res480" ] && cli="$cli \\ + -c:v libx264 -vf scale=$res480 -crf 20 -maxrate 4M -c:a aac -q:a 3 '${file%.upload.*}'.480p.mp4 \\ + -c:v libvpx -vf scale=$res480 -crf 28 -b:v 0 -c:a libvorbis -q:a 6 '${file%.upload.*}'.480p.webm" + [ "$res240" ] && cli="$cli \\ + -c:v libx264 -vf scale=$res240 -crf 19 -maxrate 1M -c:a aac -q:a 2 '${file%.upload.*}'.240p.mp4 \\ + -c:v libvpx -vf scale=$res240 -crf 25 -b:v 0 -c:a libvorbis -q:a 5 '${file%.upload.*}'.240p.webm" + + if eval "ffmpeg $cli"; then + return 0 + else + echo == FFMPEG ERROR == + echo FFMPEG CLI was: + echo ffmpeg "$cli" + echo + return 1 + fi +} + +transcode_link(){ + local file="$1" + if [ "$resNative" ]; then + ln -rs "${file%.upload.*}.native.mp4" "${file%.upload.*}.mp4" + ln -rs "${file%.upload.*}.native.webm" "${file%.upload.*}.webm" + elif [ "$res1080" ]; then + ln -rs "${file%.upload.*}.1080p.mp4" "${file%.upload.*}.mp4" + ln -rs "${file%.upload.*}.1080p.webm" "${file%.upload.*}.webm" + elif [ "$res720" ]; then + ln -rs "${file%.upload.*}.720p.mp4" "${file%.upload.*}.mp4" + ln -rs "${file%.upload.*}.720p.webm" "${file%.upload.*}.webm" + elif [ "$res480" ]; then + ln -rs "${file%.upload.*}.480p.mp4" "${file%.upload.*}.mp4" + ln -rs "${file%.upload.*}.480p.webm" "${file%.upload.*}.webm" + elif [ "$res240" ]; then + ln -rs "${file%.upload.*}.240p.mp4" "${file%.upload.*}.mp4" + ln -rs "${file%.upload.*}.240p.webm" "${file%.upload.*}.webm" + fi +} + +if [ "$1" = run ] && LOCK "$tpid"; then + read pid <"$tpid" + if [ "$pid" -a -d "/proc/$pid/" ]; then + RELEASE "$tpid" + exit 0 + else + printf "%i\n" $$ >"$tpid" + RELEASE "$tpid" + fi + + while read file <"$transq"; do + transcode_run "$file" \ + && transcode_link "$file" + if LOCK "$transq"; then + sed -ni '2,$p' "$transq" + RELEASE "$transq" + fi + done + + rm -- "$tpid" + exit 0 +fi -- 2.39.2