A TCP multi-broadcast media streaming server/client
Go to file
Fierelier 374cc6a32b Fix security exploit :> 2024-02-20 04:22:52 +01:00
client Remove static versions from requirements.txt 2024-02-10 03:37:20 +01:00
modules Fix security exploit :> 2024-02-20 04:22:52 +01:00
.gitignore Attempt at process pipe full close 2024-02-10 03:26:38 +01:00
LICENSE Rewrite 2022-05-29 14:31:07 +02:00
README.md Update README.md 2023-11-08 12:17:36 +01:00
fsockets.py Add token authent 2023-11-08 08:08:28 +01:00

README.md

fstream

A TCP multi-broadcast media streaming server/client. Check out the past source, for simpler implementation. Compatible with Python 3.4 and up!

Client

Token

fstream.py <ip:port> token
Gives you a token you can broadcast with. By default, tokens expire after 2 minutes. They can only be used once, and only one token can exist per user.

This is useful for getting a one-time access via HTTPS, and then using it to stream via HTTP, avoiding the CPU overhead of HTTPS and the security risk of HTTP. Think of it like a handshake.

Server environment variables (fserv_arg_*)

  • user: Your user's name.
  • user_password: Your user's password.

Broadcast

fstream.py <ip:port> broadcast
Accepts data from stdin, and sends it to the specified server.

Server environment variables (fserv_arg_*)

  • user: Your user's name.
  • user_password: Your user's password. Optional, if you use token.
  • token: Your temporary token. Optional, if you use user_password.
  • channel: The channel you wanna stream to. Can be any name. Defaults to default.
  • channel_password: The channel's password. Can be any password. Defaults to no password.
  • bufsize: The size of chunks. If someone watches your stream, it will begin at the start of a chunk. Defaults to 0 (no set size, lowest delay).

All arguments are optional but for user and one of user_password or token.

Example

export fserv_arg_user="fier"
export fserv_arg_user_password="123"
export fserv_arg_user_channel="default"
export fserv_arg_channel_password="456"
ffmpeg -f gdigrab -framerate 30 -i desktop -vf scale=-2:480 -c:v libx264 -pix_fmt yuv420p -maxrate 1M -f h264 - | ./fstream.py 127.0.0.1:61920 broadcast

Broadcast Windows desktop as fier to 127.0.0.1:61920, supplying 123 as the user password. default is the channel, 456 is the channel's password. Pipe the output from ffmpeg.

Watch

fstream.py <ip:port> broadcast
Accepts data from the server, and sends it to stdout.

Server environment variables (fserv_arg_*)

  • user: The user you wanna watch.
  • channel: The user's channel you wanna watch.
  • channel_password: The channel's password.

All arguments are optional but for user.

Example

export fserv_arg_user="fier"
export fserv_arg_channel="default"
export fserv_arg_channel_password="456"
./fstream.py 127.0.0.1:61920 watch | ffplay -i -

Watch fier's default channel at 127.0.0.1:61920, supplying 456 as the password, and pipe it into ffplay for playback.

Server

Settings

Edit modules/settings.py for generic server/socket-related settings, and modules/fstream/settings.py for fstream related settings.

Creating a user

Make a folder called users and make a file in it called YourUsername.ini, put this in it:

[DEFAULT]
password=foobar

If you would like to implement your own authentication, make your own module to replace the authenticate() function - see modules/fstream/authent.py and modules/fstream/main.mods.

The Protocol

Establishing a connection

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

First, send two new line characters (\n\n) (could also be HTTP headers, as they end in \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=default,channel_password=456 or broadcast,user=fier,user_password=123,channel=default,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.