agalwood/Motrix · error · MediaParseError

unsupported-live

unsupported-live

Error message

dynamic (live) MPD

What it means

MediaParseError with code 'unsupported-live', thrown by parseDash when the MPD root element carries type="dynamic". The library only supports static (VOD) DASH manifests because it builds a fixed SegmentPlan; live windows require sliding playlists and segment-time updates it does not model.

Source

Thrown at src/core/media/dash-parser.ts:15

import {
  type ByteRange,
  type InitSegment,
  MediaParseError,
  type MediaPart,
  resolveUri,
  type SegmentPlan,
} from './segment-plan'

export function parseDash(
  xml: string,
  mpdUrl: string
): { video: SegmentPlan; audio?: SegmentPlan } {
  if (/<MPD\b[^>]*\btype\s*=\s*"dynamic"/i.test(xml)) {
    throw new MediaParseError('unsupported-live', 'dynamic (live) MPD')
  }
  if (/<ContentProtection\b/i.test(xml)) {
    throw new MediaParseError('unsupported-encryption', 'DRM-protected MPD')
  }

  const mpdBaseUrl = extractMpdBaseUrl(xml, mpdUrl)

  const periodMatch = /<Period\b([^>]*)>([\s\S]*?)<\/Period>/i.exec(xml)
  const periodAttrs = periodMatch?.[1] ?? ''
  const periodBody = periodMatch?.[2] ?? xml

  const mpdDuration = parseDuration(
    attrVal(/<MPD\b[^>]*>/i.exec(xml)?.[0] ?? '', 'mediaPresentationDuration')
  )
  const periodDuration =
    parseDuration(attrVal(periodAttrs, 'duration')) ?? mpdDuration
  const periodBaseUrl = resolveLevelBaseUrl(periodBody, mpdBaseUrl)

View on GitHub (pinned to 1a708ee577)

Solutions

  1. Point the fetcher at a static (type="static") MPD or a VOD asset URL.
  2. If you must handle live, integrate a dedicated live-DASH player (dash.js, Shaka) instead of this parser.
  3. Detect the manifest type up front by regex-checking for type="dynamic" and surface a clear user-facing message before calling parseDash.
  4. Confirm the URL is the VOD variant — some CDNs expose ?format=vod or distinct /vod/ paths.

Example fix

// before
const plan = parseDash(xml, mpdUrl)
// after — pre-check and route live URLs elsewhere
if (/type\s*=\s*"dynamic"/i.test(xml)) {
  throw new UserFacingError('Live streams are not supported. Use a VOD URL.')
}
const plan = parseDash(xml, mpdUrl)
Defensive patterns

Strategy: validation

Validate before calling

function isStaticMpd(xml: string): boolean {
  return !/<MPD\b[^>]*\btype\s*=\s*"dynamic"/i.test(xml)
}
if (!isStaticMpd(xml)) {
  throw new Error('Live DASH (type=dynamic) is not supported; provide a static MPD URL.')
}

Type guard

function isStaticMpd(xml: string): boolean {
  return !/<MPD\b[^>]*\btype\s*=\s*"dynamic"/i.test(xml)
}

Try / catch

try {
  const plan = parseDash(xml, mpdUrl)
} catch (e) {
  if (e instanceof MediaParseError && e.code === 'unsupported-live') {
    // inform user to provide a VOD URL
  } else throw e
}

Prevention

When it happens

Trigger: Calling parseDash(xml, mpdUrl) on a manifest whose <MPD> tag includes type="dynamic" — i.e. any live or event DASH stream from a broadcaster CDN (Twitch, YouTube Live, DASH-IF reference live packs).

Common situations: User-supplied URL pointing at a live stream instead of VOD; CDN that serves the same path as dynamic for live events; testing against the DASH-IF live sample set instead of the VOD set.

Related errors


AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12). Data as JSON: /api/errors/99539229eac076ed. Report an issue: GitHub.