🎬 移动端音视频处理

移动端的音视频播放受平台策略限制较大,尤其是自动播放全屏控制,需要特殊处理。

自动播放策略

平台策略限制条件
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" 预加载策略 移动端建议 metadataauto 浪费流量
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 保存播放进度,用户体验更好