HLS streaming experiment
23. 9. 2025Note: Code written by AI. All experiments done on win10 machine.
Goal: Stream my desktop for the purpose of teaching.
More: Provide a remote user with a link that can be opened in browser (or/and VLC). Don’t bother with sound. Use GPU for video encoding to reduce propeller noise.
python server.py
from http.server import HTTPServer, SimpleHTTPRequestHandler
class CORSHandler(SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header('Access-Control-Allow-Origin', '*')
super().end_headers()
port = 8080
server = HTTPServer(('0.0.0.0', port), CORSHandler)
print(f"Serving on http://localhost:{port}")
server.serve_forever()
stream.bat
ffmpeg -f gdigrab -video_size 1920x1080 -framerate 25 -i desktop ^
-c:v h264_nvenc -preset p6 -tune ll -pix_fmt yuv420p ^
-b:v 6000k -maxrate 6000k -bufsize 1000k ^
-g 50 -keyint_min 25 ^
-f hls -hls_time 3 -hls_list_size 6 ^
-hls_flags delete_segments+append_list+omit_endlist ^
-hls_segment_type fmp4 -hls_fmp4_init_filename init.mp4 ^
stream.m3u8
- Latency may be reduced by using smaller ‘-bufsize’, but the video quality will suffer (at some point very visible jumping).
player.htm
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HLS Stream</title>
<style>
body { background: #000; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; }
video { width: 80%; height: auto; }
</style>
</head>
<body>
<video id="video" controls autoplay muted></video>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script>
const video = document.getElementById('video');
const hlsUrl = 'stream.m3u8'; // your HLS playlist
if (Hls.isSupported()) {
const hls = new Hls({
// optional low-latency tuning
liveSyncDurationCount: 3,
maxBufferLength: 10
});
hls.loadSource(hlsUrl);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, () => video.play());
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
// Safari native HLS support
video.src = hlsUrl;
video.addEventListener('loadedmetadata', () => video.play());
} else {
alert("HLS not supported in this browser");
}
</script>
</body>
</html>
Notes: Latency is significant (5 - 30 s). CPU usage is still high, possibly ffmpeg is doing something weird (-video_size ? Can’t i just select monitor 1 somehow?). Stuff to try.