84 lines
3.6 KiB
Bash
Executable File
84 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# encode - Encode for streaming and schedule cron job
|
|
# Usage: encode
|
|
# Called by cron every minute; process oldest .upload file in ./uploadpage/streams)
|
|
# Required: file coreutils(readlink ls head mv tail rm) cron(crontab) date ffmpeg
|
|
# mailer[gitlab.com/pepa65/mailer]
|
|
|
|
# Check for oldest uploaded file
|
|
_=$(readlink -f -- "${BASH_SOURCE:-$0}") repopath=${_%/*}
|
|
log=$repopath/process.log dir=$repopath/uploadpage/streams
|
|
upload=$(ls -tr "$dir"/*.upload 2>/dev/null |head -1)
|
|
|
|
# Finished if no uploadpage/streams/*.upload files found
|
|
[[ $upload ]] || exit 0
|
|
|
|
Log(){ # 1:message 2:returncode(empty: no exit) I:file
|
|
echo "$1">>"$log"
|
|
[[ $2 ]] && exit $2 || return 0
|
|
}
|
|
|
|
Mail(){ # 1:kind(0:done, 1:wrong type, 2:encoding error) 2:logline I:repopath,email,name,type,start,finish
|
|
source "$repopath/vars" # I:umail,user,password,smtp,port
|
|
local sbj msg from="Stream Upload server"
|
|
# If proper email set, use it, otherwise it's the authusername: look up email
|
|
[[ $email = *@* ]] && to=$email || to=${umail[$email]}
|
|
[[ $port ]] || port=587
|
|
sbj[0]="Stream Upload encoding done for ${name##*@}"
|
|
sbj[1]="Stream Upload file wrong type: $type"
|
|
sbj[2]="Stream Upload error encoding"
|
|
msg[0]="Heya,\n\nEncoded video with tag '$name'.\nEncoding started on $start and finished on $finish.\n\nStream Upload server"
|
|
msg[1]="Heya,\n\nThe file '$name' from $start is of type '$type' and could not be used.\n\nStream Upload server\n"
|
|
msg[2]="Heya,\n\nThe file '$name' started encoding on $start but ran into an error on $finish.\n\nStream Upload server\n"
|
|
if [[ $to && $user && $password && $smtp && $port ]]
|
|
then
|
|
mailer -m "$(echo -e "${msg[$1]}")" -t "$to" -s "${sbj[$1]}" -u "$user" -p "$password" -S "$smtp" -P "$port" -f "$from" &&
|
|
Log "== Mail with subject '${sbj[$1]}' sent to $to" ||
|
|
Log "== Mail with subject '${sbj[$1]}' failed to send"
|
|
Log "Start encoding on $start, finished on $finish"
|
|
else
|
|
Log "== Mail with subject '${sbj[$1]}' could not be sent"
|
|
(($1==2)) && Log "Start encoding on $start, error on $finish"
|
|
fi
|
|
Log "$2" $1
|
|
}
|
|
|
|
# Rename upload and check type
|
|
file=${upload%.upload} video=$file.mp4 name=${file##*/} key=${name%%.*}
|
|
rest=${name#*.} date=${rest:0:15} _=${rest:15} email=${_%@*}
|
|
mv "$upload" "$file"
|
|
|
|
# Strip the '_' if email set
|
|
[[ $email ]] && email=${email:1}
|
|
|
|
type=$(file -bL --mime-type "$file")
|
|
[[ ! ${type:0:5} = video ]] && Mail 1 "File $name is of type $type"
|
|
|
|
# Encode video
|
|
start=$(date +'%Y-%m-%d at %H:%M:%S') error=0
|
|
## Single pass
|
|
#ffmpeg -y -i "$file" -c:v libx264 -x264opts no-scenecut -b:v 6M -force_key_frames 'expr:gte(t,n_forced*2)' -c:a copy -tune zerolatency -f mp4 "$video" ||
|
|
# Double pass
|
|
set -o pipefail # to get ffmpeg's returncode
|
|
ffmpeg -y -i "$file" -c:v libx264 -x264opts no-scenecut -b:v 6M -maxrate 6M -bufsize 12M -force_key_frames 'expr:gte(t,n_forced*2)' -movflags faststart -c:a copy -tune zerolatency -pass 1 -passlogfile "$file" -f mp4 "$video" 2>&1 |tail -n 20 >"$file.1log" &&
|
|
ffmpeg -y -i "$file" -c:v libx264 -x264opts no-scenecut -b:v 6M -maxrate 6M -bufsize 12M -force_key_frames 'expr:gte(t,n_forced*2)' -movflags faststart -c:a copy -tune zerolatency -pass 2 -passlogfile "$file" -f mp4 "$video" 2>&1 |tail -n 20 >"$file.2log" ||
|
|
error=1
|
|
|
|
# Remove logfiles
|
|
rm "$file"-*
|
|
finish=$(date +'%Y-%m-%d at %H:%M:%S')
|
|
((error)) && Mail 2 "Error encoding $name"
|
|
|
|
# Remove tailfiles if no errors
|
|
rm -- "$file".?log
|
|
|
|
# Schedule cron job
|
|
m=${date:13:2} m=${m#0} h=${date:11:2} h=${h#0}
|
|
D=${date:8:2} D=${D#0} M=${date:5:2} M=${M#0}
|
|
crontab -l >/dev/null || echo -e "# m h dom mon dow command\n" |crontab -
|
|
line="$m $h $D $M "'*'" $repopath/stream '$name'"
|
|
echo -e "$(crontab -l)\n$line" |crontab -
|
|
|
|
Mail 0 "crontab: '$line'"
|