On iOS 26, HLS alternate audio track selection behaves inconsistently

Summary

On iOS 26, HLS alternate audio track selection behaves inconsistently on both VOD and live streams: the French track falls back to the DEFAULT=YES (English) track after manual selection, and in some cases switching to a non-default track appears to work but it is then impossible to switch back to English.

Environment

  • iOS version: 26
  • Players affected: native Safari on iOS 26 and THEOplayer (issue also reproducible on THEOplayer's own demo page)
  • Stream type: HLS/CMAF with demuxed alternate audio renditions (CMFC container)
  • Affected stream types: both VOD and live streaming
  • Issue NOT present on iOS 17/18

Manifest

#EXTM3U
#EXT-X-VERSION:4
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-STREAM-INF:BANDWIDTH=8987973,AVERAGE-BANDWIDTH=8987973,VIDEO-RANGE=SDR,CODECS="avc1.640028",RESOLUTION=1920x1080,FRAME-RATE=29.970,AUDIO="program_audio"
video_1080p.m3u8
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="program_audio",LANGUAGE="en",ASSOC-LANGUAGE="en",NAME="English",AUTOSELECT=YES,DEFAULT=YES,CHANNELS="2",URI="audio_ENG.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="program_audio",LANGUAGE="de",ASSOC-LANGUAGE="de",NAME="Deutsch",AUTOSELECT=YES,DEFAULT=NO,CHANNELS="2",URI="audio_DEU.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="program_audio",LANGUAGE="fr",ASSOC-LANGUAGE="fr",NAME="Francais",AUTOSELECT=YES,DEFAULT=NO,CHANNELS="2",URI="audio_FRA.m3u8"

Steps to Reproduce

  1. Load the HLS manifest (VOD or live) in Safari on iOS 26, or in any AVFoundation-backed player
  2. Start playback — English plays correctly as DEFAULT
  3. Manually select "Francais" from the audio track selector
  4. Observe that English audio continues playing (French does not play)
  5. In a separate scenario: manually select "Deutsch" — German plays correctly
  6. Attempt to switch back to English — English does not resume; audio remains on the previously selected track

Expected behavior

  • Selecting any track should immediately switch to that language
  • Switching back to English (DEFAULT=YES) should work at any time
  • Behavior should be consistent across VOD and live streams

Actual behavior

Two distinct anomalies observed, reproducible on both VOD and live streams, in both native Safari and THEOplayer:

  1. French-specific fallback: selecting the French track causes playback to fall back to English. This does not happen with German.
  2. Cannot return to English: in cases where a non-default track plays correctly, attempting to switch back to the DEFAULT=YES track (English) fails — the previous non-default track continues playing.

The fact that the issue reproduces in native Safari confirms this is an AVFoundation/WebKit-level regression, not a third-party player bug.

What we have already verified and ruled out

  • LANGUAGE codes are BCP-47 compliant (en, fr, de) ✓
  • EXT-X-VERSION:4 is present ✓
  • Audio codec removed from STREAM-INF CODECS (video-only) ✓
  • ASSOC-LANGUAGE attribute added matching LANGUAGE value ✓
  • Container metadata verified via ffprobe: mdhd box correctly contains language tags (e.g. "fra") ✓
  • Audio segment content verified via ffplay: correct audio in each language file ✓
  • French audio source file contains correct French audio content ✓
  • Issue reproduces in native Safari on iOS 26, confirming it is not a THEOplayer-specific bug
  • Issue does NOT reproduce on iOS 17/18 with the same manifest and segments

Additional notes

The VOD stream is packaged with AWS MediaConvert, CMAF output group, SEGMENTED_FILES, AAC-LC codec (mp4a.40.2), 128kbps, 48kHz stereo. English uses AudioTrackType ALTERNATE_AUDIO_AUTO_SELECT_DEFAULT; French and German use ALTERNATE_AUDIO_AUTO_SELECT. The live stream uses AWS MediaPackage with a similar CMAF/HLS output configuration.

Please advise whether this is a known regression in AVFoundation on iOS 26 and whether a fix is planned.

Update — Workaround found

After further investigation I have found a workaround that resolves the inconsistent track switching behaviour described above.

Observation

I noticed that changing the order of EXT-X-MEDIA audio entries in the manifest produced different results. Specifically, when the DEFAULT=YES track is listed first, switching behaviour is unreliable. When the DEFAULT=YES track is placed last, switching back to the default language works correctly.

Workaround

Reorder the EXT-X-MEDIA audio entries so that the DEFAULT=YES rendition appears last in the manifest:

#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="program_audio",LANGUAGE="de",NAME="Deutsch",AUTOSELECT=YES,DEFAULT=NO,CHANNELS="2",URI="audio_DEU.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="program_audio",LANGUAGE="fr",NAME="Francais",AUTOSELECT=YES,DEFAULT=NO,CHANNELS="2",URI="audio_FRA.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="program_audio",LANGUAGE="en",NAME="English",AUTOSELECT=YES,DEFAULT=YES,CHANNELS="2",URI="audio_ENG.m3u8"

In our case the manifest is generated programmatically, so the fix was applied at the job builder level by sorting audio sources to ensure the default track is always added last.

Notes

  • The original issue was intermittent, so I cannot guarantee this workaround covers every edge case
  • The behaviour described in the original post (French-specific fallback and inability to return to English) was part of a broader inconsistency affecting all tracks, not just French
  • The workaround has been verified on both VOD and live CMAF/HLS streams on iOS 26 with native Safari and THEOplayer

I am still filing this with Feedback Assistant as the root behaviour — track switching appearing to rely on position index when returning to the default rendition — appears to be a regression. If anyone has additional data points or a different explanation, please share.

On iOS 26, HLS alternate audio track selection behaves inconsistently
 
 
Q