HLS Audio Track Switches but Has No Sound: A Request-by-Request Diagnosis
Diagnose silent alternate HLS audio by checking rendition-group links, audio playlist requests, segments, codecs, timestamps, player events, and device output.
A language or commentary option can appear in an HLS player, accept a click, and still produce silence. The visible selection only proves that a track was presented to the interface. It does not prove that the selected rendition belongs to the active variant, that its playlist loaded, that audio segments arrived, or that decoded audio reached the device output.
This guide follows that chain in order. Use only streams you own or are authorized to inspect, and remove signed URLs, cookies, tokens, viewer identifiers, and IP addresses before sharing a trace.
Verification method — September 19, 2026: We ran a Node.js 24.12.0 script against two synthetic multivariant playlists. The valid fixture contained two alternate-audio renditions in one audio group and a variant referencing that group. The broken fixture referenced the nonexistent group audio-v2 and marked both members of audio as DEFAULT=YES. The script detected both structural errors and accepted the valid fixture. It parses only the playlist fields used by this controlled example. It does not fetch media, decode audio, switch a real player, test browsers or devices, or replace a standards-aware HLS validator. The script is stored at scripts/test-hls-audio-rendition-links.cjs.
Confirm what “switched” actually means
First record the exact symptom. Did the menu highlight a different language? Did the player emit a track-switch event? Did it request the selected audio playlist? Did it fetch new audio fragments? Did the media clock keep moving? These are different checkpoints, not interchangeable proof.
| Last confirmed checkpoint | What remains unproven | Next evidence |
|---|---|---|
| Menu selection changed | Player accepted or loaded the rendition | Player track events and selected track ID |
| Player reports the new track | Its playlist and fragments loaded | Network requests for the selected audio URI |
| Audio fragments return 200 | They contain usable, synchronized audio | Response type, bytes, demux/decode errors, timestamps |
| Audio buffer advances | Sound reaches the intended output | Element volume, mute state, OS mixer, output route |
| Sound returns after switching back | Alternate rendition path is healthy | Compare the two playlists, codecs, fragments, and timelines |
Keep the Network panel open before reproducing the switch and preserve the log. Note the active variant, selected audio name and language, player version, browser, operating system, device, output route, and the precise switch time. Our M3U8 developer-tools guide provides a privacy-safe request checklist.
Verify the rendition-group wiring
Alternate HLS audio is declared with #EXT-X-MEDIA:TYPE=AUDIO. Tags sharing the same GROUP-ID form a rendition group. A variant's #EXT-X-STREAM-INF AUDIO attribute must match the GROUP-ID of an audio rendition group elsewhere in the multivariant playlist.
Check the selected path, not just whether any audio tag exists:
- Find the active
#EXT-X-STREAM-INFline and record itsAUDIOvalue. - Find every audio
#EXT-X-MEDIAentry with that exactGROUP-ID. - Confirm each member has a unique
NAMEand usefulLANGUAGEmetadata. - Confirm no group has more than one
DEFAULT=YES; whenDEFAULT=YESis present, RFC 8216 requiresAUTOSELECT=YES. - Resolve the selected rendition's
URIrelative to the multivariant playlist URL. - If multiple audio groups serve different variants, verify that corresponding groups contain the same set of alternatives as required by the specification.
Apple's alternate-media documentation notes that an omitted rendition URI can mean the described media is included in the variant. Do not report that as a missing URL without checking the packaging design. Also inspect CHANNELS where channel layouts differ; RFC 8216 requires it when two renditions use the same codec but different channel counts.
Our controlled fixture found two manifest-level mistakes, but it cannot establish that a real silent track has either mistake. Run a full validator and inspect the requests before drawing that conclusion.
Follow the selected audio request chain
After selecting a track with an external URI, look for its media-playlist request and then its initialization section, key, and media segments. Record final URLs after redirects, response status, content type, transferred bytes, timing, cache headers, and the first failing resource.
| Network observation | Likely investigation area | Controlled next step |
|---|---|---|
| No request for the selected audio playlist | UI-to-player selection, wrong track ID, inactive group | Log the player's selected track before and after the action |
| Audio playlist returns 401/403 | Authorization or signed child URL | Compare credentials and expiry with the working rendition |
| Audio playlist returns 200, segments 404 | Packaging order, path resolution, origin/CDN availability | Request the exact resolved segment with equivalent authorization |
| Requests return 200 with zero or tiny bodies | Empty/error response hidden behind success status | Inspect content length, type, and permitted response sample |
| Audio fragments load but append or decode fails | Codec, container, initialization, encryption, timestamp issue | Capture demux, append, media, and decode errors |
| Requests stop only after a quality change | New variant references a different or incomplete audio group | Compare AUDIO groups for both variants |
A status of 200 is not proof of audio. A CDN or application can return an HTML error document with a success status, and a valid media container can still hold silence or an unsupported format. Avoid publishing protected fragments in bug reports.
Check codecs, channels, and the timeline
The variant's CODECS declaration needs to describe the formats used by the variant stream, including formats present in referenced rendition groups. Compare that declaration with the actual initialization and media data using tools approved for your content. Check whether the affected browser and device support the audio codec and channel layout.
Apple's authoring guidance says separate audio must use EXT-X-MEDIA; alternative audio should cover the entire content duration. It also requires discontinuities to align across variants and renditions. Around the switch point, compare media timestamps, discontinuity markers, initialization sections, encryption/key changes, and whether the selected audio buffer covers the current video time.
A track can load correctly yet remain inaudible if its timeline starts elsewhere, its samples are silent, or the decoder rejects the format. Conversely, an event named “switched” does not prove that the first decoded sample was rendered. Keep playlist, network, buffer, and output evidence separate.
Record the player path and its events
In hls.js, record AUDIO_TRACKS_UPDATED, AUDIO_TRACK_SWITCHING, AUDIO_TRACK_LOADING, AUDIO_TRACK_LOADED, AUDIO_TRACK_SWITCHED, fragment events, buffer events, and ERROR. Save the selected hls.audioTrack, the track metadata, and error details and fatal fields. The hls.js API explicitly lists audio-track load errors and timeouts, which are more useful than a generic “no sound” report.
Do not assume native HLS exposes the same events. The browser's HTMLMediaElement.audioTracks API has limited availability according to MDN, so code that depends on it is not a universal cross-browser diagnostic. On native playback, use the browser or device's media diagnostics and the events actually supported there.
If the entire presentation stalls rather than only becoming silent, use the broader HLS buffering diagnosis. For failures that begin before playback, use the HLS playback troubleshooting checklist.
Rule out mute and output routing last—but do rule them out
Before changing the manifest, confirm the video element is not muted, its volume is above zero, the tab and site are not muted, and the operating-system mixer has not muted the browser. Check the actual output device: Bluetooth reconnects, HDMI displays, casting, headphones, and accessibility routes can move audio away from the expected speaker.
Use a known-good authorized stream in the same browser session as a control. If it is also silent, investigate the browser and output path before blaming the selected rendition. If only one HLS audio track is silent while another works at the same playback time, compare the rendition-specific network and media evidence.
Do not solve an output-routing problem by rewriting the playlist, and do not solve a broken child playlist by repeatedly calling video.play().
Test switches at difficult boundaries
One successful switch near the beginning is weak evidence. For each supported browser and real device, test the default track and every user-selectable alternative at these points:
- Before playback begins, if the product allows preselection.
- During steady playback in more than one video quality.
- Near a segment boundary and after a seek.
- Before and after a declared discontinuity, ad break, or key change.
- After a brief network loss and after the app returns from the background.
- With stereo and multichannel output routes your product officially supports.
Record whether the selection persists across a video-quality change. A desktop browser narrowed to phone width does not test mobile decoding, Bluetooth routing, background policy, or native HLS behavior. Mark untested platforms as untested instead of generalizing from one browser.
Write an actionable result
A useful incident report might say: “At 14:03:12, hls.js selected German track ID 1. The German audio playlist returned 200, but its first segment returned 404; English continued from the same video position. Query tokens were removed.” That gives the player, packaging, and CDN owners a first failing request.
Include the active variant URI, referenced audio group, selected rendition metadata, first failing audio resource, codec/channel information, switch event sequence, current playback time, relevant buffered range, browser/player versions, and output route. Do not collapse all of that into “the language button is broken.”
References
- RFC 8216: HTTP Live Streaming, alternative renditions and rendition groups
- Apple: Adding alternate media to a playlist
- Apple: HLS authoring specification for Apple devices
- hls.js audio track API
- hls.js event listener reference
- hls.js error details
- MDN: HTMLMediaElement audioTracks
Diagnose silence as a chain: manifest relationship, selected playlist, audio objects, demux and decode, synchronized buffer, then output route. The first missing checkpoint identifies the next owner and avoids speculative changes elsewhere in the stack.