Remake client helpers in Python

This commit is contained in:
Fierelier 2023-12-28 05:27:25 +01:00
parent 8a02ea306e
commit b74431c63e
13 changed files with 263 additions and 145 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
/users/
/users/
/client/config/

View File

@ -1,70 +0,0 @@
#!/usr/bin/env bash
cd "$(dirname "$(realpath "$BASH_SOURCE")")"
sys_python="python3"
function setUser() {
export fstream_arg_user="fier"
export fstream_arg_user_password="123"
}
function setChannel() {
export fstream_arg_channel="default"
export fstream_arg_channel_password="456"
}
export fstream_arg_bufsize="4096"
fstream_aespass=""
enc_resolution="480"
enc_framerate="15"
enc_bitrate="1M"
enc_preset="ultrafast"
enc_cmd=(
ffmpeg
# INPUT
-strict experimental -avioflags direct -thread_queue_size 1 -hwaccel auto -probesize 32 -fflags nobuffer -flags low_delay -flags2 fast # delay hack
-f x11grab -framerate "$enc_framerate" -i "$DISPLAY" # linux
#-f gdigrab -framerate "$enc_framerate" -i desktop # windows
-vf "scale=-2:$enc_resolution"
# ENCODING
-max_probe_packets 0 -max_delay 0 -flags2 fast # delay hack
-c:v libx264 -pix_fmt yuv420p -preset "$enc_preset" -tune zerolatency -x264-params "nal-hrd=cbr" -b:v "$enc_bitrate" -minrate "$enc_bitrate" -maxrate "$enc_bitrate" -bufsize "${enc_bitrate}*2"
-x264opts intra-refresh=1 # delay hack
# OUTPUT
-flags2 fast # delay hack
-f mpegts
-flags2 fast -muxdelay 0 -muxpreload 0 -max_delay 0 -flush_packets 1 # delay hack
-
)
if [ "$fstream_arg_bufsize" == "" ] || [ "$fstream_arg_bufsize" == "0" ]; then
unset fstream_arg_bufsize
fi
export fstream_arg_token=""
setChannel
while :; do
# Get token
export fstream_ssl="1"
export fstream_ssl_ignoreCert="1"
setUser
unset fstream_arg_token
unset fstream_arg_channel
unset fstream_arg_channel_password
export fstream_arg_token="$("$sys_python" fstream.py "fier.me:61921" token)"
unset fstream_arg_user_password
# Broadcast
unset fstream_ssl
unset fstream_ssl_ignoreCert
setChannel
if ! [ "$fstream_aespass" == "" ]; then
"${enc_cmd[@]}" | fstream_aespass="$fstream_aespass" fstream_aesbuffer="$(($fstream_arg_bufsize - 16))" "$sys_python" fstream-util-pipe_to_aes.py | "$sys_python" fstream.py "fier.me:61920" broadcast
else
"${enc_cmd[@]}" | "$sys_python" fstream.py "fier.me:61920" broadcast
fi
sleep 1
done

View File

@ -1,31 +0,0 @@
#!/bin/bash
# USER SETTINGS
BITRATE="8k"
FST_IP="fier.me:61920"
FST_USER="user"
FST_PASSWORD="123"
FST_CHANNEL="default"
FST_CHANNELPASS="456"
PYTHON="python3"
# LINUX:
ARGS_INPUT="-f pulse -i 1"
# WINDOWS:
# ARGS_INPUT="-f gdigrab -framerate "$FRAMERATE" -i desktop"
ARGS_ENCODING="-c:a libopus -ac 1 -vbr off -application lowdelay -mapping_family 0"
ARGS_OUTPUT="-f mpegts"
# APPLY PROPERTIES
ARGS_ENCODING="$ARGS_ENCODING -b:a $BITRATE"
# HACKS - LOWER DELAY
ARGS_INPUT="-strict experimental -avioflags direct -thread_queue_size 1 -hwaccel auto -probesize 32 -fflags nobuffer -flags low_delay -flags2 fast $ARGS_INPUT"
ARGS_ENCODING="-max_probe_packets 0 -max_delay 0 -flags2 fast $ARGS_ENCODING -x264opts intra-refresh=1"
ARGS_OUTPUT="-flags2 fast $ARGS_OUTPUT -flags2 fast -muxdelay 0 -muxpreload 0 -max_delay 0 -flush_packets 1"
ffmpeg $FLAGS_INPUT $ARGS_INPUT $ARGS_ENCODING $ARGS_OUTPUT - | "$PYTHON" fstream.py "$FST_IP" "broadcast,user=$FST_USER,user-password=$FST_PASSWORD,channel=$FST_CHANNEL,channel-password=$FST_CHANNELPASS"

113
client/broadcast.py Executable file
View File

