Want to embed an M3U8 video player into your website, blog, or forum? This article provides complete code examples from basic embedding to advanced customization, covering responsive layouts, autoplay configuration, and the most common CORS cross-origin error solutions. No programming experience required β just copy and paste the code.
Table of Contents
- Why Choose iframe Embedding?
- Basic Embed Code (Get Started in 3 Minutes)
- Responsive Layout: Mobile & Desktop
- URL Parameters: Customize Playback Behavior
- Platform-Specific Embed Guides
- CORS Cross-Origin Errors: Causes & 5 Solutions
- Advanced Techniques: Autoplay, Mute & Event Listening
- Frequently Asked Questions
Why Choose iframe Embedding?
iframe (inline frame) is the simplest and safest way to embed third-party content into web pages. Compared to directly importing JavaScript libraries (like hls.js), iframe embedding offers the following advantages:
- Zero coding barrier: Just copy a snippet of HTML code β no JavaScript or video protocol knowledge required
- Automatic compatibility: The player internally handles HLS.js loading, browser compatibility, mobile adaptation, and other complex logic
- Isolation security: Scripts inside the iframe run in an isolated environment and won't affect your website's other functionality
- Instant updates: When the player is upgraded, the embedded version syncs automatically without manual code changes
π‘ Use Cases: iframe embedding is particularly suitable for WordPress blog posts, Discuz/Flarum forum threads, corporate product showcase pages, online education course pages, and any scenario requiring quick video player integration.
Basic Embed Code (Get Started in 3 Minutes)
Simplest Embedding Method
Copy the following code into your webpage's HTML, replacing YOUR_M3U8_URL with your actual video stream URL:
<iframe
src="https://m3u8-player.cc/player.html?url=YOUR_M3U8_URL"
width="100%"
height="400"
frameborder="0"
allowfullscreen>
</iframe>
For example, here is a complete example using a test stream URL:
<iframe
src="https://m3u8-player.cc/player.html?url=https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"
width="100%"
height="400"
frameborder="0"
allowfullscreen>
</iframe>
β οΈ Important: Make sure your M3U8 link uses the HTTPS protocol. If your website is HTTPS (which most modern sites are) but the video stream is HTTP, the browser will block the load, causing a "mixed content" error β and the console may not show a clear error message.
Responsive Layout: Mobile & Desktop
The basic code above may cause width overflow or distorted aspect ratios on mobile devices. Here are optimized responsive embedding solutions that automatically adapt to a 16:9 video ratio:
Option 1: CSS Aspect Ratio Container (Recommended)
<style>
.m3u8-player-container {
position: relative;
width: 100%;
padding-bottom: 56.25%; /* 16:9 ratio */
height: 0;
overflow: hidden;
border-radius: 12px;
}
.m3u8-player-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
}
</style>
<div class="m3u8-player-container">
<iframe
src="https://m3u8-player.cc/player.html?url=YOUR_M3U8_URL"
allowfullscreen
allow="autoplay; fullscreen; encrypted-media">
</iframe>
</div>
Option 2: Using aspect-ratio Property (Modern Browsers)
<style>
.m3u8-player-wrapper {
width: 100%;
aspect-ratio: 16 / 9;
border-radius: 12px;
overflow: hidden;
}
.m3u8-player-wrapper iframe {
width: 100%;
height: 100%;
border: none;
}
</style>
<div class="m3u8-player-wrapper">
<iframe
src="https://m3u8-player.cc/player.html?url=YOUR_M3U8_URL"
allowfullscreen
allow="autoplay; fullscreen; encrypted-media">
</iframe>
</div>
π‘ Why 56.25%? 56.25% is the mathematical result of the 16:9 aspect ratio (9 Γ· 16 = 0.5625). If your video is 4:3, use padding-bottom: 75%; for 21:9 widescreen movies, use padding-bottom: 42.86%.
URL Parameters: Customize Playback Behavior
By adding query parameters to the iframe URL, you can control the player's behavior:
| Parameter | Type | Description | Example |
|---|---|---|---|
url |
string (required) | M3U8 video stream URL, needs URL encoding | url=https%3A%2F%2Fexample.com%2Fstream.m3u8 |
autoplay |
boolean | Whether to autoplay. Note: modern browsers usually require mute for autoplay | autoplay=true |
muted |
boolean | Whether to mute by default. Recommended to enable with autoplay | muted=true |
controls |
boolean | Whether to show playback controls | controls=true |
poster |
string | Video cover image URL, displayed before loading | poster=https%3A%2F%2Fexample.com%2Fcover.jpg |
Full Parameter Example
<iframe
src="https://m3u8-player.cc/player.html?url=https%3A%2F%2Fexample.com%2Flive.m3u8&autoplay=true&muted=true&controls=true&poster=https%3A%2F%2Fexample.com%2Fthumb.jpg"
width="100%"
height="400"
frameborder="0"
allowfullscreen
allow="autoplay; fullscreen; encrypted-media">
</iframe>
β οΈ Autoplay Restrictions: Chrome, Safari, Edge, and other modern browsers have implemented strict autoplay policies: unless the user has interacted with the page, autoplay with sound is blocked. If you set autoplay=true, be sure to also set muted=true so the video can autoplay silently, and users can manually unmute afterward.
Platform-Specific Embed Guides
WordPress Websites
In the WordPress classic editor, switch to "Text/HTML" mode and paste the iframe code directly. If using the Gutenberg block editor, add a "Custom HTML" block and paste the code:
<!-- wp:html -->
<div style="position:relative;width:100%;padding-bottom:56.25%;height:0;overflow:hidden;border-radius:12px;">
<iframe
src="https://m3u8-player.cc/player.html?url=YOUR_M3U8_URL"
style="position:absolute;top:0;left:0;width:100%;height:100%;border:none;"
allowfullscreen
allow="autoplay; fullscreen; encrypted-media">
</iframe>
</div>
<!-- /wp:html -->
Discuz / Forum Posts
Most forums support direct HTML input. If the forum has HTML filtering enabled, contact the administrator to allow <iframe> tags, or use the forum's "Insert Media" feature.
Hexo / Hugo Static Blogs
Use HTML code directly in Markdown files (Markdown supports inline HTML):
## Live Stream Demo
<div style="position:relative;width:100%;padding-bottom:56.25%;height:0;overflow:hidden;">
<iframe
src="https://m3u8-player.cc/player.html?url=YOUR_M3U8_URL"
style="position:absolute;top:0;left:0;width:100%;height:100%;border:none;"
allowfullscreen>
</iframe>
</div>
Vue / React Projects
In a Vue single-file component, place the iframe code directly in the template:
<template>
<div class="video-wrapper">
<iframe
:src="playerUrl"
frameborder="0"
allowfullscreen
allow="autoplay; fullscreen; encrypted-media"
></iframe>
</div>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
streamUrl: String
})
const playerUrl = computed(() => {
const encoded = encodeURIComponent(props.streamUrl)
return `https://m3u8-player.cc/player.html?url=${encoded}&autoplay=true&muted=true`
})
</script>
<style scoped>
.video-wrapper {
position: relative;
width: 100%;
padding-bottom: 56.25%;
height: 0;
}
.video-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
border-radius: 12px;
}
</style>
CORS Cross-Origin Errors: Causes & 5 Solutions
The most common error after iframe embedding is the CORS (Cross-Origin Resource Sharing) error. The browser console will show something like:
Access to XMLHttpRequest at 'https://example.com/stream.m3u8'
from origin 'https://m3u8-player.cc' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Why Can VLC Play It But the Browser Can't?
This is the most critical distinction: VLC, PotPlayer, and other desktop players do not enforce browser CORS policies β they directly make network requests to fetch video data. The hls.js player in the browser uses XMLHttpRequest to fetch the M3U8 manifest and TS segments, and the browser enforces the Same-Origin Policy.
Therefore, a link that plays in VLC may not play in a web player.
Solution 1: Ask the Video Provider to Enable CORS (Most Recommended)
If you own or can contact the video stream server administrator, add the following response headers to the server configuration:
location ~* \.(m3u8|ts|key)$ {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, OPTIONS';
add_header Access-Control-Allow-Headers 'Origin, X-Requested-With, Content-Type, Accept';
}
<IfModule mod_headers.c>
<FilesMatch "\.(m3u8|ts|key)$">
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, OPTIONS"
</FilesMatch>
</IfModule>
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
<ExposeHeader>ETag</ExposeHeader>
<MaxAgeSeconds>3000</MaxAgeSeconds>
</CORSRule>
</CORSConfiguration>
π‘ Wildcard vs Credentials Conflict: If the player needs to send Cookies or authentication info (withCredentials: true), the server cannot use the wildcard *. You must explicitly specify the allowed origin domain, e.g., Access-Control-Allow-Origin: https://m3u8-player.cc.
Solution 2: Use a CORS Proxy Service (Temporary Testing Only)
If you just need temporary testing, you can use a public CORS proxy. But note: proxy services are not suitable for production because you cannot control their stability and security.
https://corsproxy.io/?https://example.com/stream.m3u8
Solution 3: Build Your Own Reverse Proxy (Production Recommended)
Configure a reverse proxy on your server to forward requests to the video source server, eliminating cross-origin issues:
location /proxy/ {
proxy_pass https://video-source-server.com/;
proxy_set_header Host video-source-server.com;
# Add CORS headers
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, OPTIONS';
# Handle preflight requests
if ($request_method = 'OPTIONS') {
return 204;
}
}
Solution 4: Check Mixed Content (HTTP vs HTTPS)
Even with correct CORS configuration, if the video source is http:// and your website is https://, the browser will silently block loading. The console may not show a CORS error, only a network request failure.
The only solution: ensure the video source uses HTTPS. If the source server does not support HTTPS, no browser-based player can play it.
Solution 5: CDN Cache Causing CORS Header Loss
If you use CloudFront, Alibaba Cloud CDN, or other acceleration services, you may encounter a situation where "it worked yesterday but errors today." This is because CDN nodes have cached the old response headers.
Resolution steps:
- In CDN configuration, ensure "origin pull" forwards the
Originrequest header - Clear CDN cache (Purge / refresh cache)
- In CDN behavior settings, add CORS-related response headers to the whitelist for forwarding
π Diagnostic Checklist: When encountering playback failure, troubleshoot in this order:
- In browser DevTools (F12) β Network tab, check if the M3U8 request response headers contain
Access-Control-Allow-Origin - Confirm the video source URL uses the HTTPS protocol
- Check TS segment requests (not only the M3U8 file needs CORS, all .ts files also need it)
- Test in Incognito/Private mode to rule out browser cache interference
- Use curl command to test:
curl -I https://your-stream.m3u8and check response headers
Advanced Techniques: Autoplay, Mute & Event Listening
Autoplay Best Practices
Modern browser autoplay policies are becoming increasingly strict. Here is a summary of autoplay rules across browsers:
| Browser | Autoplay Conditions | Muted Autoplay |
|---|---|---|
| Chrome | User has interacted with the site (click, scroll, etc.) or has high media engagement score | Allowed |
| Safari | Only muted autoplay allowed, requires playsinline attribute |
Allowed |
| Firefox | Blocks all autoplay unless user explicitly allows | Allowed (requires user setting) |
| Edge | Same as Chrome (Chromium-based) | Allowed |
Therefore, if you want the video to start playing automatically after loading, use this configuration:
<iframe
src="https://m3u8-player.cc/player.html?url=YOUR_URL&autoplay=true&muted=true"
allow="autoplay; fullscreen; encrypted-media"
allowfullscreen>
</iframe>
Communicating with the Player via postMessage
If you need finer control (e.g., listening to playback status, getting current time), you can use the HTML5 postMessage API to communicate with the player inside the iframe:
const iframe = document.querySelector('iframe');
const playerWindow = iframe.contentWindow;
// Send play command
playerWindow.postMessage({ action: 'play' }, 'https://m3u8-player.cc');
// Send pause command
playerWindow.postMessage({ action: 'pause' }, 'https://m3u8-player.cc');
// Listen for player events
window.addEventListener('message', (event) => {
if (event.origin !== 'https://m3u8-player.cc') return;
console.log('Player status:', event.data);
// event.data may contain: { type: 'ready' | 'playing' | 'paused' | 'ended' | 'error', ... }
});
π‘ Use Cases: postMessage communication is suitable for: custom play/pause buttons, syncing multiple players, auto-advancing to the next episode when video ends, syncing playback progress to the server for watch history, and other advanced features.
Frequently Asked Questions
Q1: The embedded player shows a black screen with no error message?
The most likely cause is mixed content blocking. Check if the video source URL is HTTPS. If it's HTTP, switch to an HTTPS address or ask the video provider to enable SSL.
Q2: Why doesn't autoplay work even with autoplay=true?
Please also set muted=true. Modern browsers require videos to be muted by default for autoplay. Users can manually unmute via the player controls.
Q3: Can I embed this in a WeChat Official Account article?
WeChat Official Account articles do not support custom iframe code. We recommend converting the video link to a QR code or short link, guiding users to click and jump to the player page.
Q4: Will iframe embedding affect my website's SEO?
No. iframe content is not considered part of your page by search engines, so it won't pass negative SEO impact. However, the video content inside the iframe also won't directly boost your page's search ranking. We recommend adding relevant text descriptions on your page alongside the iframe.
Q5: What video formats does the player support?
M3U8Player primarily supports the HLS (HTTP Live Streaming) protocol, i.e., .m3u8 playlist format. For direct video files like MP4 and WebM, we recommend using the native HTML5 <video> tag.
Q6: Does the embedded player have a fullscreen button on mobile?
Yes. As long as the iframe tag includes the allowfullscreen attribute, mobile users can tap the fullscreen button to enter fullscreen mode. iOS Safari also supports system-level fullscreen gestures.
π Try iframe Embedding Now
Visit the M3U8Player online player to get your custom embed code, with live preview and one-click copy.
Go to Online Player βRelated Articles: