This commit is contained in:
root 2022-10-11 07:44:28 +07:00
parent ab642d9c51
commit 9abad2f998
13 changed files with 57 additions and 41 deletions

6
.gitignore vendored
View File

@ -1,7 +1,7 @@
countdown countdown
mailhash accounts
vars vars
mailer.log mailer.log
web.log
process.log process.log
uploadpage/streams/* upload.log
web/streams/*

View File

@ -4,10 +4,9 @@
%interface% { %interface% {
log { log {
output file /var/www/web.log output file /var/www/upload.log
format console
} }
php_fastcgi 127.0.0.1:9000 php_fastcgi 127.0.0.1:9000
root * /var/www/uploadpage root * /var/www/web
file_server file_server
} }

View File

@ -1,8 +1,8 @@
# Build image: # Build image:
# docker build -t streamupload . # docker build -t streamupload .
# Run container, one of: # Run container, one of:
# docker run -d --name stream -p 8080:80 -v $PWD/uploadpage:/var/www/uploadpage streamupload # docker run -d --name stream -p 8080:80 -v $PWD/web:/var/www/web streamupload
# docker run -d --name stream -p 443:443 -v $PWD/uploadpage:/var/www/uploadpage streamupload # docker run -d --name stream -p 443:443 -v $PWD/web:/var/www/web streamupload
# Access shell in container: # Access shell in container:
# docker exec -ti stream /bin/bash # docker exec -ti stream /bin/bash
# Destroy container and image: # Destroy container and image:
@ -16,5 +16,5 @@ ADD https://good4.eu/mailer /usr/local/bin/mailer
ADD https://good4.eu/caddy /usr/local/bin/caddy ADD https://good4.eu/caddy /usr/local/bin/caddy
COPY Caddyfile Dockerfile /root/ COPY Caddyfile Dockerfile /root/
WORKDIR /var/www WORKDIR /var/www
COPY encode init stream vars mailhash ./ COPY encode init stream vars accounts ./
ENTRYPOINT ./init ENTRYPOINT ./init

View File

@ -13,18 +13,18 @@
* Move the `streamupload` directory to a place that is accessible to the web * Move the `streamupload` directory to a place that is accessible to the web
server, like: `mv streamupload /var/www` and `cd` to that place. Now the server, like: `mv streamupload /var/www` and `cd` to that place. Now the
output of `pwd` is the value for `$repopath`. output of `pwd` is the value for `$repopath`.
* do `mkdir "$repopath/uploadpage/streams"` and * do `mkdir "$repopath/web/streams"` and
`chmod 777 "$repopath/uploadpage/streams"`. `chmod 777 "$repopath/web/streams"`.
* Copy `_vars` to `vars`, `_mailhash` to `mailhash` and `_countdown` to * Copy `_vars` to `vars`, `_accounts` to `accounts` and `_countdown` to
`countdown` and set the variables in `vars` (webserver, SMTP-server), `countdown` and set the variables in `vars` (webserver, SMTP-server),
`mailhash` (usernames, emails and bcrypt-password-hashes) and `countdown` `accounts` (usernames, emails and bcrypt-password-hashes) and `countdown`
(if any countdown-files can be used). (if any countdown-files can be used).
* Make a crontab-entry: "* * * * * $repopath/encode" (replace `$repopath`!). * Make a crontab-entry: "* * * * * $repopath/encode" (replace `$repopath`!).
* Install the `mailer` binary by downloading it from the repo at * Install the `mailer` binary by downloading it from the repo at
https://https://github.com/pepa65/mailer/releases/latest and moving it to https://https://github.com/pepa65/mailer/releases/latest and moving it to
`/usr/local/bin` and make it executable: `chmod +x /usr/local/bin/mailer`. `/usr/local/bin` and make it executable: `chmod +x /usr/local/bin/mailer`.
If it's not installed, everything (except the emails) will still work. If it's not installed, everything (except the emails) will still work.
* Run a php/webserver on `$repopath/uploadpage`: * Run a php/webserver on `$repopath/web`:
- Get it to restart on reboot. - Get it to restart on reboot.
- Change the relevant `php.ini` to allow large file uploads: - Change the relevant `php.ini` to allow large file uploads:
* `post_max_size` - Upper limit of uploaded video sizes, say `10G`. * `post_max_size` - Upper limit of uploaded video sizes, say `10G`.
@ -42,10 +42,10 @@ Make the config file `/root/Caddyfile` like:
:80 { :80 {
log { log {
output file $repopath/web.log output file $repopath/upload.log
} }
php_fastcgi unix//run/php/php-fpm.sock php_fastcgi unix//run/php/php-fpm.sock
root * $repopath/uploadpage root * $repopath/web
file_server file_server
} }
``` ```
@ -75,10 +75,10 @@ killall -9 caddy &>/dev/null
### Docker ### Docker
After cloning this repo, `cd streamupload`, and setting the variables in `vars` and After cloning this repo, `cd streamupload`, and setting the variables in `vars` and
`mailhash`, a docker image can be built from the included `Dockerfile` by: `accounts`, a docker image can be built from the included `Dockerfile` by:
`docker build -t streamupload .`. In the case of running on a LAN and not having a `docker build -t streamupload .`. In the case of running on a LAN and not having a
DNS A record, start it with: DNS A record, start it with:
`docker run -d -p 8080:80 -v $PWD/uploadpage:/var/www/uploadpage streamupload`. `docker run -d -p 8080:80 -v $PWD/web:/var/www/web streamupload`.
In case of a domainname, replace `8080:80` by `443:443`. In case of a domainname, replace `8080:80` by `443:443`.
## Usage ## Usage
@ -86,5 +86,5 @@ In case of a domainname, replace `8080:80` by `443:443`.
(supported are: Restream.io, YouTube.com, Facebook.com). (supported are: Restream.io, YouTube.com, Facebook.com).
* Go to the server's URL in the browser: `http://$ipaddress:80` or for docker: * Go to the server's URL in the browser: `http://$ipaddress:80` or for docker:
`http://$ipaddress:80` or in case of a domainname: `https://$domainname`. `http://$ipaddress:80` or in case of a domainname: `https://$domainname`.
* Log in with the username and passwors as prepared in `mailhash`. * Log in with the username and passwors as prepared in `accounts`.
* Fill in the form, and click "Schedule Stream". * Fill in the form, and click "Schedule Stream".

8
encode
View File

@ -2,16 +2,16 @@
set +vx 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 ./web/streams)
# Required: file coreutils(readlink ls head mv tail rm) cron(crontab) date ffmpeg # Required: file coreutils(readlink ls head mv tail rm) cron(crontab) date ffmpeg
# mailer[gitlab.com/pepa65/mailer] # mailer[gitlab.com/pepa65/mailer]
# Check for oldest uploaded file # Check for oldest uploaded file
_=$(readlink -f -- "${BASH_SOURCE:-$0}") repopath=${_%/*} _=$(readlink -f -- "${BASH_SOURCE:-$0}") repopath=${_%/*}
log=$repopath/process.log dir=$repopath/uploadpage/streams log=$repopath/process.log dir=$repopath/web/streams
upload=$(ls -Atr "$dir"/*.upload 2>/dev/null |head -1) upload=$(ls -Atr "$dir"/*.upload 2>/dev/null |head -1)
# Finished if no uploadpage/streams/*.upload files found # Finished if no web/streams/*.upload files found
[[ $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
@ -22,7 +22,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
local lines line message sbj msg to from="Stream Upload server" user password smtp port ssltls bcc 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 source "$repopath/vars" # I:user,password,smtp,port,ssltls,bcc
mapfile -t lines <"$repopath/mailhash" mapfile -t lines <"$repopath/accounts"
for line in "${lines[@]}" for line in "${lines[@]}"
do [[ ${line:0:1} = '#' ]] && continue do [[ ${line:0:1} = '#' ]] && continue
[[ $username = ${line%%$'\t'*} ]] && _=${line#*$'\t'} to=${_%$'\t'*} && break [[ $username = ${line%%$'\t'*} ]] && _=${line#*$'\t'} to=${_%$'\t'*} && break

6
stream
View File

@ -2,7 +2,7 @@
# stream - Stream video when called from crontab # stream - Stream video when called from crontab
# Usage: stream <tag> # Usage: stream <tag>
# The tag refers to video files in ./uploadpage/streams without the # The tag refers to video files in ./web/streams without the
# '.mp4', that should have been re-encoded by `encode`. The tag has no path # '.mp4', that should have been re-encoded by `encode`. The tag has no path
# information, has the "streamkey" at the start before the first dot (there # information, has the "streamkey" at the start before the first dot (there
# 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 '@'.
@ -11,7 +11,7 @@
_=$(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/web/streams/$1.mp4 key=${1%%.*} target=${1##*@}
case $target in case $target in
Facebook) rtmp=rtmps://live-api-s.facebook.com:443/rtmp/$key ;; Facebook) rtmp=rtmps://live-api-s.facebook.com:443/rtmp/$key ;;
YouTube) rtmp=rtmp://a.rtmp.youtube.com/live2/$key ;; YouTube) rtmp=rtmp://a.rtmp.youtube.com/live2/$key ;;
@ -25,7 +25,7 @@ set -o pipefail # to get ffmpeg's returncode
if 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"
then then
rm "$in.log" "${in%.mp4}" rm "$in.log" "${in%.mp4}"
[[ $savedir && -f $savedir ]] && mv "$in" "$savedir" || rm "$in" [[ $savedir && -d $savedir ]] && mv "$in" "$savedir" || rm "$in"
else else
echo "Error while streaming $1" >>"$log" echo "Error while streaming $1" >>"$log"
fi fi

View File

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

View File

@ -34,6 +34,7 @@ function filename(){
<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>');
if($user!=='library' && $user!=='pp'){ ///////////////////////////////
// Check countdown options // Check countdown options
$cf=file(__DIR__.'/../countdown',FILE_IGNORE_NEW_LINES & FILE_SKIP_EMPTY_LINES); $cf=file(__DIR__.'/../countdown',FILE_IGNORE_NEW_LINES & FILE_SKIP_EMPTY_LINES);
$n=0; $n=0;
@ -65,6 +66,9 @@ print(' <select name="target" required title="Click to select where to stream
<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">');
}else{ //////////////////////////////////
print(' <input type="submit" value="Upload" name="schedule">'); ///////////////////////
} ////////////////////////////////////
print(' <p id="response">&nbsp;</p> print(' <p id="response">&nbsp;</p>
</form> </form>
</div> </div>

View File

@ -3,7 +3,7 @@ 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__.'/../accounts',FILE_IGNORE_NEW_LINES & FILE_SKIP_EMPTY_LINES);
foreach($mh as $line){ foreach($mh as $line){
if(substr($line, 0, 1)!='#'){ if(substr($line, 0, 1)!='#'){
$field=explode("\t", trim($line, "\n")); $field=explode("\t", trim($line, "\n"));

View File

@ -7,18 +7,21 @@ if(!isset($_POST['schedule']) || empty($user)){ // If not post: start again
function Back($msg){ function Back($msg){
if(empty($msg)){ if(empty($msg)){
print('<p style="padding:5px;background-color:green;color:white"><b>File successfully uploaded, encoding started</b></p>'); print('
<p style="padding:5px;background-color:green;color:white"><b>File successfully uploaded, encoding started</b></p>');
}else{ }else{
print('<p style="padding:5px;background-color:red;color:white"><b>ERROR: '.$msg.'</b></p>'); print('
<p style="padding:5px;background-color:red;color:white"><b>ERROR: '.$msg.'</b></p>');
} }
print('<form action="index.php" method="post"> print('
<input type="submit" value="Upload another file" name="submit" autofocus> <form action="index.php" method="post">
</form></div>'); <input type="submit" value="Upload another file" name="submit" autofocus>
</form></div>');
exit; exit;
} }
// Get mails // Get mails
$mh=file(__DIR__.'/../mailhash',FILE_IGNORE_NEW_LINES & FILE_SKIP_EMPTY_LINES); $mh=file(__DIR__.'/../accounts',FILE_IGNORE_NEW_LINES & FILE_SKIP_EMPTY_LINES);
foreach($mh as $line){ foreach($mh as $line){
if(substr($line, 0, 1)!='#'){ if(substr($line, 0, 1)!='#'){
$field=explode("\t", $line); $field=explode("\t", $line);
@ -50,6 +53,12 @@ $min=substr($time, 3, 2);
$tme=$hour.$min; $tme=$hour.$min;
$dir='streams/'; $dir='streams/';
$name=$key.'.'.$date.'_'.$tme.$id.$user.$email.'@'.$target; $name=$key.'.'.$date.'_'.$tme.$id.$user.$email.'@'.$target;
if($user=='library' || $user=='pp'){ ////////////////////////
move_uploaded_file($_FILES['file']['tmp_name'], $dir.'video.'.$user);
sleep(15);
session_unset();
header('Location: login.php');
} ///////////////////////
$file=$dir.$name.'.upload'; $file=$dir.$name.'.upload';
print('<!DOCTYPE html> print('<!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
@ -59,9 +68,10 @@ print('<!DOCTYPE html>
<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="login.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>
<h1>Encoding</h1> <div class="container">
<p>Uploaded <b>'.$upload.'</b></p>'); <h1>Encoding</h1>
<p>Uploaded <b>'.$upload.'</b></p>');
if(preg_match('/20[0-9][0-9]-[0-1][0-9]-[0-3][0-9]/', $date)===false){ if(preg_match('/20[0-9][0-9]-[0-1][0-9]-[0-3][0-9]/', $date)===false){
Back('Date somehow incorrect: '.$date); Back('Date somehow incorrect: '.$date);
} }
@ -83,12 +93,15 @@ 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>'); print('
<p>Streaming <b>'.$name.'.mp4</b>');
if(isset($countdown)){ if(isset($countdown)){
print('<br><br>using <b>'.$countdown.'</b>'); print('
<br><br>using <b>'.$countdown.'</b>');
} }
print('</p> print('
<p>When done encoding, email <b>'.$to.'</b></p> </p>
<p>Streaming on <b>'.$date.'</b> at <b>'.$time.'</b>h on <b>'.$target.'</b></p>'); <p>When done encoding, email <b>'.$to.'</b></p>
<p>Streaming on <b>'.$date.'</b> at <b>'.$time.'</b>h on <b>'.$target.'</b></p>');
Back(''); Back('');
?> ?>