Skip to content

feat: Add Native Support for Direct HLS Streams #108

Description

@Nirupon123

The Problem

Currently, the application does not properly support direct HLS stream links (e.g., links ending in .m3u8). When a user pastes an HLS link into the "Stream Link" input, it encounters several blocking issues across the stack:

  1. Backend Validation Failure: The frontend submits the link with stream_type: "platform". The PlatformSource class enforces a strict domain whitelist (YouTube, Twitch, Vimeo). If an HLS link is hosted on a CDN, it throws a validation error and fails to spawn the audio grabber.
Image
  1. Performance Overhead: Even if the domain check is bypassed, PlatformSource routes the URL through yt-dlp to extract the media URL. This is unnecessary for raw .m3u8 streams, which can be fed directly to ffmpeg, and it adds significant latency to stream startup.
  2. Frontend Video Rendering: The frontend (stream.js) is hardcoded to embed video using an iframe designed for YouTube, Twitch, or Vimeo. It does not recognize .m3u8 links, so it hides the video player entirely (resulting in a blank gray box). Furthermore, standard desktop browsers cannot play HLS streams natively in an iframe without a library.

Desired Behavior & Proposed Solution

To fully support HLS streams natively and efficiently, we need changes on both the backend and frontend:

1. Backend: Auto-Routing for Speed & SSRF Protection

  • Auto-Routing: In transcribe_server.py, detect if a submitted platform URL ends in .m3u8. If so, automatically upgrade it to stream_type: "url". This bypasses yt-dlp entirely, passing the stream directly to ffmpeg for instant startup.
  • Admin Bypass: Natively allow non-admin users to use stream_type: "url" only if the URL is an HLS playlist.
  • SSRF Prevention: Update URLSource._validate_url in audio_sources.py to include strict Server-Side Request Forgery (SSRF) checks. It must resolve the URL's hostname via DNS and reject any internal, private, or loopback IP addresses before passing it to ffmpeg.

2. Frontend: Native Video Rendering (hls.js)

  • Native Video Tag: Add a standard <video> tag to stream.html alongside the existing iframe.
  • HLS Library: Import the hls.js library via CDN.
  • Conditional Rendering: Update stream.js so that if the VIDEO_URL ends in .m3u8, it hides the iframe embed, displays the native <video> tag, and uses hls.js to attach and autoplay the stream.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions