WAVE MP4
HLS · to · MP4

Convert HLS to MP4

HLS is a streaming format: a .m3u8 playlist that points at many small .ts segments. Wave concatenates the segments you already have into a single MP4 - no re-encoding, no upload. Wave does not download HLS streams from remote servers; that step is browser-CORS-blocked and needs a tool like yt-dlp on your own machine first.

Under the hood

What actually changes

HLS segments source VIDEO H.264 / HEVC AUDIO AAC MP4 same streams VIDEO copied AUDIO copied REMUX container change
Local .ts or .m4s segments are concatenated at the NAL level. No decoding, no re-encoding. Wave does not download remote HLS streams - CORS blocks that.

HTTP Live Streaming (HLS) is Apple's streaming spec, published in 2009 and now the delivery format for most live and on-demand video on the web outside of MPEG-DASH deployments. The client fetches an .m3u8 playlist (a small text file listing segment URLs), then downloads .ts (MPEG Transport Stream) segments in sequence and plays them back-to-back. The playlist plus segments together are what's on your disk when you've captured an HLS stream with yt-dlp, N_m3u8DL, or a browser dev-tools "save all resources" workflow.

The MP4 conversion is a stream concat - each .ts segment already contains H.264 video and AAC audio (the standard HLS profile) or HEVC video and AAC audio (the HLS 2.0 profile). Wave reads the playlist, opens each segment file locally, glues the video frames end-to-end, wraps them in an MP4 container, and writes the output. No re-encoding (see Remux vs re-encode for why that's a big deal), no upload; the operation is bounded by disk speed. A ten-minute HLS stream typically finishes in under a minute.

Where this page can't help: downloading segments from a remote HLS server. Browser CORS policy blocks Wave from fetching arbitrary origins - even if you paste in an .m3u8 URL that points at a working stream, the browser will refuse the segment fetches unless the origin sends the right CORS headers, which most streaming providers deliberately do not. The practical workflow is to capture the segments locally first with yt-dlp (`yt-dlp -f best <stream_url>`) or N_m3u8DL_DASH, which runs outside the browser and doesn't have CORS constraints, then feed the resulting playlist + segments to Wave.

HLS profiles matter for the concat quality. Bog-standard HLS uses H.264 Main or High profile at 4:2:0, which every consumer player decodes; the MP4 output plays anywhere. HEVC HLS (fMP4 or TS) requires HEVC decoders on the playback side. Live-encrypted HLS with AES-128 or SAMPLE-AES protection is a separate story: encrypted segments need decryption keys before concat, and Wave won't process encrypted segments because the pattern is almost always about circumventing DRM.

How to convert

Three steps.

  1. 01

    Step 1

    Capture the HLS stream to disk first, with yt-dlp or N_m3u8DL. You should end up with a folder of .ts segments plus an .m3u8 playlist.

  2. 02

    Step 2

    Drop the .m3u8 playlist (or the folder of .ts segments) onto Wave. Wave reads the playlist and concatenates the segments in order.

  3. 03

    Step 3

    Save the output. The MP4 contains the same H.264 or HEVC video and AAC audio, in a single-file container.

FAQ

Answers, specifically.

Can Wave download the HLS stream directly from the .m3u8 URL?

No. Browser CORS policy blocks Wave from fetching from arbitrary streaming origins. Capture the segments locally first with yt-dlp (`yt-dlp -f best <stream_url>` on the command line) or a browser extension like Video DownloadHelper - both work outside browser CORS constraints. Once the segments are on disk, Wave stitches them.

Do I need every .ts segment for the conversion to work?

Yes. HLS segments are typically 4-10 seconds each; a missing segment shows as a gap in the output MP4. If yt-dlp reported errors during capture, some segments may be missing - re-run the download for those specific segments.

HEVC HLS - does it work?

Yes. Wave detects HEVC-in-TS during the concat and writes the output MP4 with the hvc1 codec tag for Apple compatibility. Playback needs HEVC decoders on the viewing side (universal on modern devices, Windows 10 needs the HEVC Extensions app).

The playlist references separate audio and video streams (fMP4).

HLS 2.0 uses fragmented MP4 segments with audio and video as separate playlists. Wave handles this - the master playlist tells Wave which audio playlist pairs with which video playlist, and the concat runs in parallel. Output is a single MP4 with muxed audio and video.

Encrypted HLS (AES-128 or SAMPLE-AES) - can I stitch it?

No. Encrypted HLS needs the decryption key, and processing DRM-protected streams is out of scope for Wave. If you have legitimate access to the key (a corporate video training stream, an owner-published HLS with your license), decrypt segment-by-segment with `openssl enc -aes-128-cbc -d -in seg.ts -out seg.dec.ts -K <key> -iv <iv>` before feeding to Wave.

The output audio and video are out of sync.

HLS segment timestamps must be monotonic across the playlist. If your capture used variable segment durations or skipped ahead, drift accumulates. Try re-capturing with fixed segment length (yt-dlp's `--hls-prefer-native` and letting it choose segment size).

Multi-audio HLS (dubbed audio, described audio) - which track does Wave use?

The default-flagged audio playlist. Multi-audio pass-through is on the roadmap; for now a specific alternate track requires ffmpeg locally: `ffmpeg -i playlist.m3u8 -map 0:v -map 0:a:1 -c copy output.mp4` where 0:a:1 picks the second audio track.

Related

Other converters.