LinuxPlay uses FFmpeg
for capturing, encoding and streaming video/audio via
UDP multicast
. A TCP handshake negotiates encoder/decoder modes and handles password
authentication. The client decodes the stream using PyAV
and displays it with a
PyQt5
GUI, while mouse/keyboard inputs and clipboard data are synchronized using
xdotool
and xclip
.
Note: LinuxPlay is a toy project designed for beginners who want to learn advanced
remote desktop streaming concepts. If you're comfortable with the terminal, you can copy and paste the commands
below to run LinuxPlay directly, no need to use the GUI launcher (start.py
).
The host captures the screen using FFmpeg
's x11grab
input at the specified
resolution and framerate.
ffmpeg -f x11grab -framerate 30 -video_size 1920x1080 -i :0
Captured frames are encoded with either software encoders (like libx264
,
libx265
, or libaom-av1
) or hardware-accelerated encoders (such as NVIDIA NVENC or VAAPI).
ffmpeg -c:v h264_nvenc -b:v 8M -preset llhq -f mpegts udp://239.0.0.1:5000
A TCP handshake on port 7001
ensures both the host and client agree on the encoder type and if used,
verifies the password.
# Client sends:
PASSWORD:yourpassword
# Host replies:
OK:h264
The encoded video is sent via UDP multicast
(239.0.0.1:5000
), while audio captured from PulseAudio
is streamed on port 6001
.
# Video stream:
ffmpeg ... -f mpegts udp://239.0.0.1:5000
# Audio stream:
ffmpeg -f pulse -i default.monitor -c:a libopus -b:a 128k -f mpegts udp://239.0.0.1:6001
The client decodes the UDP stream using PyAV
(which binds to FFmpeg) and uses hardware decoding
(NVIDIA NVDEC or VAAPI) if available.
av.open("udp://@239.0.0.1:5000?fifo_size=5000000&overrun_nonfatal=1", options={"hwaccel": "h264_nvdec"})
Decoded frames are converted into images and rendered in a PyQt5
GUI, ensuring smooth playback.
User input (mouse/keyboard) on the client is sent as UDP control messages (port 7000
) to the host, which uses
xdotool
to simulate these events.
# Example control message:
MOUSE_MOVE 400 300
# Executed on host:
xdotool mousemove 400 300
Clipboard content is synchronized between host and client via UDP multicast (port 7002
) using xclip
on the host
and the clipboard API in PyQt5
on the client.
xclip -o -selection clipboard
A GUI launcher (written in PyQt5
) allows configuration of host/client options such as encoder/decoder, resolution,
framerate, bitrate, audio, password, and adaptive bitrate management.
7001
negotiates settings and handles password authentication.239.0.0.1
) on dedicated ports for video (5000
), audio (6001
), and clipboard (7002
).7000
) and executed with xdotool.
Advanced Users & Tinkerers: If you're comfortable with the terminal, you can copy and paste the commands below to run LinuxPlay directly, no need to use the GUI launcher (start.py
). This toy project is designed for beginners who want to explore advanced remote desktop streaming concepts. Experiment, learn and have fun!