Skip to content

Fix HLS download failure when EXT-X-DEFINE variables are referenced in media playlist segment URLs#3259

Open
prashant9934 wants to merge 1 commit into
androidx:releasefrom
prashant9934:fix/hls-variable-substitution-download
Open

Fix HLS download failure when EXT-X-DEFINE variables are referenced in media playlist segment URLs#3259
prashant9934 wants to merge 1 commit into
androidx:releasefrom
prashant9934:fix/hls-variable-substitution-download

Conversation

@prashant9934

@prashant9934 prashant9934 commented Jun 3, 2026

Copy link
Copy Markdown

PR Description:

Summary

Fixes HLS download failures for streams where the multivariant playlist defines
variables via #EXT-X-DEFINE:NAME=...,VALUE=... and media playlists reference
them in segment URLs without an explicit #EXT-X-DEFINE:IMPORT=... tag.

Fixes #3258

Problem

HlsDownloader (via SegmentDownloader) uses a single HlsPlaylistParser()
instance constructed with HlsMultivariantPlaylist.EMPTY. This instance first
parses the multivariant playlist, then parses each media playlist. However, the
parsed multivariant playlist was never stored back into the parser instance.

When media playlists are subsequently parsed, multivariantPlaylist is still
EMPTY, so:

  • variableDefinitions is unavailable during replaceVariableReferences()
  • {$variable} references in segment URLs pass through unsubstituted
  • Downloads fail with HTTP errors on malformed URLs
  • HlsMediaPeriod.getStreamKeys() crashes with IndexOutOfBoundsException

During playback this works correctly because HlsPlaylistTracker constructs
the parser with the real multivariant playlist.

Fix

HlsPlaylistParser.java:

  • Make multivariantPlaylist field non-final
  • After parsing a multivariant playlist in parse(), store it in the instance
  • Subsequent parseMediaPlaylist() calls on the same instance now have access
    to the correct variableDefinitions for variable substitution

HlsMediaPeriod.java:

  • Add bounds checks in getStreamKeys() to prevent IndexOutOfBoundsException
    when redundantGroupIndicesPerWrapper has an empty array or when
    renditionRedundantGroupIndex exceeds the redundant groups list size

Testing

Tested with an HLS stream using:

#EXT-X-DEFINE:NAME="awsContentSegmentPrefix",VALUE="https://cdn.example.com/"

in the multivariant playlist, with media playlist segment URLs referencing
{$awsContentSegmentPrefix} directly. Download completes successfully with
variables resolved. Existing playback behavior is unchanged

@google-cla

google-cla Bot commented Jun 3, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@marcbaechinger marcbaechinger self-requested a review June 3, 2026 13:49
@marcbaechinger

marcbaechinger commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Thanks. Please can you file the CLA? We can't process this before the CLA requirements.

As you are saying that the problem manifests in download use cases only. Would you be able to craft a unit test that demonstrates the failure and verifies the fix? That's what we have to do anyway internally when processing your fix, and if you are able to provide this, this may make taking the pull a bit quicker. Thanks for considering adding such a unit test. We'd need the CLA in any case.

@prashant9934 prashant9934 force-pushed the fix/hls-variable-substitution-download branch from 3161a6b to 0affbd7 Compare June 3, 2026 16:57
prashant9934 pushed a commit to prashant9934/media3 that referenced this pull request Jun 8, 2026
… HlsDownloader

HlsDownloader.getSegments() now creates a HlsPlaylistParser with the
multivariant playlist context and uses ParsingLoadable.load() to parse
child manifests. This allows EXT-X-DEFINE variables defined in the
multivariant playlist to be resolved via IMPORT in media playlists
during the download path.

Previously, child manifests were parsed via getManifest() which uses
the original parser constructed with HlsMultivariantPlaylist.EMPTY.
Variables imported via #EXT-X-DEFINE:IMPORT could not be resolved,
causing segment URLs with unresolved {$variable} references to fail
during download.

This fixes HLS download failures for streams that define variables in
the multivariant playlist and reference them in media playlist segment
URLs (e.g. {$awsContentSegmentPrefix} in Art19 video podcasts).

Issue: androidx#3259
@prashant9934 prashant9934 force-pushed the fix/hls-variable-substitution-download branch from 0affbd7 to 9356b0f Compare June 8, 2026 22:07
prashant9934 pushed a commit to prashant9934/media3 that referenced this pull request Jun 8, 2026
… HlsDownloader

HlsDownloader.getSegments() now creates a HlsPlaylistParser with the
multivariant playlist context and uses ParsingLoadable.load() to parse
child manifests. This allows EXT-X-DEFINE variables defined in the
multivariant playlist to be resolved via IMPORT in media playlists
during the download path.

Previously, child manifests were parsed via getManifest() which uses
the original parser constructed with HlsMultivariantPlaylist.EMPTY.
Variables imported via #EXT-X-DEFINE:IMPORT could not be resolved,
causing segment URLs with unresolved {$variable} references to fail
during download.

This fixes HLS download failures for streams that define variables in
the multivariant playlist and reference them in media playlist segment
URLs (e.g. {$awsContentSegmentPrefix} in Art19 video podcasts).

Issue: androidx#3259
@prashant9934 prashant9934 force-pushed the fix/hls-variable-substitution-download branch from 9356b0f to b879848 Compare June 8, 2026 22:09
… HlsDownloader

HlsDownloader.getSegments() now creates a HlsPlaylistParser with the
multivariant playlist context and uses ParsingLoadable.load() to parse
child manifests. This allows EXT-X-DEFINE variables defined in the
multivariant playlist to be resolved via IMPORT in media playlists
during the download path.

Previously, child manifests were parsed via getManifest() which uses
the original parser constructed with HlsMultivariantPlaylist.EMPTY.
Variables imported via #EXT-X-DEFINE:IMPORT could not be resolved,
causing segment URLs with unresolved {$variable} references to fail
during download.

This fixes HLS download failures for streams that define variables in
the multivariant playlist and reference them in media playlist segment
URLs (e.g. {$awsContentSegmentPrefix} in Art19 video podcasts).

Issue: androidx#3259
@prashant9934 prashant9934 force-pushed the fix/hls-variable-substitution-download branch from b879848 to 1bf8f43 Compare June 8, 2026 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HLS download fails when EXT-X-DEFINE variables from multivariant playlist are used in media playlist segment URLs

2 participants