Add docker support
This commit is contained in:
@@ -4,7 +4,7 @@ from flask import Flask, render_template, request, Response, abort, jsonify
|
||||
from werkzeug.exceptions import HTTPException
|
||||
|
||||
import dlp
|
||||
from utils import is_valid_url, get_error_message
|
||||
from utils import is_valid_url, get_error_message, get_video_id, resolve_video_id
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@@ -34,14 +34,9 @@ def player():
|
||||
|
||||
try:
|
||||
stream_info = dlp.get_stream_info(video_url)
|
||||
from urllib.parse import quote
|
||||
|
||||
# URL encode for path (use -- as delimiter)
|
||||
encoded_url = quote(video_url, safe="")
|
||||
|
||||
# Only set HLS URL if we actually have HLS
|
||||
video_id = get_video_id(video_url)
|
||||
hls_url = stream_info.get("hls_url")
|
||||
proxy_hls_url = f"/hls/{encoded_url}--index.m3u8" if hls_url else None
|
||||
proxy_hls_url = f"/hls/{video_id}/index.m3u8" if hls_url else None
|
||||
|
||||
return render_template(
|
||||
"player.html",
|
||||
@@ -86,49 +81,17 @@ def player():
|
||||
abort(500, description=str(e))
|
||||
|
||||
|
||||
@app.route("/hls/<path:full_path>")
|
||||
def hls_proxy(full_path):
|
||||
@app.route("/hls/<video_id>/index.m3u8")
|
||||
def hls_index(video_id):
|
||||
try:
|
||||
from urllib.parse import unquote
|
||||
|
||||
# Split: last part is filename, rest is video URL
|
||||
# Format: /hls/<encoded_video_url>/<filename>
|
||||
# Since / is ambiguous (in URL and in video URL), we use a delimiter
|
||||
# Format: /hls/<encoded_video_url>--<filename>
|
||||
|
||||
if "--" not in full_path:
|
||||
abort(400, description="Invalid path format")
|
||||
|
||||
parts = full_path.rsplit("--", 1)
|
||||
if len(parts) != 2:
|
||||
abort(400, description="Invalid path format")
|
||||
|
||||
encoded_video_url = parts[0]
|
||||
filename = parts[1]
|
||||
|
||||
# Decode the video URL
|
||||
video_url = unquote(encoded_video_url)
|
||||
video_url = resolve_video_id(video_id)
|
||||
if not video_url:
|
||||
abort(400, description="Unknown video id")
|
||||
|
||||
if not is_valid_url(video_url):
|
||||
abort(400, description="Invalid URL")
|
||||
|
||||
# Main playlist request
|
||||
if filename == "index.m3u8":
|
||||
playlist = dlp.get_hls_playlist(video_url)
|
||||
return Response(playlist, mimetype="application/vnd.apple.mpegurl", headers={"Cache-Control": "public, max-age=31536000"})
|
||||
|
||||
# Sub-playlist or segment request
|
||||
segment_url = unquote(filename)
|
||||
|
||||
segment_data = dlp.get_hls_segment_with_retry(video_url, segment_url)
|
||||
|
||||
if segment_data is None:
|
||||
abort(500, description="Failed to fetch segment")
|
||||
|
||||
# Determine content-type by filename extension
|
||||
if filename.endswith(".m3u8"):
|
||||
return Response(segment_data, mimetype="application/vnd.apple.mpegurl", headers={"Cache-Control": "public, max-age=31536000"})
|
||||
return Response(segment_data, mimetype="video/mp2t", headers={"Cache-Control": "public, max-age=31536000"})
|
||||
playlist = dlp.get_hls_playlist(video_url)
|
||||
return Response(playlist, mimetype="application/vnd.apple.mpegurl", headers={"Cache-Control": "public, max-age=31536000"})
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
@@ -140,6 +103,32 @@ def hls_proxy(full_path):
|
||||
return Response(str(e), status=500, mimetype="text/plain")
|
||||
|
||||
|
||||
@app.route("/hls/<video_id>/seg/<seg_id>")
|
||||
def hls_segment(video_id, seg_id):
|
||||
try:
|
||||
video_url = resolve_video_id(video_id)
|
||||
if not video_url:
|
||||
abort(400, description="Unknown video id")
|
||||
|
||||
if not is_valid_url(video_url):
|
||||
abort(400, description="Invalid URL")
|
||||
|
||||
data = dlp.get_hls_segment_with_retry(video_url, str(seg_id))
|
||||
if data is None:
|
||||
abort(500, description="Failed to fetch segment")
|
||||
|
||||
return Response(data, mimetype="video/mp2t", headers={"Cache-Control": "public, max-age=31536000"})
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except ValueError as e:
|
||||
logger.warning(f"Validation error: {e}")
|
||||
abort(400, description=str(e))
|
||||
except Exception as e:
|
||||
logger.error(f"HLS segment error: {e}")
|
||||
return Response(str(e), status=500, mimetype="text/plain")
|
||||
|
||||
|
||||
@app.errorhandler(Exception)
|
||||
def handle_error(e):
|
||||
if isinstance(e, HTTPException):
|
||||
|
||||
Reference in New Issue
Block a user