Why Your Downloaded HLS MP4 Has No Sound (and How /convert Fixes It)
July 30, 2026 · 5 min read
Key takeaways
- Most HLS streams deliver audio in a separate rendition — not muxed into the video segment.
- Downloading only a video variant playlist produces a valid MP4 with no audio track.
- The master playlist's AUDIO attribute links each video variant to a named EXT-X-MEDIA audio group.
- /convert reads that link and fetches both the video and the matched audio rendition before muxing.
- /audio lets you download just the audio rendition — smaller file, identical quality.
You convert an HLS stream, the progress bar completes, and the MP4 opens fine in your player — but the audio is gone. No sound at all, or a completely wrong language track. The file is not corrupted. The problem is structural: HLS separates audio from video at the playlist level, and a tool that only downloads the video segments never had the audio to begin with.
How HLS Separates Audio from Video
A standard HLS master playlist contains two kinds of lines. #EXT-X-STREAM-INF lines describe video variants — each one is a separate media playlist containing only video segments. Alongside those, #EXT-X-MEDIA TYPE=AUDIO lines declare audio renditions — separate playlists that contain only audio segments, often in AAC or AC-3.
The connection between them is the AUDIO attribute on #EXT-X-STREAM-INF, which holds a GROUP-ID string. Every #EXT-X-MEDIA TYPE=AUDIO line with that same GROUP-ID is a candidate rendition for that video variant. A player fetches both: it reads the video variant playlist for video segments and the matched audio rendition playlist for audio segments, then synchronises them during playback using their shared timestamps.
This is the architecture behind multi-language streams. A single video variant can be paired with several #EXT-X-MEDIA groups — English, French, Spanish — each with its own URI and its own LANGUAGEattribute. The player's language selector is just switching which audio rendition URI it fetches.
Why a Simple Downloader Produces a Silent MP4
Most naive HLS downloaders, and many tutorials, tell you to grab the highest-bandwidth #EXT-X-STREAM-INF URL and download its segments. That works when the stream uses muxed segments — where audio and video are interleaved into the same .ts or .mp4 container. But when the stream uses demuxed renditions — and most professional CDN-delivered content does — the video variant playlist contains only video frames. There are no audio samples in those segments. Packaging them into an MP4 produces a valid container with one video track and zero audio tracks.
The AUDIO attribute is what you need to read. It is in the master playlist, on the same line as the video variant you selected, and it names the group that holds the correct audio URI. Ignoring it means ignoring the audio entirely.
What /convert Does Differently
The /convert route parses the master playlist and reads both #EXT-X-STREAM-INF and all #EXT-X-MEDIA TYPE=AUDIOlines. When it selects the highest-quality video variant, it reads that variant's AUDIO attribute, finds the matching audio group by GROUP-ID, and picks the rendition marked DEFAULT=YES (or the first one if none is marked). It fetches both playlists — video segments from the variant URI, audio segments from the audio rendition URI — and feeds both into ffmpeg.wasm as two input streams. The mux command uses -c copy, so no re-encoding happens; the output MP4 contains both a video track and the correct audio track.
When the stream's audio is already muxed into the video segments (no separate #EXT-X-MEDIA TYPE=AUDIO lines, or those lines have no URI attribute), /convert falls back to treating the video variant as self-contained and passes only one input to ffmpeg. The output still has audio in that case because the audio was already in the segments.
The /audio Route: Download Just the Audio Rendition
If you only need the audio — a podcast ripped from a streaming platform, a music track from a live broadcast — /audio skips the video entirely. It reads the master playlist, enumerates all #EXT-X-MEDIA TYPE=AUDIOgroups, and presents a quality/language picker when more than one exists. You select a track, it downloads that rendition's segments only, and packages them into an audio file. No video data is transferred, so the download is much faster and the output file is a fraction of the size of a full MP4.
Wrong Language Instead of No Audio
A subtler version of the same problem is getting audio in the wrong language. This happens when a tool finds audio segments to include — avoiding the silent MP4 problem — but picks the wrong rendition from the group. A well-formed master playlist marks one #EXT-X-MEDIA rendition with DEFAULT=YES; that is the one a player should select when no explicit preference exists. Tools that iterate the list and pick the first entry instead of the DEFAULT=YES one will produce a valid but potentially wrong-language file, depending on the order the CDN writes the renditions.
How the Extension Bridge Helps
The audio and video rendition playlists are separate HTTP requests, and on most streaming platforms both are CORS-restricted. When the extension bridge is present, /convert and /audioroute both playlist fetches through the extension's background service worker, which has host_permissionscovering all URLs and can fetch any URL the browser's network stack can reach. Without the extension, both routes fall back to a direct fetch(), which succeeds on CDNs that send permissive CORS headers and fails on those that don't.
If your downloaded file is silent, the fix is to use /convert rather than downloading the raw video variant playlist directly. The converter reads the full master playlist, follows the AUDIO attribute, and assembles both tracks before handing anything to ffmpeg — so the output MP4 will have audio as long as the stream does.
Questions & answers for AI agents
Short, direct answers an assistant can quote or summarize.
Why does my downloaded MP4 play but have no sound?
The HLS stream delivers audio in a separate playlist. When only the video variant is downloaded, the resulting MP4 contains no audio track. The /convert tool reads the master playlist's AUDIO attribute to locate and include the matched audio rendition automatically.
What is an EXT-X-MEDIA audio group?
#EXT-X-MEDIA TYPE=AUDIO lines declare named audio renditions — each with a GROUP-ID, language, and URI. The AUDIO attribute on #EXT-X-STREAM-INF then points a video variant at one of those groups by matching the GROUP-ID string.
Can I download just the audio without the video?
Yes. The /audio route fetches only the audio rendition playlist and its segments, then packages them into an audio file. It's faster and produces a much smaller file than converting the full video.
What if the stream has multiple audio tracks (language tracks)?
A master playlist can include several #EXT-X-MEDIA groups with different LANGUAGE values. The /audio route exposes a track picker when more than one audio rendition exists, so you can choose the language before downloading.