@ -0,0 +1,113 @@
#!/usr/bin/env python3
import sys
import os
p = os.path.join
pUp = os.path.dirname
s = False
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
s = os.path.realpath(sys.executable)
else:
s = os.path.realpath(__file__)
sp = pUp(s)
# script start
import toml
import subprocess
def addressStr(addr):
return addr[0] + ":" + str(addr[1])
def addressSslStr(addr):
return addr[0] + ":" + str(addr[1] + 1)
def perr(rtn,cmd = None,op = None):
if rtn == 0: return
if cmd == None: cmd = []
exc = subprocess.CalledProcessError(rtn,cmd,op)
raise exc
def pcallStr(*args,**kwargs):
proc = subprocess.Popen(*args,**kwargs, stdout=subprocess.PIPE)
response = proc.stdout.read().decode("utf-8").strip("\n")
rtn = proc.wait()
perr(rtn,args[0])
return response
def main():
print("* Parsing config ...")
configFiles = ["broadcast.toml"]
if len(sys.argv) > 1:
configFiles = sys.argv[1:]
length = len(configFiles)
index = 0
while index < length:
configFiles[index] = p(sp,"config",configFiles[index])
index += 1
config = toml.load(configFiles)
for key in config["args"]:
os.environ["fstream_arg_" + key] = str(config["args"][key])
length = len(config["encoder"])
index = 0
while index < length:
if "values" in config:
for key in config["values"]:
config["encoder"][index] = config["encoder"][index].replace("$val:" +key+ "$",str(config["values"][key]))
for key in os.environ:
config["encoder"][index] = config["encoder"][index].replace("$env:" +key+ "$",os.environ[key])
index += 1
ssl = False
if "ssl" in config and "enabled" in config["ssl"] and config["ssl"]["enabled"] != False:
if "ignoreCert" in config["ssl"] and config["ssl"]["ignoreCert"] == True:
os.environ["fstream_ssl_ignoreCert"] = "1"
ssl = True
aes = False
if "aespass" in config:
if not "bufsize" in config["args"]:
print("aespass is set, but args.bufsize is not.")
sys.exit(1)
os.environ["fstream_aespass"] = config["aespass"]
os.environ["fstream_aesbuffer"] = str(config["args"]["bufsize"] - 16)
aes = True
address = config["address"].rsplit(":",1)
address[1] = int(address[1])
if ssl == True:
print("* Getting login-token ...")
os.environ["fstream_ssl"] = "1"
os.environ["fstream_arg_token"] = pcallStr([
sys.executable,
p(sp,"fstream.py"),
addressSslStr(address),
"token"
])
del os.environ["fstream_arg_user_password"]
del os.environ["fstream_ssl"]
procClient = subprocess.Popen([
sys.executable,
p(sp,"fstream.py"),
addressStr(address),
"broadcast"
],stdin=subprocess.PIPE)
if aes == True:
procEncoder = subprocess.Popen(config["encoder"],stdout=subprocess.PIPE)
procAes = subprocess.Popen([
sys.executable,
p(sp,"util","fstream-util-pipe_to_aes.py"),
addressStr(address),
"broadcast"
],stdin=procEncoder.stdout,stdout=procClient.stdin)
else:
procEncoder = subprocess.Popen(config["encoder"],stdout=procClient.stdin)
procEncoder.wait()
main()

View File

@ -0,0 +1,37 @@
# Basic information
address = "fier.me:61920"
args.user = "fier"
args.user_password = "123"
args.channel = "default"
args.channel_password = "456"
args.bufsize = 4096
# Encryption
ssl.enabled = true
ssl.ignoreCert = true
#aespass = "e2epass"
# Encoder values
values.framerate = 30
values.bitrate = "1M"
values.resolution = 480
encoder = [
"ffmpeg",
# INPUT
"-strict","experimental","-avioflags","direct","-thread_queue_size","1","-hwaccel","auto","-probesize","32","-fflags","nobuffer","-flags","low_delay","-flags2","fast", # delay hack
"-f","x11grab","-framerate","$val:framerate$","-i","$env:DISPLAY$", # linux
#"-f","gdigrab","-framerate","$val:framerate$","-i","desktop", # windows
#"-f","v4l2","-input_format","mjpeg","-framerate","$val:framerate$","-video_size","1280x720","-i","/dev/video3",
"-vf","scale=-2:$val:resolution$",
# ENCODING
"-max_probe_packets","0","-max_delay","0","-flags2","fast", # delay hack
"-c:v","libx264","-pix_fmt","yuv420p","-preset","ultrafast","-tune","zerolatency","-x264-params","nal-hrd=cbr","-b:v","1M","-minrate","$val:bitrate$","-maxrate","$val:bitrate$","-bufsize","$val:bitrate$*2",
"-x264opts","intra-refresh=1", # delay hack
# OUTPUT
"-flags2","fast", # delay hack
"-f","mpegts",
"-flags2","fast","-muxdelay","0","-muxpreload","0","-max_delay","0","-flush_packets","1", # delay hack
"-"
]

16
client/config/watch.toml Normal file
View File

