Skip to content

H5 getBackgroundAudioManager 每次调用创建新实例,导致多音频并发播放 #18568

@mefengl

Description

@mefengl

请先确认

  • 我已搜索并确定这个提交不是重复的

Taro 版本

4.1.7

相关领域

媒体 API

使用框架

React

相关平台

  • 所有平台
  • Web 端(H5)
  • 移动端(React-Native)
  • 鸿蒙(Harmony)
  • 鸿蒙容器(Harmony Hybrid)
  • ASCF 元服务
  • 快应用(QuickApp)
  • 所有小程序
  • 微信小程序
  • 企业微信小程序
  • 京东小程序
  • 百度小程序
  • 支付宝小程序
  • 支付宝 IOT 小程序
  • 头条小程序
  • QQ 小程序
  • 钉钉小程序
  • 飞书小程序
  • 快手小程序

小程序基础库版本

No response

问题描述

H5 端 Taro.getBackgroundAudioManager() 每次调用都创建新实例,导致多个音频同时播放。

当前实现问题:

源码位置:packages/taro-h5/src/api/media/background-audio/index.ts

/**
 * 获取全局唯一的背景音频管理器
 */
export const getBackgroundAudioManager = () => new BackgroundAudioManager()

注释说"获取全局唯一",但实际每次调用 new BackgroundAudioManager(),每个实例内部创建独立的 HTMLAudioElement(见 BackgroundAudioManager.ts:13

问题表现:

  1. 在不同页面/组件调用 Taro.getBackgroundAudioManager() 会创建多个管理器实例
  2. 每个实例有独立的 <audio> 元素
  3. 导致多个音频同时播放(例如:切换页面后两首歌同时响)
  4. 与微信小程序行为不一致(小程序是真单例)

复现场景:

// 页面 A
const audioManager1 = Taro.getBackgroundAudioManager()
audioManager1.src = 'audio1.mp3'
audioManager1.play()

// 跳转到页面 B
const audioManager2 = Taro.getBackgroundAudioManager()
audioManager2.src = 'audio2.mp3'
audioManager2.play()

// 结果:audio1 和 audio2 同时播放 ❌
// 预期:audio2 播放,audio1 自动停止 ✅

复现链接

https://github.com/NervJS/taro/blob/main/packages/taro-h5/src/api/media/background-audio/index.ts#L17

复现步骤

  1. 创建 Taro H5 项目
  2. 在页面 A 调用 Taro.getBackgroundAudioManager() 播放音频
  3. 跳转到页面 B,再次调用 Taro.getBackgroundAudioManager() 播放另一首音频
  4. 观察:两个音频同时播放

环境信息

Taro CLI 4.1.7 environment info:
  System:
    OS: macOS 15
    Shell: zsh
  Binaries:
    Node: 22.x
    npm: 10.x
  npmPackages:
    @tarojs/cli: 4.1.7 => 4.1.7
    @tarojs/components: 4.1.7 => 4.1.7
    @tarojs/plugin-platform-h5: 4.1.7 => 4.1.7
    @tarojs/react: 4.1.7 => 4.1.7
    @tarojs/taro: 4.1.7 => 4.1.7
    react: ^18.0.0 => 18.3.1

建议修复方案

let _instance: BackgroundAudioManager | null = null

/**
 * 获取全局唯一的背景音频管理器
 */
export const getBackgroundAudioManager = () => {
  if (!_instance) _instance = new BackgroundAudioManager()
  return _instance
}

影响范围:

  • ✅ 修复 H5 多音频并发问题
  • ✅ 与小程序行为对齐
  • ✅ 无破坏性变更(现有代码无需修改)
  • ✅ 最小改动(3 行代码)

开源贡献

补充说明:

我已经在本地验证了这个修复方案,并准备了 PR

Metadata

Metadata

Assignees

No one assigned

    Labels

    F-reactFramework - ReactT-h5Target - 编译到 H5

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions