不能直接识别横竖屏状态。<source> 的 media 属性仅在 DOM 插入时静态求值一次,不监听屏幕旋转,且浏览器对 orientation 支持不一致,导致切换失效;可靠方案需用 JavaScript 结合 matchMedia 与手动 load 控制。

source 的 media 属性能识别横竖屏吗?
不能直接识别“横屏”或“竖屏”状态。HTML 的 <source> 标签中 media 属性只支持 CSS 媒体查询语法,而原生媒体特性里没有 orientation: landscape 或 orientation: portrait 这类实时响应式切换能力——它只在元素插入 DOM 时求值一次,且不监听屏幕旋转事件。
也就是说,media="(orientation: landscape)" 看起来合理,但实际行为取决于浏览器加载策略:多数浏览器会在初始渲染时判断并选择匹配的 <source>,之后旋转屏幕不会触发重新选择或切换视频源。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
为什么用 media="(orientation: ...)" 加载不同视频经常失效?
常见错误现象包括:竖屏打开页面却加载了横屏视频、旋转后画面卡顿或黑屏、iOS Safari 完全忽略 orientation 切换。
-
orientation 是一个“连续性媒体特性”,但 <source> 不具备动态重评估机制;<video> 元素一旦选定 source 就不会自动切换
- 部分安卓 WebView 和旧版 Chrome 对
orientation 支持不一致,甚至返回错误初始值(比如始终报 portrait)
- iOS Safari 在
autoplay 场景下可能跳过 media 匹配逻辑,直接使用第一个 <source>
- 即使匹配成功,横竖屏视频宽高比差异若未配合
object-fit 或 CSS 重设,也会导致拉伸或裁切
真正可靠的横竖屏视频加载方案
放弃依赖 <source media="..."> 自动切换,改用 JavaScript 主动控制:
- 用
window.matchMedia("(orientation: landscape)") 监听变化,手动调用 video.src = "..." 并触发 load()
- 确保新视频 URL 携带不同分辨率/编码参数(如横屏用
1920x1080,竖屏用 1080x1920),避免浏览器缓存复用旧资源
- 添加
preload="none" 防止多个 source 提前下载,节省流量
- 在
resize + orientationchange 双事件中判断,尤其 iOS 需要 orientationchange(resize 在 Safari 中延迟明显)
<video id="myVideo" preload="none">
<source data-portrait="video/portrait.mp4">
<source data-landscape="video/landscape.mp4">
</video>
<script>
const video = document.getElementById("myVideo");
const updateSource = () => {
const isLandscape = window.matchMedia("(orientation: landscape)").matches;
const src = isLandscape
? video.querySelector('source[data-landscape]').dataset.landscape
: video.querySelector('source[data-portrait]').dataset.portrait;
if (video.src !== src) {
video.src = src;
video.load(); // 必须显式调用
}
};
window.addEventListener("orientationchange", updateSource);
window.addEventListener("resize", () => setTimeout(updateSource, 100)); // 防抖
</script>
横竖屏视频的实际兼容性陷阱
真正的麻烦不在写法,而在内容适配本身:
- 同一视频文件无法同时满足横竖屏最佳播放体验——横屏需要宽幅构图,竖屏需要主体居中+上下留黑或动态裁切,最好由服务端提供两套独立编码
- H.264 编码的竖屏 MP4 文件,某些安卓机型会错误解析旋转元数据,导致画面逆时针转 90°,需用
transform: rotate(90deg) 补偿(但会影响 controls 位置)
- WebP/WebM 不支持 orientation 元数据,MP4 才有
com.apple.quicktime.rotation,但浏览器读取行为不统一
- 如果走 MSE(Media Source Extensions)方案,必须按 orientation 分别初始化
MediaSource,不能复用同一个实例
横竖屏视频加载不是个“加个 media 属性就能好”的问题,关键在何时加载、如何替换、以及视频本身是否真的为两种方向做了优化——属性只是入口,背后全是播放器逻辑和内容管线的事。
orientation 是一个“连续性媒体特性”,但 <source> 不具备动态重评估机制;<video> 元素一旦选定 source 就不会自动切换orientation 支持不一致,甚至返回错误初始值(比如始终报 portrait)autoplay 场景下可能跳过 media 匹配逻辑,直接使用第一个 <source>
object-fit 或 CSS 重设,也会导致拉伸或裁切<source media="..."> 自动切换,改用 JavaScript 主动控制:
- 用
window.matchMedia("(orientation: landscape)")监听变化,手动调用video.src = "..."并触发load() - 确保新视频 URL 携带不同分辨率/编码参数(如横屏用
1920x1080,竖屏用1080x1920),避免浏览器缓存复用旧资源 - 添加
preload="none"防止多个 source 提前下载,节省流量 - 在
resize+orientationchange双事件中判断,尤其 iOS 需要orientationchange(resize在 Safari 中延迟明显)
<video id="myVideo" preload="none">
<source data-portrait="video/portrait.mp4">
<source data-landscape="video/landscape.mp4">
</video>
<script>
const video = document.getElementById("myVideo");
const updateSource = () => {
const isLandscape = window.matchMedia("(orientation: landscape)").matches;
const src = isLandscape
? video.querySelector('source[data-landscape]').dataset.landscape
: video.querySelector('source[data-portrait]').dataset.portrait;
if (video.src !== src) {
video.src = src;
video.load(); // 必须显式调用
}
};
window.addEventListener("orientationchange", updateSource);
window.addEventListener("resize", () => setTimeout(updateSource, 100)); // 防抖
</script>
横竖屏视频的实际兼容性陷阱
真正的麻烦不在写法,而在内容适配本身:
- 同一视频文件无法同时满足横竖屏最佳播放体验——横屏需要宽幅构图,竖屏需要主体居中+上下留黑或动态裁切,最好由服务端提供两套独立编码
- H.264 编码的竖屏 MP4 文件,某些安卓机型会错误解析旋转元数据,导致画面逆时针转 90°,需用
transform: rotate(90deg) 补偿(但会影响 controls 位置)
- WebP/WebM 不支持 orientation 元数据,MP4 才有
com.apple.quicktime.rotation,但浏览器读取行为不统一
- 如果走 MSE(Media Source Extensions)方案,必须按 orientation 分别初始化
MediaSource,不能复用同一个实例
横竖屏视频加载不是个“加个 media 属性就能好”的问题,关键在何时加载、如何替换、以及视频本身是否真的为两种方向做了优化——属性只是入口,背后全是播放器逻辑和内容管线的事。
transform: rotate(90deg) 补偿(但会影响 controls 位置)com.apple.quicktime.rotation,但浏览器读取行为不统一MediaSource,不能复用同一个实例


















