HLS Player: Test an M3U8 Stream Online
Paste an .m3u8 link and play it in your browser. See the renditions, bitrates and codecs, whether the stream is live and how far behind, and a plain explanation when it does not play. Free, no sign-up.
Stream URL
Player
What the player tells you
HLS (HTTP Live Streaming) cuts video into short files and lists them in a text playlist, the .m3u8. A player downloads the playlist, then the segments, one after another, over plain HTTPS. That is why HLS plays in a browser and through a CDN, where RTMP does not.
A master playlist lists several renditions of the same stream at different resolutions and bitrates; the player picks one and switches as the connection changes. A media playlist lists the segments of one rendition. The quality list in the readout shows the renditions of a master playlist; a media playlist has just one.
A live playlist keeps growing and has no end tag; a VOD playlist ends with #EXT-X-ENDLIST. The segment target is the longest segment the server promises. Players start about three targets from the live edge, so with 6-second segments a viewer sits roughly 18 seconds behind, before any encoder delay.
Why a stream that works elsewhere fails in a browser
- CORS. A browser only lets a page read a file from another site if that server sends Access-Control-Allow-Origin. Desktop players such as VLC and ffplay do not check it, which is why they play a stream this page cannot.
- Mixed content. An HTTPS page may not load an http:// stream. Serve the playlist and the segments over HTTPS.
- Expired or locked URLs. Signed URLs carry a token that expires, and some CDNs check the Referer. A 403 here usually means one of the two.
- Codecs. H.264 video with AAC audio plays in every current browser. HEVC, AV1 and some audio codecs depend on the browser and the device.
Streaming platforms work the other way round: your encoder sends RTMP to YouTube, Twitch or Kick, and they turn it into HLS for viewers. Their watch pages are not .m3u8 links, and their internal playlists are signed and locked to their own players, so they will not play here.
Reading an M3U8 file
An .m3u8 is plain text: open it in a browser tab or a text editor. A master playlist names one media playlist per rendition, with the tags the player uses to choose between them:
#EXTM3U #EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720,CODECS="avc1.64001f,mp4a.40.2" 720p/index.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=6000000,RESOLUTION=1920x1080,CODECS="avc1.640028,mp4a.40.2" 1080p/index.m3u8
| Tag | What it means |
|---|---|
#EXTM3U | The first line of every HLS playlist. A file without it is not one, which is the "not an HLS playlist" error above. |
#EXT-X-STREAM-INF | In a master playlist: one rendition. BANDWIDTH is its peak bitrate in bits per second; RESOLUTION, CODECS and FRAME-RATE describe it; the next line is its media playlist. |
#EXT-X-TARGETDURATION | The longest segment, in whole seconds. Every segment, rounded, must fit within it, and players time their refreshes and their distance from the live edge from it. |
#EXT-X-MEDIA-SEQUENCE | The number of the first segment listed. In a live playlist it keeps rising as old segments drop off the top. |
#EXTINF | The length of the next segment in seconds, followed on the next line by the segment's address. |
#EXT-X-PLAYLIST-TYPE | VOD if the playlist never changes, EVENT if segments are only added. A live window that drops old segments has no type. |
#EXT-X-DISCONTINUITY | The next segment does not continue the previous one: a new file, new timestamps or a new encoding. A 24/7 playlist that joins several videos needs one at every join, or players can stall or skip there. |
#EXT-X-PROGRAM-DATE-TIME | The wall-clock time of a segment's first frame, which lets a player show real time and line streams up. |
#EXT-X-ENDLIST | No more segments will be added: an on-demand video, or a live event that has finished. |
Making an HLS stream to test
If you need a stream of your own, FFmpeg writes one from any video file. This plays the file in real time and keeps a live window of six 4-second segments:
ffmpeg -re -i input.mp4 \ -c:v libx264 -preset veryfast -b:v 3000k -g 60 -keyint_min 60 -sc_threshold 0 \ -c:a aac -b:a 128k \ -f hls -hls_time 4 -hls_list_size 6 -hls_flags delete_segments \ stream.m3u8
For 30 fps input, -g 60 puts a keyframe every 2 seconds and -sc_threshold 0 stops extra keyframes at scene cuts, so each 4-second segment starts cleanly. Drop -re and use -hls_playlist_type vod to write an on-demand playlist instead. Serve the folder over HTTPS, and send the CORS header and the right content types, for example in nginx:
location /hls/ {
add_header Access-Control-Allow-Origin * always;
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
}Without the header, browsers on other sites, this page included, refuse to read the stream, while VLC still plays it.
Need a stream that never stops?
TheLoops keeps a video or a playlist live on YouTube, Twitch and Kick around the clock from the cloud, with no computer left on. Free 24-hour trial.
Start freeFAQ
A UTF-8 text playlist. For HLS it lists either the video segments to play in order or, in a master playlist, the different renditions of the same stream. Open one in a text editor and it starts with #EXTM3U.
VLC is a desktop program, so it ignores the browser rules: it plays http:// streams, does not need CORS headers and decodes more codecs. A web page needs an HTTPS stream whose server allows cross-site reads (CORS), and a codec the browser supports.
No. A watch page is not an .m3u8 link, and the platforms' internal HLS playlists are signed, expire quickly and only work in their own players. This tool is for streams you host or can get a public HLS link for.
No. Your browser fetches the playlist and the segments straight from the stream's server. The page has no server-side part for the player, does not save the URL and does not put it in the address bar, so it never reaches our analytics.
HLS players start a few segments back from the live edge, about three segment targets, so they have something buffered. With 6-second segments that is roughly 18 seconds, plus whatever the encoder and the CDN add. Low-latency HLS and shorter segments cut it down.
AES-128 encrypted HLS plays if the key URL is reachable from the browser, with the same CORS rule as the playlist. DRM-protected streams (Widevine, FairPlay, PlayReady) need a licence server and do not play here.
Yes. On Android and on current iPhones the page plays through hls.js and shows every reading. On iPhones older than iOS 17.1, Safari plays HLS itself, so the stream plays but the page cannot list or switch the renditions.