一、混合内容带来播放黑屏的业务现象
现在绝大多数业务网站都升级为 HTTPS 安全页面。很多同学会遇到一个很迷惑故障:网页本身是 HTTPS,M3U8 播放地址打开黑屏,但是复制 M3U8 链接新开标签页播放却完全正常。
这个问题很多新手不了解,它来自浏览器的 Mixed‑Content 混合内容安全策略。简单解释:HTTPS 安全页面里面,浏览器默认会拦截页面内部发起的 HTTP 非安全资源请求。
这里特别容易踩坑:M3U8 主索引地址改成了 HTTPS,但是 M3U8 内部分片、密钥地址写死 HTTP 绝对链接。从外部看播放地址是 HTTPS,但是分片请求依旧是 HTTP,被浏览器安全策略拦截,直接黑屏。
很多人排查的时候,只看浏览器地址栏的 M3U8 链接,忽略 M3U8 文本内部写死的子资源地址。curl 命令测试全部 200,但是浏览器页面内无法播放。遇到混合内容相关的播放故障,我会使用 m3u8live.cn,查看完整 M3U8 原始文本,核对内部分片、密钥使用的协议。
二、混合内容常见故障场景
场景 1:M3U8 主地址改为 HTTPS,分片写死 HTTP 绝对 URL
对外暴露的播放链接改成 HTTPS,但是 M3U8 清单内部 TS 分片是写死的 http 开头绝对地址。页面内加载时,分片请求属于混合不安全内容,浏览器拦截分片,页面黑屏。新开标签直接访问 M3U8 不受页面上下文限制,播放正常。
场景 2:AES‑128 加密流密钥地址使用 HTTP 协议
M3U8、TS 分片全部是 HTTPS,唯独 #EXT‑X‑KEY 密钥地址是 HTTP。密钥请求被浏览器拦截,拿不到密钥,解密失败黑屏。
场景 3:Master 多码率索引,子流写死 HTTP 协议
默认清晰度子流是 HTTPS,其他档位子 M3U8 写死 HTTP。默认码率播放正常,切换其他清晰度直接黑屏。
场景 4:Nginx 代理转发,内部生成 M3U8 错误输出 HTTP 协议
代理网关对外是 HTTPS,后端切片服务生成 M3U8 的时候,内部拼接地址错误输出 http,造成混合内容。
三、容易混淆的误区
❌误区:只要我给用户的播放链接是 HTTPS,所有资源就都是 HTTPS。
外部链接只是入口,M3U8 文本内部写死的子资源地址才是浏览器真实请求地址。
✅正确:优先业务后端切片输出相对路径,不写死 http/https 域名,浏览器会继承页面访问协议,自动适配 HTTPS 环境。
四、排查实操步骤
第一步,待测 M3U8 粘贴网页调试工具,查看原始 M3U8 文本,检查 TS 分片、密钥、子流地址协议头。 第二步,看浏览器控制台警告,混合内容拦截浏览器会打印明确安全警告。 第三步,新开独立浏览器标签访问同一个 M3U8,如果新开标签播放正常,嵌入 HTTPS 业务页面就黑屏,高度怀疑混合内容问题。
五、业务开发运维建议
- HTTPS 业务环境,切片服务尽量输出相对路径,不要写死 http 绝对 URL,自动继承页面协议。
- 如果业务必须使用绝对 URL,全部统一输出 https 协议,分片、密钥、多码率子流全部统一。
- Nginx 反向代理场景,要识别前端请求协议,生成 M3U8 的时候不能硬编码 http。
- 测试不能只新开标签页测试 M3U8,务必嵌入真实 HTTPS 业务页面做完整冒烟。
六、总结
Mixed‑Content 混合内容是 HTTPS 网站播放 M3U8 的隐形坑。外部播放链接为 HTTPS,不代表 M3U8 内部的分片、密钥也是 HTTPS。写死 HTTP 绝对地址会被浏览器安全策略拦截,表现为嵌入页面黑屏,新开标签播放正常。优先后端输出相对路径,避免硬编码 http 域名。借助网页调试工具查看 M3U8 原始文本,检查所有子资源协议,快速定位混合内容故障。