轶哥博客

妄图改变世界的全栈程序员。

MediaDevices设置音频输出设备

MediaDevices 为浏览器控制音频输入设备、音频输出设备、视频输入设备提供了接口。

简单检测浏览器对MediaDevicesAPI的支持情况:

  checkMediaDevicesSupport () {
    if (!navigator) {
      throw new Error('navigator not supported.')
    }

    if (!navigator.mediaDevices) {
      throw new Error('mediaDevices not supported.')
    }

    if (!navigator.mediaDevices.enumerateDevices) {
      throw new Error('mediaDevices.enumerateDevices() not supported.')
    }
    return true
  }

获取设备列表:

  async getDeviceList () {
    await navigator.mediaDevices.getUserMedia({
      video: true,
      audio: true
    })

    this.deviceList = await navigator.mediaDevices.enumerateDevices()

    return this.deviceList
  }

设置音频输出设备(来源):

  setOutAudioDevices (element, sinkId) {
    return new Promise((resolve, reject) => {
      if (typeof element.sinkId !== 'undefined') {
        element.setSinkId(sinkId)
          .then(() => {
            console.log(`Success, audio output device attached: ${sinkId} to element with ${element.title} as source.`)
            resolve(true)
          })
          .catch(error => {
            let errorMessage = error
            if (error.name === 'SecurityError') {
              errorMessage = `You need to use HTTPS for selecting audio output device: ${error}`
            }
            console.error(errorMessage)
            reject(errorMessage)
          })
      } else {
        console.warn('Browser does not support output device selection.')
      }
    })
  }

大坑提示:

const audio = document.createElement('audio') // 不能用 new Audio(res.url),否则无法设置输出信号,最好不要使用 createElement
audio.src = res.url

audio.load()

if (deviceId) {
  await jsMediaDevices.setOutAudioDevices(audio, deviceId)
}

audio.play()

设置输出设备不能用Audio对象,并且不能在audio.load()之前调用setOutAudioDevices

最好不要使用createElement,应该直接写到HTML中,否则部分浏览器将会出现此报错信息:DOMException: play() failed because the user didn't interact with the document first.,在Chrome 50+版本中,JavaScript启动的播放发生之前都需要明确的用户操作。这有助于确保用户不会在没有明确地与页面交互的情况下开始下载和播放媒体。因此videoaudio标签需要播放前事先加载到HTML。

Uncaught (in promise) DOMException: Failed to load because no supported source was found.:报错通常与音频源有关(src里面的地址),可能是音频大小为0,也可能是发生了跨域。


更多示例代码:https://webrtc.github.io/samples/

对MediaDevices接口的简单封装:https://github.com/yi-ge/js-media-devices

  上一篇 (Node.js打印PDF文件)
下一篇 (JS推测Base64图片类型)