feat(hls): add native HLS (m3u8) download protocol

New hls protocol in internal/protocol/hls (registered ahead of http):
- master playlist variant picking (highest bandwidth), RFC3986 segment
  URL resolution, fMP4 init segments, EXT-X-BYTERANGE, EXT-X-GAP skip
- AES-128 decryption with mid-playlist key rotation and sequence-derived
  IVs; explicit errors for live streams, SAMPLE-AES and multi-period fMP4
- concurrent segment downloads with retry, journal-based resume across
  pause/app restarts, automatic in-order merge into a single .ts/.mp4
- best-effort Content-Length probing for determinate progress
- anti-hotlink Referer/Cookie/UA via task extra headers (Go transport
  does not filter them)

Core: fix SchemeFilter extension match for URLs with query strings
(also benefits .torrent links); Flutter: Protocol.hls enum, hls protocol
config model (prevents config round-trip wipe) and HLS settings block
with localized labels in all 22 locales.

Tests: parser/crypto unit tests, httptest e2e (Referer-enforced CDN,
encrypted streams, byterange, pause/resume, store/restore) and an
opt-in live-site acceptance gate (HLS_LIVE_URL).
This commit is contained in:
sun committed 2026-09-14 09:55:31 +08:00
1 parent e5ac13cfdc
commit 4f74101b3a
44 files changed
+2824 -6

No files matched your search

+283
View File
@@ -0,0 +1,283 @@
#EXTM3U
#EXT-X-TARGETDURATION:20
#EXT-X-ALLOW-CACHE:YES
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:1
#EXTINF:20.000,
seg-1-v1-a1.ts
#EXTINF:20.000,
seg-2-v1-a1.ts
#EXTINF:20.000,
seg-3-v1-a1.ts
#EXTINF:20.000,
seg-4-v1-a1.ts
#EXTINF:20.000,
seg-5-v1-a1.ts
#EXTINF:20.000,
seg-6-v1-a1.ts
#EXTINF:20.000,
seg-7-v1-a1.ts
#EXTINF:20.000,
seg-8-v1-a1.ts
#EXTINF:20.000,
seg-9-v1-a1.ts
#EXTINF:20.000,
seg-10-v1-a1.ts
#EXTINF:20.000,
seg-11-v1-a1.ts
#EXTINF:20.000,
seg-12-v1-a1.ts
#EXTINF:20.000,
seg-13-v1-a1.ts
#EXTINF:20.000,
seg-14-v1-a1.ts
#EXTINF:20.000,
seg-15-v1-a1.ts
#EXTINF:20.000,
seg-16-v1-a1.ts
#EXTINF:20.000,
seg-17-v1-a1.ts
#EXTINF:20.000,
seg-18-v1-a1.ts
#EXTINF:20.000,
seg-19-v1-a1.ts
#EXTINF:20.000,
seg-20-v1-a1.ts
#EXTINF:20.000,
seg-21-v1-a1.ts
#EXTINF:20.000,
seg-22-v1-a1.ts
#EXTINF:20.000,
seg-23-v1-a1.ts
#EXTINF:20.000,
seg-24-v1-a1.ts
#EXTINF:20.000,
seg-25-v1-a1.ts
#EXTINF:20.000,
seg-26-v1-a1.ts
#EXTINF:20.000,
seg-27-v1-a1.ts
#EXTINF:20.000,
seg-28-v1-a1.ts
#EXTINF:20.000,
seg-29-v1-a1.ts
#EXTINF:20.000,
seg-30-v1-a1.ts
#EXTINF:20.000,
seg-31-v1-a1.ts
#EXTINF:20.000,
seg-32-v1-a1.ts
#EXTINF:20.000,
seg-33-v1-a1.ts
#EXTINF:20.000,
seg-34-v1-a1.ts
#EXTINF:20.000,
seg-35-v1-a1.ts
#EXTINF:20.000,
seg-36-v1-a1.ts
#EXTINF:20.000,
seg-37-v1-a1.ts
#EXTINF:20.000,
seg-38-v1-a1.ts
#EXTINF:20.000,
seg-39-v1-a1.ts
#EXTINF:20.000,
seg-40-v1-a1.ts
#EXTINF:20.000,
seg-41-v1-a1.ts
#EXTINF:20.000,
seg-42-v1-a1.ts
#EXTINF:20.000,
seg-43-v1-a1.ts
#EXTINF:20.000,
seg-44-v1-a1.ts
#EXTINF:20.000,
seg-45-v1-a1.ts
#EXTINF:20.000,
seg-46-v1-a1.ts
#EXTINF:20.000,
seg-47-v1-a1.ts
#EXTINF:20.000,
seg-48-v1-a1.ts
#EXTINF:20.000,
seg-49-v1-a1.ts
#EXTINF:20.000,
seg-50-v1-a1.ts
#EXTINF:20.000,
seg-51-v1-a1.ts
#EXTINF:20.000,
seg-52-v1-a1.ts
#EXTINF:20.000,
seg-53-v1-a1.ts
#EXTINF:20.000,
seg-54-v1-a1.ts
#EXTINF:20.000,
seg-55-v1-a1.ts
#EXTINF:20.000,
seg-56-v1-a1.ts
#EXTINF:20.000,
seg-57-v1-a1.ts
#EXTINF:20.000,
seg-58-v1-a1.ts
#EXTINF:20.000,
seg-59-v1-a1.ts
#EXTINF:20.000,
seg-60-v1-a1.ts
#EXTINF:20.000,
seg-61-v1-a1.ts
#EXTINF:20.000,
seg-62-v1-a1.ts
#EXTINF:20.000,
seg-63-v1-a1.ts
#EXTINF:20.000,
seg-64-v1-a1.ts
#EXTINF:20.000,
seg-65-v1-a1.ts
#EXTINF:20.000,
seg-66-v1-a1.ts
#EXTINF:20.000,
seg-67-v1-a1.ts
#EXTINF:20.000,
seg-68-v1-a1.ts
#EXTINF:20.000,
seg-69-v1-a1.ts
#EXTINF:20.000,
seg-70-v1-a1.ts
#EXTINF:20.000,
seg-71-v1-a1.ts
#EXTINF:20.000,
seg-72-v1-a1.ts
#EXTINF:20.000,
seg-73-v1-a1.ts
#EXTINF:20.000,
seg-74-v1-a1.ts
#EXTINF:20.000,
seg-75-v1-a1.ts
#EXTINF:20.000,
seg-76-v1-a1.ts
#EXTINF:20.000,
seg-77-v1-a1.ts
#EXTINF:20.000,
seg-78-v1-a1.ts
#EXTINF:20.000,
seg-79-v1-a1.ts
#EXTINF:20.000,
seg-80-v1-a1.ts
#EXTINF:20.000,
seg-81-v1-a1.ts
#EXTINF:20.000,
seg-82-v1-a1.ts
#EXTINF:20.000,
seg-83-v1-a1.ts
#EXTINF:20.000,
seg-84-v1-a1.ts
#EXTINF:20.000,
seg-85-v1-a1.ts
#EXTINF:20.000,
seg-86-v1-a1.ts
#EXTINF:20.000,
seg-87-v1-a1.ts
#EXTINF:20.000,
seg-88-v1-a1.ts
#EXTINF:20.000,
seg-89-v1-a1.ts
#EXTINF:20.000,
seg-90-v1-a1.ts
#EXTINF:20.000,
seg-91-v1-a1.ts
#EXTINF:20.000,
seg-92-v1-a1.ts
#EXTINF:20.000,
seg-93-v1-a1.ts
#EXTINF:20.000,
seg-94-v1-a1.ts
#EXTINF:20.000,
seg-95-v1-a1.ts
#EXTINF:20.000,
seg-96-v1-a1.ts
#EXTINF:20.000,
seg-97-v1-a1.ts
#EXTINF:20.000,
seg-98-v1-a1.ts
#EXTINF:20.000,
seg-99-v1-a1.ts
#EXTINF:20.000,
seg-100-v1-a1.ts
#EXTINF:20.000,
seg-101-v1-a1.ts
#EXTINF:20.000,
seg-102-v1-a1.ts
#EXTINF:20.000,
seg-103-v1-a1.ts
#EXTINF:20.000,
seg-104-v1-a1.ts
#EXTINF:20.000,
seg-105-v1-a1.ts
#EXTINF:20.000,
seg-106-v1-a1.ts
#EXTINF:20.000,
seg-107-v1-a1.ts
#EXTINF:20.000,
seg-108-v1-a1.ts
#EXTINF:20.000,
seg-109-v1-a1.ts
#EXTINF:20.000,
seg-110-v1-a1.ts
#EXTINF:20.000,
seg-111-v1-a1.ts
#EXTINF:20.000,
seg-112-v1-a1.ts
#EXTINF:20.000,
seg-113-v1-a1.ts
#EXTINF:20.000,
seg-114-v1-a1.ts
#EXTINF:20.000,
seg-115-v1-a1.ts
#EXTINF:20.000,
seg-116-v1-a1.ts
#EXTINF:20.000,
seg-117-v1-a1.ts
#EXTINF:20.000,
seg-118-v1-a1.ts
#EXTINF:20.000,
seg-119-v1-a1.ts
#EXTINF:20.000,
seg-120-v1-a1.ts
#EXTINF:20.000,
seg-121-v1-a1.ts
#EXTINF:20.000,
seg-122-v1-a1.ts
#EXTINF:20.000,
seg-123-v1-a1.ts
#EXTINF:20.000,
seg-124-v1-a1.ts
#EXTINF:20.000,
seg-125-v1-a1.ts
#EXTINF:20.000,
seg-126-v1-a1.ts
#EXTINF:20.000,
seg-127-v1-a1.ts
#EXTINF:20.000,
seg-128-v1-a1.ts
#EXTINF:20.000,
seg-129-v1-a1.ts
#EXTINF:20.000,
seg-130-v1-a1.ts
#EXTINF:20.000,
seg-131-v1-a1.ts
#EXTINF:20.000,
seg-132-v1-a1.ts
#EXTINF:20.000,
seg-133-v1-a1.ts
#EXTINF:20.000,
seg-134-v1-a1.ts
#EXTINF:20.000,
seg-135-v1-a1.ts
#EXTINF:20.000,
seg-136-v1-a1.ts
#EXTINF:20.000,
seg-137-v1-a1.ts
#EXTINF:4.111,
seg-138-v1-a1.ts
#EXT-X-ENDLIST