Add countdown option

Some more checks & safety
Encode for resolution 1920x1080, SAR 16:9, 25 fps, 18000 tbn
This commit is contained in:
pepa65 2022-09-18 09:48:53 +07:00
parent 67be8d8863
commit 7c1f3b372c
7 changed files with 66 additions and 17 deletions

3
.gitignore vendored
View File

@ -1,5 +1,6 @@
vars countdown
mailhash mailhash
vars
mailer.log mailer.log
web.log web.log
process.log process.log

3
_countdown Normal file
View File

@ -0,0 +1,3 @@
# Separated by TABs: id(1 unique character: A-Z, a-z, 0-9) / name[for dropdown menu]
# The id refers to a video in streams whose name starts with a dot followed by the id.
A Two-minute countdown

2
_vars
View File

@ -18,3 +18,5 @@ password='(smtp password)'
smtp='' smtp=''
# Defaults to: '587' # Defaults to: '587'
port='' port=''
# Defaults to; '' (StartTLS)
ssltls='1'

21
encode
View File

@ -20,7 +20,7 @@ Log(){ # 1:message 2:returncode(empty: no exit) I:file
} }
Mail(){ # 1:kind(0:done, 1:wrong type, 2:encoding error) 2:logline I:repopath,email,username,name,type,start,finish Mail(){ # 1:kind(0:done, 1:wrong type, 2:encoding error) 2:logline I:repopath,email,username,name,type,start,finish
source "$repopath/vars" # I:user,password,smtp,port source "$repopath/vars" # I:user,password,smtp,port,ssltls
local sbj msg to from="Stream Upload server" local sbj msg to from="Stream Upload server"
mapfile -t <"$repopath/mailhash" mapfile -t <"$repopath/mailhash"
for line in "${MAPFILE[@]}" for line in "${MAPFILE[@]}"
@ -30,6 +30,8 @@ Mail(){ # 1:kind(0:done, 1:wrong type, 2:encoding error) 2:logline I:repopath,em
# If email given, strip ':' # If email given, strip ':'
[[ $email ]] && to=${email:1} [[ $email ]] && to=${email:1}
[[ $port ]] || port=587 [[ $port ]] || port=587
# If ssltls is not empty, switch to SSL/TLS
[[ $ssltls ]] && $ssltls='-T'
sbj[0]="Stream Upload encoding done for ${name##*@}" sbj[0]="Stream Upload encoding done for ${name##*@}"
sbj[1]="Stream Upload file wrong type: $type" sbj[1]="Stream Upload file wrong type: $type"
sbj[2]="Stream Upload error encoding" sbj[2]="Stream Upload error encoding"
@ -38,7 +40,7 @@ Mail(){ # 1:kind(0:done, 1:wrong type, 2:encoding error) 2:logline I:repopath,em
msg[2]="Heya,\n\nThe file '$name' started encoding on $start but ran into an error on $finish.\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 ]] if [[ $to && $user && $password && $smtp && $port ]]
then # All ingredients for a mail present then # All ingredients for a mail present
/usr/local/bin/mailer -m "$(echo -e "${msg[$1]}")" -t "$to" -s "${sbj[$1]}" -u "$user" -p "$password" -S "$smtp" -P "$port" -f "$from" 2>"$repopath/mailer.log" && /usr/local/bin/mailer -m "$(echo -e "${msg[$1]}")" -t "$to" -s "${sbj[$1]}" -u "$user" -p "$password" -S "$smtp" -P "$port" $ssltls -f "$from" 2>"$repopath/mailer.log" &&
Log "== Mail with subject '${sbj[$1]}' sent to $to" || Log "== Mail with subject '${sbj[$1]}' sent to $to" ||
Log "== Mail with subject '${sbj[$1]}' failed to send to: $to" Log "== Mail with subject '${sbj[$1]}' failed to send to: $to"
Log "Start encoding on $start, finished on $finish" Log "Start encoding on $start, finished on $finish"
@ -51,7 +53,7 @@ Mail(){ # 1:kind(0:done, 1:wrong type, 2:encoding error) 2:logline I:repopath,em
# Rename upload and check type # Rename upload and check type
file=${upload%.upload} video=$file.mp4 name=${file##*/} key=${name%%.*} file=${upload%.upload} video=$file.mp4 name=${file##*/} key=${name%%.*}
rest=${name#*.} date=${rest:0:15} _=${rest:16} _=${_%@*} username=${_%%:*} email=${_#$username} rest=${name#*.} date=${rest:0:15} id=${rest:15:1} _=${rest:16} _=${_%@*} username=${_%%:*} email=${_#$username}
mv "$upload" "$file" mv "$upload" "$file"
type=$(file -bL --mime-type "$file") type=$(file -bL --mime-type "$file")
@ -63,8 +65,8 @@ start=$(date +'%Y-%m-%d at %H:%M:%S') error=0
#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 #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 # Double pass
set -o pipefail # to get ffmpeg's returncode 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 -vf "format=yuv420p,scale=1920x1080,setdar=16/9,fps=25" -video_track_timescale 18000 -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" || ffmpeg -y -i "$file" -c:v libx264 -x264opts no-scenecut -vf "format=yuv420p,scale=1920x1080,setdar=16/9,fps=25" -video_track_timescale 18000 -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 error=1
# Remove logfiles # Remove logfiles
@ -72,6 +74,15 @@ rm "$file"-*
finish=$(date +'%Y-%m-%d at %H:%M:%S') finish=$(date +'%Y-%m-%d at %H:%M:%S')
((error)) && Mail 2 "Error encoding $name" ((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
Log ".. $id $countdown $video"
# Remove tailfiles if no errors # Remove tailfiles if no errors
rm -- "$file".?log rm -- "$file".?log

View File

@ -1,6 +1,10 @@
<?php // Schedule page <?php // Schedule page
require "check.php"; require "check.php";
$user=$_SESSION['user']; $user=$_SESSION['user'];
if(empty($user)){
header('Location: login.php');
}
print('<!DOCTYPE html> print('<!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Stream Upload scheduling</title> <title>Stream Upload scheduling</title>
@ -29,8 +33,27 @@ function filename(){
<input id="input" type="file" name="file" required accept=".mp4" onchange="filename()" autofocus> <input id="input" type="file" name="file" required accept=".mp4" onchange="filename()" autofocus>
<input class="abs" id="fakeinput" tabindex="-1"> <input class="abs" id="fakeinput" tabindex="-1">
<p class="abs" id="name">Click to select the video</p> <p class="abs" id="name">Click to select the video</p>
</div> </div>');
<select name="target" id="target" required title="Click to select where to stream to"> // Check countdown options
$cf=file(__DIR__.'/../countdown',FILE_IGNORE_NEW_LINES & FILE_SKIP_EMPTY_LINES);
$n=0;
foreach($cf as $line){
if(substr($line, 0, 1)!='#'){
$field=explode("\t", $line);
$id[$n]=htmlspecialchars($field[0]);
$name[$n++]=htmlspecialchars($field[1]);
}
}
// Populate Countdown dropdown
if($n>0){
print(' <select name="id" title="Click to select an optional countdown">');
print(' <option value="_" selected>No countdown</option>');
for($i=0; $i<$n; ++$i){
print(' <option value="'.$id[$i].$name[$i].'">'.$name[$i].'</option>');
}
print(' </select>');
}
print(' <select name="target" required title="Click to select where to stream to">
<option value="" disabled selected hidden>Streaming Destination</option> <option value="" disabled selected hidden>Streaming Destination</option>
<option value="Restream">Restream</option> <option value="Restream">Restream</option>
<option value="Facebook">Facebook</option> <option value="Facebook">Facebook</option>

View File

@ -1,7 +1,7 @@
<?php // Login page <?php // Login page
session_start(); session_start();
$user=$_POST['user']; $user=$_POST['user'];
if(!empty($user)){ // Login attempt if(!empty($user) && preg_match('/[A-Za-z0-9]+/', $user)!==false){ // Login attempt and valid input
// Read hash and check password // Read hash and check password
$mh=file(__DIR__.'/../mailhash',FILE_IGNORE_NEW_LINES & FILE_SKIP_EMPTY_LINES); $mh=file(__DIR__.'/../mailhash',FILE_IGNORE_NEW_LINES & FILE_SKIP_EMPTY_LINES);
foreach($mh as $line){ foreach($mh as $line){

View File

@ -23,11 +23,16 @@ foreach($mh as $line){
} }
} }
$upload=htmlspecialchars(basename($_FILES['file']['name'])); $upload=htmlspecialchars(basename($_FILES['file']['name']));
$key=$_POST['streamkey']; $key=htmlspecialchars($_POST['streamkey']);
$date=$_POST['date']; $date=htmlspecialchars($_POST['date']);
$time=$_POST['time']; $time=htmlspecialchars($_POST['time']);
$email=$_POST['email']; $email=htmlspecialchars($_POST['email']);
$target=$_POST['target']; $target=htmlspecialchars($_POST['target']);
$id=htmlspecialchars($_POST['id']);
if(substr($id, 0, 1)!=='_'){
$countdown=substr($id, 1);
}
$id=substr($id, 0, 1);
if($email){ if($email){
$to=$email; $to=$email;
$email=':'.$email; $email=':'.$email;
@ -38,7 +43,7 @@ $hour=substr($time, 0, 2);
$min=substr($time, 3, 2); $min=substr($time, 3, 2);
$tme=$hour.$min; $tme=$hour.$min;
$dir='streams/'; $dir='streams/';
$name=$key.'.'.$date.'_'.$tme.'_'.$user.$email.'@'.$target; $name=$key.'.'.$date.'_'.$tme.$id.$user.$email.'@'.$target;
$file=$dir.$name.'.upload'; $file=$dir.$name.'.upload';
print('<!DOCTYPE html> print('<!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
@ -72,7 +77,11 @@ if(!move_uploaded_file($_FILES['file']['tmp_name'], $file)){
Back('Error moving the file'); Back('Error moving the file');
} }
print('<p>Streaming <b>'.$name.'.mp4</b></p>'); print('<p>Streaming <b>'.$name.'.mp4</b>');
print('<p>When done encoding, email <b>'.$to.'</b></p>'); if(isset($countdown)){
print('<br><br>using <b>'.$countdown.'</b>');
}
print('</p>
<p>When done encoding, email <b>'.$to.'</b></p>');
Back('Streaming on <b>'.$date.'</b> at <b>'.$time.'</b>h on <b>'.$target.'</b>'); Back('Streaming on <b>'.$date.'</b> at <b>'.$time.'</b>h on <b>'.$target.'</b>');
?> ?>