🎬 移动端音视频处理
移动端的音视频播放受平台策略限制较大,尤其是自动播放和全屏控制,需要特殊处理。
自动播放策略
| 平台 | 策略 | 限制条件 |
|---|---|---|
| iOS Safari | 严格禁止自动播放(含声音) | 必须由用户手势触发(click/touchend),且在同一事件循环内 |
| Android Chrome | 部分允许 | 静音视频可自动播放;有声需用户有过交互(MEI 指数) |
| 微信内置浏览器 | 严格禁止 | 需通过 WeixinJSBridge 的 WeixinJSBridgeReady 事件触发,或用户手势 |
| WebView(App 内) | 由原生配置决定 | iOS: mediaPlaybackRequiresUserAction=NO;Android: setMediaPlaybackRequiresUserGesture(false) |
自动播放兼容方案
// ===== 移动端视频自动播放兼容方案 =====
async function autoPlayVideo(videoEl) {
// ① 先尝试静音自动播放
videoEl.muted = true;
videoEl.playsInline = true; // iOS 内联播放(不全屏)
try {
await videoEl.play();
console.log('静音自动播放成功');
// 用户交互后取消静音
document.addEventListener('touchend', () => {
videoEl.muted = false;
}, { once: true });
} catch (err) {
console.log('自动播放被阻止:', err.message);
// ② 降级:等待用户首次交互
document.addEventListener('touchend', () => {
videoEl.play();
}, { once: true });
}
}
// ③ 微信环境特殊处理
function autoPlayInWeChat(videoEl) {
if (typeof WeixinJSBridge !== 'undefined') {
WeixinJSBridge.invoke('getNetworkType', {}, () => {
videoEl.play();
});
} else {
document.addEventListener('WeixinJSBridgeReady', () => {
videoEl.play();
}, false);
}
}
Video 标签关键属性
| 属性 | 作用 | 移动端注意事项 |
|---|---|---|
playsinline |
内联播放,不自动全屏 | iOS 必须加,否则强制全屏;Android 默认内联 |
webkit-playsinline |
iOS 8-9 兼容写法 | 与 playsinline 同时使用 |
x5-video-player-type="h5" |
腾讯 X5 内核同层播放 | Android 微信/QQ 浏览器需要,否则弹出独立播放器 |
x5-video-player-fullscreen="true" |
X5 内核全屏模式 | 横屏视频需要设置为 true |
x5-video-orientation |
X5 播放器方向 | landscape 横屏 / portrait 竖屏 |
preload="metadata" |
预加载策略 | 移动端建议 metadata,auto 浪费流量 |
poster |
封面图 | 必须设置,部分 Android 不设置会显示黑屏 |
controls |
显示原生控件 | 各平台样式不统一,建议自定义控件 |
完整 Video 标签模板
<!-- ===== 移动端 Video 完整写法 ===== -->
<video
src="video.mp4"
poster="cover.jpg"
controls
playsinline
webkit-playsinline
x5-video-player-type="h5"
x5-video-player-fullscreen="true"
x5-video-orientation="landscape"
preload="metadata"
loop
style="width:100%; object-fit:contain;"
>
您的浏览器不支持 video 标签
</video>
移动端视频常见坑与解决
| 问题 | 原因 | 解决方案 |
|---|---|---|
| iOS 点击播放自动全屏 | 未设置 playsinline |
添加 playsinline 属性 |
| 微信/QQ 弹出独立播放器 | 未设置 X5 同层播放 | 添加 x5-video-player-type="h5" |
| Android 视频层级覆盖其他元素 | X5 视频默认在最顶层 | 设置 x5-video-player-type="h5-page" |
| 视频无法自动播放 | 浏览器策略限制 | 先静音播放,用户交互后取消静音 |
| 封面图不显示 | 部分 Android 的 bug | 在 video 上层叠加 cover div,播放后隐藏 |
| iOS Safari 视频内联但占满屏幕 | CSS 宽高未生效 | 给 video 设置明确的 width/height 或 aspect-ratio |
Audio 音频处理
// ===== 移动端音频播放 =====
// ① 预加载音频池(解决播放延迟)
const audioPool = {};
function preloadAudio(name, src) {
const audio = new Audio();
audio.src = src;
audio.preload = 'auto';
audio.load();
audioPool[name] = audio;
}
// ② 播放音效(短音频)
function playSound(name) {
const audio = audioPool[name];
if (audio) {
audio.currentTime = 0; // 重置到开头
audio.play().catch(() => {}); // 忽略自动播放限制(静默失败)
}
}
// ③ 微信环境音频自动播放
document.addEventListener('WeixinJSBridgeReady', () => {
// 预加载背景音乐
const bgm = new Audio('bgm.mp3');
bgm.loop = true;
bgm.play();
});
// ④ 音频上下文恢复(iOS)
// iOS Safari 在页面不可见时会暂停 Web Audio API
document.addEventListener('visibilitychange', () => {
if (!document.hidden && audioContext?.state === 'suspended') {
audioContext.resume();
}
});
⚠️ 音视频最佳实践要点
- 封面图必设:poster 属性必须有,部分 Android 无封面会黑屏或显示异常
- 格式选择:视频优先 MP4 (H.264),兼容性最好;音频优先 MP3/AAC
- 清晰度适配:根据网络类型(4G/WiFi)动态切换清晰度,节省流量
- 预加载控制:移动端不要设置
preload="auto",浪费用户流量 - 播放状态管理:页面隐藏时暂停播放,页面恢复时检查是否需要恢复
- 进度保存:使用 localStorage 保存播放进度,用户体验更好