-
Notifications
You must be signed in to change notification settings - Fork 0
/
encode
executable file
·98 lines (85 loc) · 4.45 KB
/
encode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/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 -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 "$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"
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."
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"
fi
Log "${msg[$1]}"
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"
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" |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 -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)' -vf "format=yuv420p,scale=1920x1080,setdar=16/9,fps=25" -video_track_timescale 18000 -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"
# 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'"