An M3U8 sniffer finds the stream links a video player requests. This one reads a HAR file, the network log you export from DevTools, so it sees the .m3u8 and .mpd URLs the player really loaded, even when JavaScript built them. For each one it shows the status, master or variant, the encryption declared in the playlist, the Referer and Origin that the request carried, and when a signed link expires. Subtitle files, key requests and direct video files are listed too, each type with its counter.
How the sniffer works
The HAR file is read by this page with the browser's FileReader and parsed as JSON. Each request in it is checked three ways, and one is enough:
- URL: the path ends in
.m3u8or.mpd, or the query string carries one (?file=movie.m3u8). - MIME type:
application/vnd.apple.mpegurl,application/x-mpegurl,audio/mpegurlorapplication/dash+xml. - Response body: text that starts with
#EXTM3Uor an<MPD>element. This catches APIs that serve a playlist from a URL like/api/stream?id=42.
When the HAR holds the response text (plain or base64), the sniffer parses it with the same engine as the M3U8 tester. A master playlist gets its variant count, top resolution, audio and subtitle tracks; a variant playlist gets its segment count, duration and live or on-demand status. Encryption comes from the #EXT-X-KEY lines: none, AES-128, SAMPLE-AES or DRM. A master rarely carries keys itself, so the sniffer reports the encryption of the variants captured in the same HAR, or tells you to check them.
Requests for the same URL are grouped (live playlists reload every few seconds), masters are listed first, and each variant points to its master. If the HAR also contains the AES-128 key request, you see its status and size: a 16-byte answer means the key was delivered.
Subtitles, keys, video files and segments
The rest of the log is sorted by type, with a counter for each, so a HAR of 3,000 requests comes down to a short list:
- Subtitles:
.vtt,.srt,.ttmland.dfxpfiles,text/vttresponses, and bodies that start withWEBVTT. The VTT to SRT converter turns a saved WebVTT file into SRT for a video player. - Keys: the URI of every
#EXT-X-KEYline, matched with its request in the HAR, plus.keyrequests and DRM license requests. Only the status and size are shown, never the key. - Video files: MP4, WebM and MOV files the player read directly. A player that fetched one file in hundreds of Range requests gives one entry with the full file size from
Content-Range. - Segments:
.ts,.m4sand fMP4 pieces are counted under the playlist or MPD that lists them, never one by one. Segments whose manifest is missing from the HAR are grouped by folder, which tells you the recording started too late.
How to export a HAR file in Chrome, Edge, Firefox and Safari
The order matters in every browser: open the Network tab first, then reload the page and press play. A HAR only holds the requests made while the tab was recording, and the player asks for its manifest in the first seconds.
Chrome
- Open the page with the video, then open DevTools with F12 (or Ctrl+Shift+I, Cmd+Option+I on a Mac) and select the Network panel.
- Tick Preserve log if the player opens on another page. Recording is on while the round button at the top left is red (its tooltip reads Stop recording network log).
- Reload the page and press play. Let the video run a few seconds.
- Click the download icon in the action bar at the top of the Network panel, Export HAR (sanitized)..., and save the file.
- Drop the file on the sniffer above. Or skip the file: right-click any request, choose Copy > Copy all as HAR (sanitized), and paste it under "Paste HAR JSON instead".
The sanitized export leaves out the Cookie, Set-Cookie and Authorization headers. Chrome can include them: enable Settings > Preferences > Network > Allow to generate HAR with sensitive data, then pick Export HAR (with sensitive data) in the export drop-down. The sniffer does not need it, so keep the sanitized file, especially if you share it.
Microsoft Edge
- Open the page, press F12 (or Ctrl+Shift+I) and open the Network tool.
- Reload the page and press play.
- In the action bar at the top of the Network tool, click Export HAR (sanitized) and save the file. Right-click a request > Copy > Copy all as HAR (sanitized) puts the same JSON on the clipboard.
Edge uses the same setting as Chrome for the full export: Customize and control DevTools > Settings > Preferences > Network > Allow to generate HAR with sensitive data.
Firefox
- Open the page, press Ctrl+Shift+E (Cmd+Option+E on a Mac) to open the Network panel. If the player opens on another page, turn on Persist Logs in the gear menu at the right of the Network toolbar.
- Reload the page and press play.
- Open the gear menu at the right of the Network toolbar and choose Save All as HAR. Copy All as HAR puts the same JSON on the clipboard: paste it with "Paste HAR JSON instead".
The Firefox HAR keeps the request headers, cookies included, and stores binary responses in base64. That is fine here, since the file stays in your browser and the sniffer shows cookie names only, but do not send it to anyone.
Safari (Mac)
- Turn on the developer tools once: Safari > Settings > Advanced, then tick Show features for web developers. The Develop menu appears in the menu bar.
- Open the page, choose Develop > Show Web Inspector (Cmd+Option+I) and select the Network tab.
- Tick Preserve Log if the player opens on another page, so the requests are not cleared when the page changes.
- Reload the page and press play.
- Click Export in the Network tab (or press Cmd+S while it is focused) and save the
.harfile.
If Export is greyed out, reload the page once more with the Web Inspector open. When a HAR has no response text for some requests, the sniffer still lists their URLs and headers, without the playlist details.
Why a page URL is often not enough (CORS)
The "Page URL" tab asks your browser to download the page and search its HTML. Browsers only let one site read another site's page when that site answers with an Access-Control-Allow-Origin header. Most video sites do not send it, and the browser blocks the read before any text arrives. The sniffer then tells you which case it is: blocked by the site, unreachable, an HTTP error, or an http:// page that an https:// page is not allowed to load.
Even when the read works, the stream URL is often not in the HTML. Players fetch a configuration in JavaScript and build the manifest URL, with a signed token, at the moment you press play. That URL only exists in the network log. The "Page source" tab helps when the link is written in the page: paste the source from view-source: or the outerHTML copied from the Elements panel, which includes what scripts added to the page.
Sniffer page vs browser extension
Sniffer extensions watch the requests of your tab as they happen. This page reads the same information after the fact, from a log you export. Each has its place:
| This sniffer page | Vidora extension | |
|---|---|---|
| What it reads | The HAR file you export, or source you paste | The network requests of the tab where the video plays |
| Install | None | Chrome extension |
| Output | The manifest URLs, their headers, and a command to test them | A downloaded video file, with separate audio merged in |
| Your data | The file is never uploaded | Runs in your browser |
| Limits | Only what DevTools recorded | Refuses DRM, does not work on YouTube |
Use the sniffer to understand a stream or to debug a player. If what you want is the video file, the extension skips the export step.
What to do with the m3u8 link
- Check it: the Test in M3U8 Tester button opens the M3U8 tester with the URL filled in. It plays the stream, finds separate audio and tests the AES-128 key. The URL travels in the part of the link after
#, which browsers never send to a server. - Run it from a terminal: "Copy m3u8-doctor command" and "Copy ffmpeg command" give
npx m3u8-doctorandffmpegwith the Referer and Origin from the HAR, for streams that refuse other sites. Every value is quoted for the shell you pick, so a URL cannot run anything when pasted. Cookie values are never included. - Turn it into a file: the Convert to MP4 button opens the M3U8 to MP4 converter with the link filled in. It turns it into one MP4 in your browser when the server allows it, and prints the ffmpeg command when it does not.
- No HAR at hand: the guide explains how to find the m3u8 URL by hand in the Network tab of DevTools.
A DASH manifest (.mpd) goes to the DASH player and MPD analyzer instead: Open in DASH Player fills it in.
Signed links: how long the URL keeps working
Streaming CDNs often sign their links so that they stop working after a few minutes or hours. When the expiry is written in the URL, the sniffer reads it and shows two things: the time left from now, and how long the link was valid after the HAR was recorded (from the request time in the HAR).
| Parameter in the URL | Used by |
|---|---|
Expires, expires, exp, e | CloudFront canned policy, nginx secure links, many video hosts |
Policy (with Signature and Key-Pair-Id) | CloudFront custom policy: the date is inside the encoded policy |
hdnts, hdnea, __token__, exp= in the path | Akamai tokens, Vimeo CDN |
X-Amz-Date + X-Amz-Expires | Amazon S3 presigned URLs |
X-Goog-Date + X-Goog-Expires | Google Cloud Storage signed URLs |
se with sig | Azure shared access signatures |
token holding exp or a JWT | Players that pass a JSON or JWT token |
A link signed with an opaque token (a hash with no date) is flagged as signed, without a time. When a link has expired, play the video again with the Network tab open and export a new HAR: the player asks for a fresh link.
Limits worth knowing
- The sniffer only sees what DevTools recorded. Start the recording before playback starts.
- A HAR without response bodies still gives the URLs, status and headers, but not the master or variant details and encryption.
- Encryption is read from the playlist. DRM signaled only inside the media segments is detected by the tester, not here.
- Signed URLs expire. A link from an old HAR can answer 403 even though it played when you recorded it, and an expiry hidden in an opaque token cannot be read.
- Segments are matched to their manifest from the playlist, the MPD templates and the folder. A site that serves segments from another folder without a manifest in the HAR shows them in a separate group.
- Keys are reported, not used: the sniffer never reads the key bytes, and DRM licenses cannot be turned into keys.