HLS M3U8 Player to Test/Debug/Demo Streams with Native HTML5 Playback
Paste any HLS (.m3u8) URL - live or VOD - and play, inspect and debug it right in your browser with hls.js. See renditions, bitrate, buffer health, latency, dropped frames, the event log and the raw manifest.
DRM playback needs HTTPS. Widevine works in Chrome, Firefox and Edge; PlayReady in Edge; FairPlay in Safari (certificate URL required). hls.js reads AES-128 keys straight from the manifest, so plain AES streams need none of this.
Player configuration
Tune common hls.js options below, or drop any advanced options into the config editor. Changes apply on the next Play - use Apply & reload to re-run the current stream.
The raw .m3u8 playlist text will appear here after you play a stream.
If the server blocks cross-origin requests (CORS), the raw text can’t be fetched even when hls.js can still play the stream.
Use this stream URL in your own app
What Is an HLS Player?
An HLS player is a video player that can read an .m3u8 playlist, fetch the media segments it points to, and stitch them back into continuous playback - switching quality on the fly as bandwidth changes. Unlike a plain <video> tag pointed at an MP4 file, it never downloads one large file: it downloads a few seconds at a time and decides, segment by segment, which quality level to request next.
Concretely, every HLS player performs the same four jobs:
- Parse the manifest - read the master playlist, build the list of available renditions, then load the media playlist for the level it wants to start on.
- Measure and choose - estimate available throughput from completed downloads and select the highest rendition that will stream without stalling. This is adaptive bitrate (ABR).
- Buffer and decode - fetch segments ahead of the playhead, decrypt them if
#EXT-X-KEYis present, and hand them to the browser's decoder through Media Source Extensions. - Keep the timeline correct - for live streams, refresh the playlist on an interval, track
#EXT-X-MEDIA-SEQUENCE, and handle discontinuities without breaking playback.
Three ways HLS actually gets played
| Type | How it works | Where you meet it |
|---|---|---|
| Native HLS | The operating system handles the manifest and segments internally. You just set the .m3u8 as the video source. Little visibility into ABR decisions. | Safari on macOS and iOS, Android media stack, most smart TVs |
| JavaScript player (MSE-based) | A library such as hls.js parses the playlist itself and appends segments via Media Source Extensions. Full control over ABR, buffering and error handling, plus detailed diagnostics. | Chrome, Edge, Firefox - and this test player |
| Native app SDK | Platform players like AVPlayer and ExoPlayer, wrapped by a vendor SDK to add DRM, analytics and offline playback. | iOS and Android apps |
This page is the second kind. It runs hls.js directly in your browser, so what you see - rendition list, bandwidth estimate, buffer level, level switches, errors - is exactly what a real hls.js-based player on your own site would experience with the same stream.
What the Player Info Numbers Mean
| Stat | What it tells you |
|---|---|
| Resolution | The frame size of the rendition currently being decoded, read from the video element - not from the manifest. If it differs from the level you selected, playback has not switched yet. |
| Level / rendition bitrate | The BANDWIDTH value declared for the active #EXT-X-STREAM-INF entry. Declared bitrate is a peak claim by the packager; actual segment bitrate can be lower. |
| Bandwidth estimate | hls.js's rolling estimate of your real throughput, measured from completed fragment downloads. ABR picks the highest level that fits comfortably under this number. |
| Buffer health | Seconds of media already downloaded ahead of the playhead. Healthy playback sits at 10-30s for VOD. Repeatedly dipping toward 0 means stalls are coming. |
| Target duration | The #EXT-X-TARGETDURATION declared segment length. For live, this drives how much latency you can realistically achieve - roughly 3x target duration in standard HLS. |
| Dropped frames | Frames the browser decoded but could not paint in time. Non-zero and climbing usually means the device is CPU-bound on that rendition, not that the stream is bad. |
| Live latency | How far behind the live edge you are. Compare it against target duration to tell an encoder/packager problem from a player buffering choice. |
| Level switches | Each entry in the log is an ABR decision. Frequent up/down flapping points to an unstable connection or a badly spaced bitrate ladder. |
Common HLS Playback Errors and What Causes Them
| What you see | Likely cause | Fix |
|---|---|---|
| Manifest load error, nothing in the log after the request | Missing CORS headers on the manifest or segments | Serve Access-Control-Allow-Origin (and allow the Range header) from the origin or CDN |
| Blocked request on an HTTPS page | Mixed content - an http:// stream URL | Serve the playlist and every segment over HTTPS |
| 403 or 401 on the manifest | Expired signed URL, wrong token, or referrer/IP restriction | Regenerate the signed URL; check that token params survived copy-paste |
| Manifest parsing error | File does not begin with #EXTM3U, or the server returned HTML (a login or error page) with a .m3u8 URL | Open the raw manifest viewer to see what actually came back |
| Master playlist loads, video never starts | Rendition playlist paths resolve incorrectly - relative URIs against an unexpected base | Verify the resolved media playlist URL in the event log |
| Audio plays, no picture (or the reverse) | Codec the browser cannot decode via MSE, or a CODECS attribute that does not match the actual segments | Test H.264 + AAC as a baseline; HEVC and AV1 support varies by browser and OS |
| Buffer stalled / append error | Discontinuity without #EXT-X-DISCONTINUITY, mismatched init segments, or non-aligned renditions | Repackage so all renditions share segment boundaries and GOP alignment |
| Key load error on an encrypted stream | The #EXT-X-KEY URI is unreachable or not CORS-enabled | Make the key endpoint reachable from the browser's origin |
| Live stream falls further behind over time | Encoder pushing segments slower than real time, or a stale playlist being cached | Check #EXT-X-MEDIA-SEQUENCE increments and CDN cache headers on the playlist |
Reading the Raw M3U8 Manifest
| Tag | What to check |
|---|---|
#EXTM3U | Must be the very first line. If it is missing, no player will accept the file. |
#EXT-X-STREAM-INF | One per rendition in a master playlist. Confirm BANDWIDTH, RESOLUTION, CODECS and FRAME-RATE are present and truthful - ABR decisions are made from these values. |
#EXT-X-MEDIA | Alternate audio and subtitle renditions, with GROUP-ID, LANGUAGE and DEFAULT. Missing group references are a common reason audio tracks never appear. |
#EXT-X-TARGETDURATION / #EXTINF | Declared vs actual segment durations. No #EXTINF value may exceed the target duration. |
#EXT-X-PLAYLIST-TYPE / #EXT-X-ENDLIST | VOD plus #EXT-X-ENDLIST means a finished asset. Neither present means the player treats it as live. |
#EXT-X-MEDIA-SEQUENCE | For live, this should advance on each playlist refresh. A frozen value means you are being served a cached playlist. |
#EXT-X-MAP | Present for fMP4 / CMAF streams - the initialisation segment. Absent for classic MPEG-TS segments. |
#EXT-X-KEY | METHOD=AES-128 or SAMPLE-AES, plus the key URI and IV. METHOD=NONE means clear. |
#EXT-X-PART / #EXT-X-PRELOAD-HINT | Low-Latency HLS partial segments. Their presence tells you the packager is configured for LL-HLS. |
#EXT-X-DISCONTINUITY | Signals a change in encoding parameters or timeline - ad breaks and stream splices need it, or playback will break. |
How to Test an HLS / M3U8 Stream
- Paste your URL - drop any HLS
.m3u8link (a master playlist or a single media playlist) into the box, or click a sample Live / VOD stream. - Hit Play - the stream loads with hls.js (or native HLS on Safari / iOS) and starts playing.
- Read the Player Info - watch the resolution, bitrate, bandwidth estimate, buffer health, dropped frames and (for live streams) latency update in real time.
- Switch renditions - force a specific quality level or leave it on Auto to test adaptive bitrate switching.
- Debug - use the event log to trace manifest parsing, level switches, fragment loads and errors, and open the raw manifest viewer to inspect the playlist itself.
- Share - copy the share link to reopen the exact same test, or grab the ready-made code to embed the stream in your own app.
Why Use This HLS Test Player?
- Live & VOD - automatically detects whether a stream is live or on-demand and adapts the stats it shows.
- Powered by hls.js - the same open-source engine used across the web, so what you see here matches real browser playback.
- Deep debug info - renditions, per-level bitrate, target segment duration, measured bandwidth, buffer ahead, dropped frames, latency and a full event log.
- Raw manifest inspection - view the actual master and media
.m3u8text to catch playlist issues. - 100% in-browser - nothing is uploaded; the player fetches the stream directly from its origin, just like your users’ browsers do.
- Copy-paste integration - ready-made JavaScript, HTML5 and cURL snippets for the exact URL you tested.
Frequently Asked Questions
What is an M3U8 / HLS stream?
HLS (HTTP Live Streaming) delivers video as a text playlist (the .m3u8 file) that points to short media segments. A master playlist lists multiple quality renditions; each rendition has its own media playlist of segments. This tool plays that playlist and shows you exactly how it behaves. For a deeper walk-through, see our guide to M3U8 players and HLS streaming.
Why won’t my stream play here?
The most common cause is CORS: the stream’s server must send Access-Control-Allow-Origin headers for a browser on another domain to load it. Other causes are an incorrect URL, a 404, an expired signed URL, or a codec the browser can’t decode. The status message and the event log will tell you which one it is.
Does it support live streaming?
Yes. Live playlists are detected automatically; the tool then shows the live latency (how far behind the live edge you are) alongside the other stats.
Can I force a specific quality?
Yes. The Renditions panel lists every level from the manifest - click one (or use the dropdown) to lock playback to that quality, or choose Auto to let hls.js pick based on bandwidth.
Which browsers work?
Any modern browser that supports Media Source Extensions (Chrome, Edge, Firefox and Chromium-based browsers) runs the full hls.js engine with all debug data. Safari and iOS fall back to native HLS playback, where some hls.js-specific stats are unavailable.
Is my stream URL sent anywhere?
No. The player runs entirely in your browser and fetches the stream directly from its origin server. The only thing that ever contains your URL is the optional share link you choose to copy.
How do I encrypt or DRM-protect an HLS stream?
HLS can be encrypted with AES-128 or SAMPLE-AES, and premium content is usually protected with DRM such as Widevine, FairPlay and PlayReady so segments can’t be downloaded or shared. See our guide to HLS streaming encryption and DRM for how it works, or use VdoCipher’s secure player to get encrypted, DRM-protected, watermarked HLS playback out of the box.
Terms & Privacy
- This free HLS test player is provided on an “as is” basis for general testing and debugging and does not use VdoCipher player or technology. We do not guarantee playback of every stream, browser compatibility, or fitness for any purpose.
- Playback happens locally in your browser and streams are fetched directly from their origin. We do not proxy, store, or transmit your stream content or URLs to our servers.
- By using this tool you confirm you have the right to access and test the streams you load. You are solely responsible for the URLs you enter and for complying with all applicable laws and the stream provider’s terms.