Compare commits

...

3 Commits

Author SHA1 Message Date
Fierelier 1d4691e402 Remake client example scripts 2023-11-01 08:20:12 +01:00
Fierelier 0894920492 Add SSL support 2023-11-01 08:19:58 +01:00
Fierelier 1140ac45fe Add "HTTP" """support""" 2023-11-01 08:17:51 +01:00
7 changed files with 178 additions and 34 deletions

View File

@ -54,6 +54,6 @@ If you would like to implement your own authentication, make your own module to
Establish a TCP connection with the server, and send the payload. If the server likes your payload, it will stream data to you, or accept more of your data.
## The payload
Send the length of the payload as a 4-byte (32-bit) big endian unsigned integer, a null byte (hex:`00`) and a UTF-8 encoded string identifying the client's intentions follows, for example: `watch,user=fier,channel=exampleChannel,channel-password=123` or `broadcast,user=fier,user-password=123,channel=exampleChannel,channel-password=456`. The length includes only the string message, in bytes, it does not include the length itself, nor the null byte.
First, send two new line characters (`\n\n`). Then, send the length of the payload as a 4-byte (32-bit) big endian unsigned integer, a null byte (hex:`00`) and a UTF-8 encoded string identifying the client's intentions follows, for example: `watch,user=fier,channel=exampleChannel,channel-password=123` or `broadcast,user=fier,user-password=123,channel=exampleChannel,channel-password=456`. The length includes only the string message, in bytes, it does not include the length itself, nor the null byte.
If you are a watcher, you will now be blasted with data. If you are a broadcaster, you can now blast data.

View File

@ -1,35 +1,75 @@
#!/bin/bash
#!/usr/bin/env bash
cd "$(dirname "$(realpath "$BASH_SOURCE")")"
function getValue() {
var="$1"
if ! [ "${!var}" == "" ]; then
return
fi
if [ "$3" == "fail" ]; then
echo "ERROR: $1 is not defined."
exit 1
fi
declare -g "$1"="$2"
}
# USER SETTINGS
RESOLUTION="480"
FRAMERATE="15"
BITRATE="1M"
PROFILE="ultrafast"
getValue fstream_profile "profile_broadcast-screen.sh"
source "$fstream_profile"
getValue fstream_resolution "480"
getValue fstream_framerate "15"
getValue fstream_bitrate "1M"
getValue fstream_264profile "ultrafast"
FST_IP="fier.me:61920"
FST_USER="user"
FST_PASSWORD="123"
FST_CHANNEL="default"
FST_CHANNELPASS="456"
getValue fstream_ip "fier.me:61920" fail
getValue fstream_user "user" fail
getValue fstream_password "123" fail
getValue fstream_channel "default"
getValue fstream_channelpass ""
getValue fstream_python "python3"
PYTHON="python3"
getValue fstream_aespass ""
getValue fstream_aesbuffer "4096"
getValue fstream_buffer "$((fstream_aesbuffer + 16))"
# LINUX:
ARGS_INPUT="-f x11grab -framerate "$FRAMERATE" -i "$DISPLAY""
getValue fstream_ssl "0"
getValue fstream_ssl_ignoreCert "0"
# WINDOWS:
# ARGS_INPUT="-f gdigrab -framerate "$FRAMERATE" -i desktop"
fstream_encodercmd=(
ffmpeg
ARGS_ENCODING="-c:v libx264 -pix_fmt yuv420p -preset $PROFILE -tune zerolatency"
ARGS_OUTPUT="-f m4v"
# 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 "$fstream_framerate" -i "$DISPLAY" # linux
#-f gdigrab -framerate "$fstream_framerate" -i desktop # windows
-vf scale=-2:$fstream_resolution
# APPLY PROPERTIES
ARGS_INPUT="$ARGS_INPUT -vf scale=-2:$RESOLUTION"
ARGS_ENCODING="$ARGS_ENCODING -x264-params "nal-hrd=cbr" -b:v $BITRATE -minrate $BITRATE -maxrate $BITRATE -bufsize $BITRATE*2"
# ENCODING
-max_probe_packets 0 -max_delay 0 -flags2 fast # delay hack
-c:v libx264 -pix_fmt yuv420p -preset $fstream_264profile -tune zerolatency -x264-params "nal-hrd=cbr" -b:v $fstream_bitrate -minrate $fstream_bitrate -maxrate $fstream_bitrate -bufsize $fstream_bitrate*2
-x264opts intra-refresh=1 # delay hack
# 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"
# OUTPUT
-flags2 fast # delay hack
-f mpegts
-flags2 fast -muxdelay 0 -muxpreload 0 -max_delay 0 -flush_packets 1 # delay hack
-
)
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"
fstream_clientarg="broadcast,user=$fstream_user,user-password=$fstream_password,channel=$fstream_channel,channel-password=$fstream_channelpass"
if [ "$fstream_buffer" -gt "0" ]; then
fstream_clientarg="$fstream_clientarg,bufsize=$fstream_buffer"
fi
fstream_clientcmd=(
"$fstream_python" fstream.py
"$fstream_ip"
"$fstream_clientarg"
)
if [ "$fstream_aespass" == "" ]; then
"${fstream_encodercmd[@]}" | "${fstream_clientcmd[@]}"
else
"${fstream_encodercmd[@]}" | fstream_aespass="$fstream_aespass" fstream_aesbuffer="$fstream_aesbuffer" "$fstream_python" fstream-util-pipe_to_aes.py | "${fstream_clientcmd[@]}"
fi

