Email on start encode Encode audio 48000 bps Clearly show error or success in Results page Optional savedir
105 lines
4.7 KiB
Bash
Executable File
105 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set +vx
|
|
# 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 -Atr "$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 -e "$(date +'%m/%d %H:%M:%S') $1">>"$log"
|
|
[[ $2 ]] && exit $2 || return 0
|
|
}
|
|
|
|
Mail(){ # 1:kind(0:done, 1:wrong type, 2:encoding error) 2:logline I:repopath,email,username,name,type,start,finish
|
|
local lines line message sbj msg to from="Stream Upload server" user password smtp port ssltls bcc
|
|
source "$repopath/vars" # I:user,password,smtp,port,ssltls,bcc
|
|
mapfile -t lines <"$repopath/mailhash"
|
|
for line in "${lines[@]}"
|
|
do [[ ${line:0:1} = '#' ]] && continue
|
|
[[ $username = ${line%%$'\t'*} ]] && _=${line#*$'\t'} to=${_%$'\t'*} && break
|
|
done
|
|
# If email given, strip ':'
|
|
[[ $email ]] && to=${email:1}
|
|
[[ $port ]] || port=587
|
|
# If ssltls is not empty, switch to SSL/TLS
|
|
[[ $ssltls ]] && ssltls='-T'
|
|
[[ $bcc ]] && bcc="-b $bcc"
|
|
sbj[0]="Stream Upload encoding done for ${name##*@}"
|
|
sbj[1]="Stream Upload file wrong type: $type"
|
|
sbj[2]="Stream Upload error encoding"
|
|
sbj[3]="Stream Upload encoding started"
|
|
msg[0]="Encoded video with tag '$name'.\nEncoding started on $start and finished on $finish."
|
|
msg[1]="The file '$name' from $start is of type '$type' and could not be used."
|
|
msg[2]="The file '$name' started encoding on $start but ran into an error on $finish."
|
|
msg[3]="The file '$name' was received and encoding is starting."
|
|
message="Heya,\n\n${msg[$1]}\n\nStream Upload server\n"
|
|
if [[ $to && $user && $password && $smtp && $port ]]
|
|
then # All required ingredients for a mail present
|
|
/usr/local/bin/mailer -m "$(echo -e "$message")" -t "$to" $bcc -s "${sbj[$1]}" -u "$user" -p "$password" -S "$smtp" -P "$port" $ssltls -f "$from" >>"$repopath/mailer.log"
|
|
err=$?
|
|
((err==0)) && Log "== Mail with subject '${sbj[$1]}' sent to $to"
|
|
((err==1)) && Log "== Mail with subject '${sbj[$1]}' could not be sent"
|
|
((err==2)) && Log "== Mail with subject '${sbj[$1]}' failed to send to: $to"
|
|
else # Can't send
|
|
Log "== Mail with subject '${sbj[$1]}' cannot be sent [$to-$user-$password-$smtp-$port]"
|
|
fi
|
|
|
|
Log "${msg[$1]}"
|
|
# No log, no exit when just mailing to say we're starting
|
|
(($1==3)) || Log "$2" $1
|
|
}
|
|
|
|
# Rename upload and check type
|
|
file=${upload%.upload} video=$file.mp4 name=${file##*/} key=${name%%.*}
|
|
rest=${name#*.} date=${rest:0:15} id=${rest:15:1} _=${rest:16} _=${_%@*} username=${_%%:*} email=${_#$username}
|
|
mv "$upload" "$file"
|
|
|
|
start=$(date +'%Y-%m-%d at %H:%M:%S')
|
|
type=$(file -bL --mime-type "$file")
|
|
[[ ! ${type:0:5} = video ]] && Mail 1 "File $name is of type $type"
|
|
|
|
# Encode video
|
|
Mail 3
|
|
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" |tail -n 20 >"$file.0log" || error=1
|
|
# 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)' -vf "format=yuv420p,scale=1920x1080,setdar=16/9,fps=25" -video_track_timescale 18000 -movflags faststart -ar 48000 -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)' -vf "format=yuv420p,scale=1920x1080,setdar=16/9,fps=25" -video_track_timescale 18000 -movflags faststart -ar 48000 -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"
|
|
|
|
# concatenate countdown
|
|
if [[ ! $id = _ ]]
|
|
then
|
|
countdown=$(ls -tr "$dir/.$id"*.mp4 2>/dev/null |head -1)
|
|
ffmpeg -f concat -safe 0 -i <(echo -e "file '$countdown'\nfile '$video'") -c copy "${video%.mp4}_.mp4" 2>&1 |tail -n 20 >"$file.3log"
|
|
mv "${video%.mp4}_.mp4" "$video"
|
|
fi
|
|
|
|
# Remove tailfiles
|
|
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'"
|