How to Download iframe-Embedded Videos from Any Website
iframe embeds break most downloaders because of cross-origin restrictions. Here's how to identify the underlying video and download it as MP4.
A tutorial site, a course platform, a corporate training portal, or a blog post embeds a video. You want to save it for offline viewing. You install a downloader extension and… nothing happens. The download button doesn’t appear. Right-click is disabled. The Network tab in DevTools shows confusing requests to a domain you’ve never heard of.
The problem is almost always the same: the video is inside an <iframe> from a different origin than the page you’re on. Browser security rules prevent extensions and JavaScript from reaching into a cross-origin iframe to inspect or interact with its contents. This guide explains why iframe embeds are different, how to identify the underlying video, and three reliable methods to download from them.
What an iframe embed actually is
An <iframe> is a window-within-a-window: an HTML element that loads a completely separate web page inside the parent page. The parent page can specify the iframe’s URL (the src attribute) but cannot read or modify the iframe’s contents if the iframe loads from a different domain.
A Vimeo embed on a tutorial blog typically looks like this in the HTML:
<iframe
src="https://player.vimeo.com/video/123456789?h=abc123def"
width="640"
height="360"
allow="autoplay; fullscreen"
allowfullscreen>
</iframe>
The blog page is at, say, tutorialsite.com/article-about-x. The iframe loads player.vimeo.com/video/123456789. From the browser’s perspective, these are two completely separate documents — they happen to render together on screen but are isolated by the same-origin policy.
Most popular video embeds work this way:
- Vimeo:
player.vimeo.com/video/{id} - YouTube:
youtube.com/embed/{id}(mentioned for context only — Chrome Web Store policy means we don’t support YouTube downloads) - Wistia:
fast.wistia.com/embed/iframe/{id} - Loom:
loom.com/embed/{id} - Bunny Stream:
iframe.mediadelivery.net/embed/{lib}/{id} - Cloudflare Stream:
iframe.videodelivery.net/{uid} - JW Player:
cdn.jwplayer.com/players/{id} - Brightcove:
players.brightcove.net/{account}/{player}_{video}/index.html
Why same-origin policy is the problem
A browser extension that’s “active on a tab” only sees the events and DOM of that tab’s main document. The cross-origin iframe is its own document with its own origin. The extension cannot:
- Inspect the
<video>element inside the iframe - Listen to network requests originating from the iframe (without
<all_urls>permission, which most extensions don’t request) - Read the iframe’s URL parameters or auth state
The result: an extension that works perfectly when you visit Vimeo directly fails to detect the same Vimeo video when it’s embedded on a blog.
Method 1: Open the iframe in a new tab (simplest)
The single most reliable trick:
- Right-click on the embedded video → Inspect (Chrome DevTools opens at the right element)
- In the DOM panel, look up the tree for an
<iframe>element - Note the
srcattribute — it’s the iframe URL - Open that URL in a new tab
Now the iframe is the top-level document in its own tab. Cross-origin restrictions go away because the extension is now active directly on the embed’s origin.
In the new tab:
- Wait for the player to load and the video to start
- Click the extension icon
- Pick the quality, click Download
This is the workflow we recommend most often because it works for every iframe-embedded video without requiring extension permission upgrades.
Video Downloader One-for-All handles iframe embeds via this workflow seamlessly. The extension also flags when an iframe is detected on the current page and offers a one-click “Open embed in new tab” action so you don’t have to dig through DevTools.
Method 2: Find the iframe URL programmatically
If a page has multiple embedded videos and you want to script the discovery:
// Run in the page's DevTools console
document.querySelectorAll('iframe').forEach((f, i) => {
console.log(`${i}: ${f.src}`);
});
This lists every iframe on the page with its source URL. Filter by the embed providers you recognize:
document.querySelectorAll('iframe').forEach(f => {
if (f.src.includes('vimeo') || f.src.includes('wistia') || f.src.includes('jwplayer')) {
console.log(f.src);
}
});
Open each URL in a new tab and download as in Method 1.
Method 3: yt-dlp on the parent page URL
yt-dlp has an extractor list that includes most popular iframe embed providers. Pass the parent page URL and yt-dlp scans it for iframe embeds, resolves the underlying video, and downloads:
yt-dlp "https://tutorialsite.com/article-about-x"
If the parent page has multiple videos, yt-dlp prompts you to pick one or downloads all (depending on version and flags). To download all:
yt-dlp --no-playlist --yes-playlist "https://tutorialsite.com/page-with-multiple-videos"
When yt-dlp doesn’t recognize the embed provider, it falls back to its generic extractor, which scans for .m3u8, .mpd, and .mp4 URLs in the page HTML and JavaScript. Hit rate varies — works on most embeds, fails on some custom or obfuscated ones.
Why the embed sometimes shows “Not available in your region”
Some iframe embeds set domain restrictions: the embed only plays on specific parent domains. When you open the embed’s iframe URL directly in a new tab, the embed sees the new tab’s origin (which is the embed provider’s domain itself) as the parent.
For most embed providers (Vimeo, JW Player, Brightcove), this is fine — opening the embed URL directly works because the domain restriction is lifted when there’s no parent.
For a few stricter setups, the embed may refuse to play. In those cases:
- The embed is enforcing the original domain as a security measure
- Bypassing this restriction is generally against the embed creator’s intent
- We do not provide a workaround
If the embed plays in the parent context but not when opened directly, you’ve hit this restriction. Method 3 (yt-dlp on the parent URL) sometimes works because yt-dlp parses the embed metadata server-side and can sometimes extract a CDN URL that bypasses the iframe entirely.
Custom video player iframes (no recognized provider)
Some sites build their own video player and embed it via iframe from their own domain (e.g., cdn.example.com/player/{id}). These don’t match any extractor’s known patterns, so yt-dlp’s specific extractors don’t help.
The path:
- Open the iframe URL in a new tab (Method 1)
- Open DevTools → Network tab
- Play the video, look for
.m3u8,.mpd, or.mp4requests - The browser extension should detect them automatically; if it doesn’t, copy the URL and use FFmpeg
For sites that obfuscate the manifest URL (uncommon but exists — particularly on premium course platforms), you may have to read the iframe’s JavaScript to find where it constructs the URL. This is rare; most iframe video players use standard HLS or DASH URLs.
Common questions
Why does my downloader show no buttons on a page with an embedded video?
Because the video is in a cross-origin iframe and the extension doesn’t have access. Open the iframe URL in a new tab (right-click → Inspect → find the iframe src).
Can extensions just request permission to read all iframes?
They can request <all_urls> host permission, which would let them inject content scripts into every iframe regardless of origin. We deliberately don’t do this because:
- It’s a privacy red flag — many users (correctly) refuse to install extensions with that permission
- Chrome Web Store flags broad-permission extensions for additional review
- The “open in new tab” workflow is roughly as fast and avoids the permission prompt
The extension instead requests activeTab (only the current tab when the user clicks) and offers the iframe-detection flow when iframes are present.
Why does right-click → Save Video As work on some embeds but not others?
When the embed serves a single progressive MP4 file via the <video src="..."> attribute (not blob URL, not MSE-fed), the browser’s native context menu can save it. This is increasingly rare; most modern embeds use HLS or DASH which produces a blob URL — see How to Download Blob Videos in Chrome for why blob URLs can’t be saved that way.
What if the iframe is on a page behind a login wall?
The same techniques work — your browser session is the parent tab’s session, but when you open the iframe URL in a new tab, the new tab inherits the same session for the embed provider’s domain. As long as the embed provider sees you as authenticated (e.g., a paid Vimeo Showcase you have access to), the download works.
Are nested iframes a problem?
Occasionally — a site embeds an iframe that itself contains an iframe. Repeat the “right-click → Inspect → find iframe src” process iteratively until you reach the bottom-most iframe that actually contains the video element. Method 3 (yt-dlp) handles nested iframes automatically in many cases.
Can I detect iframe-embedded videos on a page programmatically?
Yes — the JavaScript snippet in Method 2 lists all iframes. Filter for known video provider domains. The extension does this automatically in the background and surfaces a notification when it detects iframes that contain video.
Comparison
| Situation | Best method |
|---|---|
| Single video on a tutorial blog | Open iframe URL in new tab → extension |
| Page with many embedded videos | yt-dlp on the parent page URL |
| Custom (non-standard) embed | DevTools Network + extension or FFmpeg |
| Domain-restricted embed | yt-dlp sometimes; otherwise use the original site |
Bottom line
iframe embeds break most downloaders not because of malice but because of the same-origin policy that’s fundamental to browser security. The workaround is to open the iframe URL in its own tab, where the cross-origin restriction no longer applies.
Install Video Downloader One-for-All — it detects iframes and offers a one-click “open in new tab” action so the workflow stays seamless. For Vimeo specifically (the most common iframe embed source), see How to Download Vimeo Videos. For when the embed uses blob URLs, see How to Download Blob Videos in Chrome.