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:
parent
f0279c4ca2
commit
ab642d9c51
3
_vars
3
_vars
@ -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
20
encode
@ -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
10
stream
@ -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 -
|
||||||
|
|||||||
@ -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: <b>'.$user.'</b></p>
|
<div class="user"><p class="user">User: <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"> </p>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>');
|
</div>');
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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: <b>'.$user.'</b></p>
|
<div class="user"><p class="user">User: <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('');
|
||||||
?>
|
?>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user