{"record":{"id":"1a9e22a9e8a0c275","repo":"agalwood/Motrix","slug":"unsupported-live-1a9e22","errorCode":"unsupported-live","errorMessage":"live HLS is not supported","messagePattern":"live HLS is not supported","errorType":"error_code","errorClass":"MediaParseError","httpStatus":null,"severity":"error","filePath":"src/core/media/hls-parser.ts","lineNumber":139,"sourceCode":" *  - METHOD=NONE → clears active key\n *  - METHOD=SAMPLE-AES/other → MediaParseError('unsupported-encryption')\n *  - EXT-X-BYTERANGE with running per-resource offset\n *  - Live guard: no ENDLIST and not PLAYLIST-TYPE:VOD → MediaParseError('unsupported-live')\n */\nexport function parseHlsMedia(text: string, url: string): SegmentPlan {\n  const lines = text.split(/\\r?\\n/)\n\n  const hasEndlist = lines.some((l) => l.startsWith('#EXT-X-ENDLIST'))\n  const playlistType = lines\n    .find((l) => l.startsWith('#EXT-X-PLAYLIST-TYPE:'))\n    ?.slice('#EXT-X-PLAYLIST-TYPE:'.length)\n    ?.trim()\n    ?.toUpperCase()\n\n  const isVod = playlistType === 'VOD'\n\n  if (!hasEndlist && !isVod) {\n    throw new MediaParseError('unsupported-live', 'live HLS is not supported')\n  }\n\n  // Parse MEDIA-SEQUENCE\n  let seq = 0\n  const seqLine = lines.find((l) => l.startsWith('#EXT-X-MEDIA-SEQUENCE:'))\n  if (seqLine) {\n    seq = Number(seqLine.slice('#EXT-X-MEDIA-SEQUENCE:'.length).trim())\n  }\n\n  // Running state\n  let activeKey: KeyRef | null = null\n  let activeInit: InitSegment | undefined\n  // Per-resource running byte offset (keyed by resolved URL)\n  const runningOffset = new Map<string, number>()\n  // Pending BYTERANGE for the next segment\n  let pendingByteRange: { length: number; offset?: number } | undefined\n\n  const segments: MediaPart[] = []","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/media/hls-parser.ts#L121-L157","documentation":"MediaParseError with code 'unsupported-live', thrown by parseHlsMedia when the playlist has neither #EXT-X-ENDLIST nor #EXT-X-PLAYLIST-TYPE:VOD. The library only handles static (complete) HLS media playlists because it builds a fixed SegmentPlan; live/sliding-window playlists require ongoing refresh which it does not model.","triggerScenarios":"Calling parseHlsMedia on an active live HLS playlist (no EXT-X-ENDLIST, no PLAYLIST-TYPE:VOD). Typical for ongoing event streams, 24/7 linear channels, or playlists where the encoder has not yet written the closing tag.","commonSituations":"User-supplied live URL; event playlists still being recorded; CDN edge that strips EXT-X-ENDLIST on in-progress assets; testing against Apple's bipbop live samples rather than the VOD ones.","solutions":["Point the fetcher at a finished (ENDLIST present) VOD asset URL.","If you must play live, use a player with native live HLS support (hls.js, AVPlayer, ExoPlayer) instead of this parser.","Pre-check: if (!text.includes('#EXT-X-ENDLIST') && !/PLAYLIST-TYPE:VOD/i.test(text)) reject as live before calling parseHlsMedia.","For event streams, wait until recording completes and the ENDLIST is appended, then re-fetch."],"exampleFix":"// before\nconst plan = parseHlsMedia(text, url)\n// after\nconst isLive = !text.includes('#EXT-X-ENDLIST') && !/#EXT-X-PLAYLIST-TYPE:VOD/i.test(text)\nif (isLive) throw new UserFacingError('Live HLS is not supported. Use a VOD URL.')\nconst plan = parseHlsMedia(text, url)","handlingStrategy":"validation","validationCode":"function isStaticHls(text: string): boolean {\n  return text.includes('#EXT-X-ENDLIST') || /#EXT-X-PLAYLIST-TYPE:VOD/i.test(text)\n}\nif (!isStaticHls(text)) {\n  throw new Error('Live HLS is not supported; provide a VOD URL.')\n}","typeGuard":"function isStaticHls(text: string): boolean {\n  return text.includes('#EXT-X-ENDLIST') || /#EXT-X-PLAYLIST-TYPE:VOD/i.test(text)\n}","tryCatchPattern":"try {\n  const plan = parseHlsMedia(text, url)\n} catch (e) {\n  if (e instanceof MediaParseError && e.code === 'unsupported-live') {\n    // prompt user for a VOD URL\n  } else throw e\n}","preventionTips":["Pre-check for EXT-X-ENDLIST / PLAYLIST-TYPE:VOD before parsing.","For event streams, wait until recording completes and re-fetch.","Maintain an allowlist of known VOD HLS hosts."],"tags":["hls","media","streaming","live"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}