View File

@ -30,6 +30,10 @@ timeout = 15 # timeout in seconds
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
unbufferedStdout = os.fdopen(sys.stdout.fileno(),"wb",0) # Make unbuffered stdout
useSSL = False
sslIgnoreCert = False
if "fstream_ssl" in os.environ and os.environ["fstream_ssl"] == "1": useSSL = True
if "fstream_ssl_ignoreCert" in os.environ and os.environ["fstream_ssl_ignoreCert"] == "1": sslIgnoreCert = True
def listToCommand(lst):
cmd = ""
@ -99,14 +103,32 @@ def stringToAddressTuple(addr):
return rtn
def main():
global serverAddr
global serverAddr, useSSL, sslIgnoreCert, connection
serverAddr = stringToAddressTuple(sys.argv[1])
global bufferSize
if useSSL: import ssl
eprint("Connecting to server...")
connection.settimeout(timeout)
connection.connect(serverAddr)
if useSSL:
eprint("Performing SSL handshake...")
if sys.version_info >= (3,10):
proto = ssl.PROTOCOL_TLS_CLIENT
else:
proto = ssl.PROTOCOL_TLS
ctx = ssl.SSLContext(proto)
if sslIgnoreCert:
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
connection = ctx.wrap_socket(
connection,
server_side = False
)
eprint("Sending payload...")
connection.sendall("\n\n".encode("ascii"))
sendResponse(connection,sys.argv[2].encode("utf-8"))
cmd = commandToList(sys.argv[2])

View File

@ -0,0 +1,19 @@
fstream_python="python3"
fstream_ip="fier.me:61920"
#fstream_ssl="0"
#fstream_ssl_ignoreCert="0"
fstream_user="user"
fstream_password="123"
fstream_channel="default"
fstream_channelpass=""
fstream_resolution="480"
fstream_framerate="15"
fstream_bitrate="1M"
fstream_profile="ultrafast"
fstream_aespass=""
fstream_aesbuffer="4096"
fstream_buffer="$((fstream_aesbuffer + 16))"

12
client/profile_watch.sh Normal file
View File

@ -0,0 +1,12 @@
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,9 +1,44 @@
#!/bin/bash
#!/usr/bin/env bash
cd "$(dirname "$(realpath "$BASH_SOURCE")")"
function getValue() {
var="$1"
if ! [ "${!var}" == "" ]; then
return
fi
if [ "$3" == "fail" ]; then
echo "ERROR: $1 is not defined."
exit 1
fi
declare -g "$1"="$2"
}
# USER SETTINGS
FST_IP="fier.me:61920"
FST_USER="user"
FST_CHANNEL="default"
FST_CHANNELPASS="123"
getValue fstream_profile "profile_watch.sh"
source "$fstream_profile"
getValue fstream_ip "fier.me:61920" fail
getValue fstream_user "user" fail
getValue fstream_channel "default"
getValue fstream_channelpass ""
getValue fstream_python "python3"
python3 fstream.py "$FST_IP" "watch,user=$FST_USER,channel=$FST_CHANNEL,channel-password=$FST_CHANNELPASS" | 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 -
getValue fstream_aespass ""
getValue fstream_aesbuffer "4096"
fstream_decodercmd=(
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 -
)
fstream_clientarg="watch,user=$fstream_user,channel=$fstream_channel,channel-password=$fstream_channelpass"
fstream_clientcmd=(
"$fstream_python" fstream.py
"$fstream_ip"
"$fstream_clientarg"
)
if [ "$fstream_aespass" == "" ]; then
"${fstream_clientcmd[@]}" | "${fstream_decodercmd[@]}"
else
"${fstream_clientcmd[@]}" | fstream_aespass="$fstream_aespass" fstream_aesbuffer="$fstream_aesbuffer" "$fstream_python" fstream-util-aes_to_pipe.py | "${fstream_decodercmd[@]}"
fi

View File

@ -3,6 +3,22 @@ import select
global clientLoopIn
def clientLoopIn(self):
chars = 0
nl = False
while chars < httpHeaderMaxSize:
chars += 1
char = recv(self.connection,1).decode(errors="replace")
if char == "\n":
if nl == True:
chars = 0
break
if nl == False:
nl = True
else:
nl = False
if chars >= httpHeaderMaxSize: return
cmd = getResponse(self.connection,1024).decode("utf-8")
if cmd == False: return
cmd = commandToList(cmd)