Aves_mio0.88/hls_cors_server.py
2026-10-03 12:51:15 +02:00

99 lines
3.2 KiB
Python

#!/usr/bin/env python3
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
import os
import argparse
import sys
def parse_args():
p = argparse.ArgumentParser(description="Semplice server HTTP per HLS con CORS")
p.add_argument("root", nargs="?", default="hls_ts_test",
help="Directory da servire (default: hls_ts_test)")
p.add_argument("-p", "--port", type=int, default=9999,
help="Porta su cui ascoltare (default: 9999)")
return p.parse_args()
class HlsHandler(SimpleHTTPRequestHandler):
extensions_map = {
**SimpleHTTPRequestHandler.extensions_map,
".m3u8": "application/vnd.apple.mpegurl",
".ts": "video/mp2t",
}
# 🔥 Patch: disabilita 304 e gestisce Range correttamente
def send_head(self):
path = self.translate_path(self.path)
if os.path.isdir(path):
return self.list_directory(path)
ctype = self.guess_type(path)
try:
f = open(path, "rb")
except OSError:
self.send_error(404, "File not found")
return None
fs = os.fstat(f.fileno())
size = fs.st_size
# Gestione Range (necessaria per Chromecast)
range_header = self.headers.get("Range")
if range_header:
try:
start = int(range_header.replace("bytes=", "").split("-")[0])
except:
start = 0
self.send_response(206)
self.send_header("Content-type", ctype)
self.send_header("Content-Range", f"bytes {start}-{size-1}/{size}")
self.send_header("Content-Length", str(size - start))
self.end_headers()
f.seek(start)
return f
# Risposta normale 200 OK (mai 304)
self.send_response(200)
self.send_header("Content-type", ctype)
self.send_header("Content-Length", str(size))
self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
self.end_headers()
return f
def end_headers(self):
# CORS e cache control
self.send_header("Access-Control-Allow-Origin", "*")
self.send_header("Access-Control-Expose-Headers",
"Content-Length, Content-Type, Accept-Ranges")
self.send_header("Cache-Control", "no-cache")
super().end_headers()
def do_OPTIONS(self):
self.send_response(204)
self.send_header("Access-Control-Allow-Origin", "*")
self.send_header("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS")
self.send_header("Access-Control-Allow-Headers", "Range")
self.end_headers()
def main():
args = parse_args()
root = os.path.abspath(args.root)
port = args.port
if not os.path.isdir(root):
print(f"Directory non trovata: {root}", file=sys.stderr)
sys.exit(1)
os.chdir(root)
server = ThreadingHTTPServer(("0.0.0.0", port), HlsHandler)
print(f"Serving {root} on http://0.0.0.0:{port}", flush=True)
try:
server.serve_forever()
except KeyboardInterrupt:
print("\nServer interrotto dall'utente")
finally:
server.server_close()
if __name__ == "__main__":
main()