Timestamp to log

Email on start encode
Encode audio 48000 bps
Clearly show error or success in Results page
Optional savedir
This commit is contained in:
root 2022-10-09 12:24:15 +07:00
parent f0279c4ca2
commit ab642d9c51
6 changed files with 50 additions and 28 deletions

3
_vars
View File

@ -11,6 +11,9 @@ interface=''
# Email for registering SSL-certificates # Email for registering SSL-certificates
sslmail='(valid email)' sslmail='(valid email)'
# Directory for saving completed streams
savedir=''
# Variables for mailer # Variables for mailer
user='(smtp login)' user='(smtp login)'
password='(smtp password)' password='(smtp password)'

20
encode
View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set +vx
# encode - Encode for streaming and schedule cron job # encode - Encode for streaming and schedule cron job
# Usage: encode # Usage: encode
# Called by cron every minute; process oldest .upload file in ./uploadpage/streams) # Called by cron every minute; process oldest .upload file in ./uploadpage/streams)
@ -15,7 +15,7 @@ upload=$(ls -Atr "$dir"/*.upload 2>/dev/null |head -1)
[[ $upload ]] || exit 0 [[ $upload ]] || exit 0
Log(){ # 1:message 2:returncode(empty: no exit) I:file Log(){ # 1:message 2:returncode(empty: no exit) I:file
echo -e "$1">>"$log" echo -e "$(date +'%m/%d %H:%M:%S') $1">>"$log"
[[ $2 ]] && exit $2 || return 0 [[ $2 ]] && exit $2 || return 0
} }
@ -36,9 +36,11 @@ Mail(){ # 1:kind(0:done, 1:wrong type, 2:encoding error) 2:logline I:repopath,em
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"
sbj[3]="Stream Upload encoding started"
msg[0]="Encoded video with tag '$name'.\nEncoding started on $start and finished on $finish." 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[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[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" message="Heya,\n\n${msg[$1]}\n\nStream Upload server\n"
if [[ $to && $user && $password && $smtp && $port ]] if [[ $to && $user && $password && $smtp && $port ]]
then # All required ingredients for a mail present then # All required ingredients for a mail present
@ -48,10 +50,12 @@ Mail(){ # 1:kind(0:done, 1:wrong type, 2:encoding error) 2:logline I:repopath,em
((err==1)) && Log "== Mail with subject '${sbj[$1]}' could not be sent" ((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" ((err==2)) && Log "== Mail with subject '${sbj[$1]}' failed to send to: $to"
else # Can't send else # Can't send
Log "== Mail with subject '${sbj[$1]}' cannot be sent" Log "== Mail with subject '${sbj[$1]}' cannot be sent [$to-$user-$password-$smtp-$port]"
fi fi
Log "${msg[$1]}" Log "${msg[$1]}"
Log "$2" $1 # No log, no exit when just mailing to say we're starting
(($1==3)) || Log "$2" $1
} }
# Rename upload and check type # Rename upload and check type
@ -59,17 +63,19 @@ 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} rest=${name#*.} date=${rest:0:15} id=${rest:15:1} _=${rest:16} _=${_%@*} username=${_%%:*} email=${_#$username}
mv "$upload" "$file" mv "$upload" "$file"
start=$(date +'%Y-%m-%d at %H:%M:%S')
type=$(file -bL --mime-type "$file") type=$(file -bL --mime-type "$file")
[[ ! ${type:0:5} = video ]] && Mail 1 "File $name is of type $type" [[ ! ${type:0:5} = video ]] && Mail 1 "File $name is of type $type"
# Encode video # Encode video
start=$(date +'%Y-%m-%d at %H:%M:%S') error=0 Mail 3
error=0
## Single pass ## 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 #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)' -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 -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 -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 -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 error=1
# Remove logfiles # Remove logfiles

10
stream
View File

@ -8,6 +8,7 @@
# has to be a dot!) and the "target" at the very end, after the last '@'. # has to be a dot!) and the "target" at the very end, after the last '@'.
# Required: ffmpeg coreutils(tail rm) # Required: ffmpeg coreutils(tail rm)
_=$(readlink -f -- "${BASH_SOURCE:-$0}") repopath=${_%/*} _=$(readlink -f -- "${BASH_SOURCE:-$0}") repopath=${_%/*}
log=$repopath/process.log log=$repopath/process.log
in=$repopath/uploadpage/streams/$1.mp4 key=${1%%.*} target=${1##*@} in=$repopath/uploadpage/streams/$1.mp4 key=${1%%.*} target=${1##*@}
@ -17,12 +18,17 @@ YouTube) rtmp=rtmp://a.rtmp.youtube.com/live2/$key ;;
RestreamSG) rtmp=rtmp://singapore.restream.io/live/$key ;; RestreamSG) rtmp=rtmp://singapore.restream.io/live/$key ;;
*) rtmp=rtmp://live.restream.io/live/$key *) rtmp=rtmp://live.restream.io/live/$key
esac esac
source "$repopath/vars" # I:savedir
# Stream, log it, and remove all files if successful # Stream, log it, and remove all files if successful
set -o pipefail # to get ffmpeg's returncode set -o pipefail # to get ffmpeg's returncode
ffmpeg -re -y -i "$in" -c:v copy -c:a copy -f flv "$rtmp" 2>&1 |tail -n 20 >"$in.log" && if ffmpeg -re -y -i "$in" -c:v copy -c:a copy -f flv "$rtmp" 2>&1 |tail -n 20 >"$in.log"
rm "$in.log" "$in" "${in%.mp4}" || then
rm "$in.log" "${in%.mp4}"
[[ $savedir && -f $savedir ]] && mv "$in" "$savedir" || rm "$in"
else
echo "Error while streaming $1" >>"$log" echo "Error while streaming $1" >>"$log"
fi
# In any case, comment-out the crontab entry so it's not waiting for next year # In any case, comment-out the crontab entry so it's not waiting for next year
crontab -l| sed "/$1/ s/^/#/" |crontab - crontab -l| sed "/$1/ s/^/#/" |crontab -

View File

@ -1,6 +1,6 @@
<?php // Schedule page <?php // Schedule page
require "check.php"; require "check.php";
$user=$_SESSION['user']; $user=@$_SESSION['user'];
if(empty($user)){ if(empty($user)){
header('Location: login.php'); header('Location: login.php');
} }
@ -22,7 +22,7 @@ function filename(){
} }
</script> </script>
<div class="user"><p class="user">User:&nbsp;<b>'.$user.'</b></p> <div class="user"><p class="user">User:&nbsp;<b>'.$user.'</b></p>
<form action="check.php" method="post"> <form action="login.php" method="post">
<input id="logoff" type="submit" name="logoff" value="Logoff"> <input id="logoff" type="submit" name="logoff" value="Logoff">
</form></div> </form></div>
<div class="container"> <div class="container">
@ -49,7 +49,7 @@ if($n>0){
print(' <select name="id" title="Click to select an optional countdown">'); print(' <select name="id" title="Click to select an optional countdown">');
print(' <option value="_" selected>No countdown</option>'); print(' <option value="_" selected>No countdown</option>');
for($i=0; $i<$n; ++$i){ for($i=0; $i<$n; ++$i){
print(' <option value="'.$id[$i].$name[$i].'">'.$name[$i].'</option>'); print(' <option value="'.$id[$i].'">'.$name[$i].'</option>');
} }
print(' </select>'); print(' </select>');
} }
@ -64,8 +64,8 @@ print(' <select name="target" required title="Click to select where to stream
<input type="date" name="date" title="Enter the date" required> <input type="date" name="date" title="Enter the date" required>
<input type="time" name="time" title="Enter the time" required></div> <input type="time" name="time" title="Enter the time" required></div>
<input type="email" name="email" placeholder="Email to notify" title="Not required"> <input type="email" name="email" placeholder="Email to notify" title="Not required">
<input type="submit" value="Schedule Stream" name="schedule"> <input type="submit" value="Schedule Stream" name="schedule">');
<p id="response"></p> print(' <p id="response">&nbsp;</p>
</form> </form>
</div> </div>
</div>'); </div>');

View File

@ -1,6 +1,6 @@
<?php // Login page <?php // Login page
session_start(); session_start();
$user=$_POST['user']; $user=@$_POST['user'];
if(!empty($user) && preg_match('/[A-Za-z0-9]+/', $user)!==false){ // Login attempt and valid input 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);

View File

@ -1,5 +1,4 @@
<?php // Encode page <?php // Encode page
session_start();
require "check.php"; require "check.php";
$user=$_SESSION['user']; $user=$_SESSION['user'];
if(!isset($_POST['schedule']) || empty($user)){ // If not post: start again if(!isset($_POST['schedule']) || empty($user)){ // If not post: start again
@ -7,8 +6,12 @@ if(!isset($_POST['schedule']) || empty($user)){ // If not post: start again
} }
function Back($msg){ function Back($msg){
print('<p>'.$msg.'</p> if(empty($msg)){
<form action="index.php" method="post"> print('<p style="padding:5px;background-color:green;color:white"><b>File successfully uploaded, encoding started</b></p>');
}else{
print('<p style="padding:5px;background-color:red;color:white"><b>ERROR: '.$msg.'</b></p>');
}
print('<form action="index.php" method="post">
<input type="submit" value="Upload another file" name="submit" autofocus> <input type="submit" value="Upload another file" name="submit" autofocus>
</form></div>'); </form></div>');
exit; exit;
@ -23,16 +26,19 @@ foreach($mh as $line){
} }
} }
$upload=htmlspecialchars(basename($_FILES['file']['name'])); $upload=htmlspecialchars(basename($_FILES['file']['name']));
$key=htmlspecialchars($_POST['streamkey']); $key=htmlspecialchars(@$_POST['streamkey']);
$date=htmlspecialchars($_POST['date']); $date=htmlspecialchars(@$_POST['date']);
$time=htmlspecialchars($_POST['time']); $time=htmlspecialchars(@$_POST['time']);
$email=htmlspecialchars($_POST['email']); $email=htmlspecialchars(@$_POST['email']);
$target=htmlspecialchars($_POST['target']); $target=htmlspecialchars(@$_POST['target']);
$id=htmlspecialchars($_POST['id']); $id=htmlspecialchars(@$_POST['id']);
if(empty($id)){
$id='_';
}
if(substr($id, 0, 1)!=='_'){ if(substr($id, 0, 1)!=='_'){
$countdown=substr($id, 1); $countdown=substr($id, 1);
$id=substr($id, 0, 1);
} }
$id=substr($id, 0, 1);
if($email){ if($email){
$to=$email; $to=$email;
$email=':'.$email; $email=':'.$email;
@ -51,7 +57,7 @@ print('<!DOCTYPE html>
<link rel="icon" href="favicon.png"> <link rel="icon" href="favicon.png">
<link rel="stylesheet" href="page.css"> <link rel="stylesheet" href="page.css">
<div class="user"><p class="user">User:&nbsp;<b>'.$user.'</b></p> <div class="user"><p class="user">User:&nbsp;<b>'.$user.'</b></p>
<form action="check.php" method="post"> <form action="login.php" method="post">
<input id="logoff" type="submit" name="logoff" value="Logoff"> <input id="logoff" type="submit" name="logoff" value="Logoff">
</form></div><div class="container"> </form></div><div class="container">
<h1>Encoding</h1> <h1>Encoding</h1>
@ -82,6 +88,7 @@ if(isset($countdown)){
print('<br><br>using <b>'.$countdown.'</b>'); print('<br><br>using <b>'.$countdown.'</b>');
} }
print('</p> print('</p>
<p>When done encoding, email <b>'.$to.'</b></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>'); <p>Streaming on <b>'.$date.'</b> at <b>'.$time.'</b>h on <b>'.$target.'</b></p>');
Back('');
?> ?>