@ -0,0 +1,16 @@
# Basic information
address = "fier.me:61920"
args.user = "fier"
args.channel = "default"
args.channel_password = "456"
args.bufsize = 4096
# Encryption
#aespass = "e2epass"
# Decoder values
decoder = [
"ffplay",
"-avioflags","direct","-strict","experimental","-analyzeduration","0","-sync","ext","-probesize","32","-fflags","nobuffer","-flags","low_delay","-max_delay","0","-max_probe_packets","0","-x264opts","intra-refresh=1","-fflags","discardcorrupt","-vf","setpts=0", # delay hack
"-"
]

View File

@ -1,12 +0,0 @@
fstream_python="python3"
fstream_ip="fier.me:61920"
#fstream_ssl="0"
#fstream_ssl_ignoreCert="0"
fstream_user="user"
fstream_channel="default"
fstream_channelpass=""
fstream_aespass=""
fstream_aesbuffer="4096"

View File

@ -1,31 +0,0 @@
#!/usr/bin/env bash
cd "$(dirname "$(realpath "$BASH_SOURCE")")"
sys_python="python3"
function setServer() {
export fstream_arg_user="fier"
export fstream_arg_channel="default"
export fstream_arg_channel_password="456"
}
export fstream_arg_bufsize="4096"
fstream_aespass=""
dec_cmd=(
ffplay
-avioflags direct -strict experimental -analyzeduration 0 -sync ext -probesize 32 -fflags nobuffer -flags low_delay -max_delay 0 -max_probe_packets 0 -x264opts intra-refresh=1 -fflags discardcorrupt -vf setpts=0 # delay hack
-
)
setServer
if [ "$fstream_arg_bufsize" == "" ] || [ "$fstream_arg_bufsize" == "0" ]; then
unset fstream_arg_bufsize
fi
while :; do
if ! [ "$fstream_aespass" == "" ]; then
"$sys_python" fstream.py "fier.me:61920" watch | fstream_aespass="$fstream_aespass" fstream_aesbuffer="$(($fstream_arg_bufsize - 16))" "$sys_python" fstream-util-aes_to_pipe.py | "${dec_cmd[@]}"
else
"$sys_python" fstream.py "fier.me:61920" watch | "${dec_cmd[@]}"
fi
sleep 1
done

95
client/watch.py Executable file
View File

@ -0,0 +1,95 @@
#!/usr/bin/env python3
import sys
import os
p = os.path.join
pUp = os.path.dirname
s = False
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
s = os.path.realpath(sys.executable)
else:
s = os.path.realpath(__file__)
sp = pUp(s)
# script start
import toml
import subprocess
def addressStr(addr):
return addr[0] + ":" + str(addr[1])
def addressSslStr(addr):
return addr[0] + ":" + str(addr[1] + 1)
def perr(rtn,cmd = None,op = None):
if rtn == 0: return
if cmd == None: cmd = []
exc = subprocess.CalledProcessError(rtn,cmd,op)
raise exc
def pcallStr(*args,**kwargs):
proc = subprocess.Popen(*args,**kwargs, stdout=subprocess.PIPE)
response = proc.stdout.read().decode("utf-8").strip("\n")
rtn = proc.wait()
perr(rtn,args[0])
return response
def main():
print("* Parsing config ...")
configFiles = ["watch.toml"]
if len(sys.argv) > 1:
configFiles = sys.argv[1:]
length = len(configFiles)
index = 0
while index < length:
configFiles[index] = p(sp,"config",configFiles[index])
index += 1
config = toml.load(configFiles)
for key in config["args"]:
os.environ["fstream_arg_" + key] = str(config["args"][key])
length = len(config["decoder"])
index = 0
while index < length:
if "values" in config:
for key in config["values"]:
config["decoder"][index] = config["decoder"][index].replace("$val:" +key+ "$",str(config["values"][key]))
for key in os.environ:
config["decoder"][index] = config["decoder"][index].replace("$env:" +key+ "$",os.environ[key])
index += 1
aes = False
if "aespass" in config:
if not "bufsize" in config["args"]:
print("aespass is set, but args.bufsize is not.")
sys.exit(1)
os.environ["fstream_aespass"] = config["aespass"]
os.environ["fstream_aesbuffer"] = str(config["args"]["bufsize"] - 16)
aes = True
address = config["address"].rsplit(":",1)
address[1] = int(address[1])
procClient = subprocess.Popen([
sys.executable,
p(sp,"fstream.py"),
addressStr(address),
"watch"
],stdout=subprocess.PIPE)
if aes == True:
procDecoder = subprocess.Popen(config["decoder"],stdin=subprocess.PIPE)
procAes = subprocess.Popen([
sys.executable,
p(sp,"util","fstream-util-aes_to_pipe.py"),
addressStr(address),
"watch"
],stdin=procClient.stdout,stdout=procDecoder.stdin)
else:
procDecoder = subprocess.Popen(config["encoder"],stdin=procClient.stdout)
procDecoder.wait()
main()