Compare commits
3 Commits
c08a841fe6
...
1d4691e402
Author | SHA1 | Date |
---|---|---|
Fierelier | 1d4691e402 | |
Fierelier | 0894920492 | |
Fierelier | 1140ac45fe |
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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))"
|
|
@ -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"
|
47
client/watch
47
client/watch
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue