You need to enable JavaScript to run this app. 添加音轨到录屏流后MediaRecorder录制的webm文件损坏
优惠活动
大模型
产品
解决方案
定价
更多

添加音轨到录屏流后MediaRecorder录制的webm文件损坏

录屏录制文件损坏问题说明

问题背景

  • 已完成屏幕共享流的录制功能,实现逻辑为录制流分片上传至服务端、服务端拼接存储为webm/mp4格式文件
  • 为录屏流追加额外媒体轨时先后尝试两种实现方案:
    • 调用addTracks方法为现有录屏流追加本地采集的音频轨
    • 新建独立MediaStream实例,整合录屏流的视频轨与本地采集的音频轨
  • 两种方案最终均触发录制文件损坏的问题,和之前单录屏无音频时的问题表现一致

补充参考:MediaRecorder API 的详细说明可通过 MDN 公开文档获取
补充约束:若建议改用WebRTC实现,需要同步解决此前场景下WebRTC录制文件损坏的问题

现有实现代码

客户端代码

startMedia = () => {
  this.setState({ mediaState: "pending" })
  navigator.mediaDevices.getDisplayMedia({ video: true }).then(async (screenSharingStream) => {
    console.log(MediaRecorder.isTypeSupported('video/webm; codecs=vp8,opus'))
    const socketIO = io.connect(baseURL, {
      query: {
        candidateID: this.candidateID,
        roundTest: this.roundTest
      }
    })
    const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true }).catch(e => { throw e });
    const mediaRecorderOptions = {
      videoBitsPerSecond: 128000,
      audioBitsPerSecond: 128000,
      mimeType: 'video/webm; codecs=vp8,opus'
    }

    const [videoTrack] = screenSharingStream.getVideoTracks();
    const [audioTrack] = mediaStream.getAudioTracks();
    if (audioTrack && videoTrack)
      videoTrack.addTrack(audioTrack)

    const stream = new MediaStream([videoTrack, audioTrack]);
    this.socketRef.current = socketIO;
    this.mediaStream = mediaStream

    this.screenSharingStream = stream
    this.candidateVideoRef.current.srcObject = this.mediaStream;
    this.mediaRecorder = new MediaRecorder(this.screenSharingStream, mediaRecorderOptions)
    this.mediaRecorder.ondataavailable = function (event) {
      if (event && event.data.size > 0) {
        const reader = new FileReader();
        reader.onload = function () {
          const dataURL = reader.result;
          console.log('van chay')
          const base64EncodedData = dataURL.split(',')[1];
          socketIO.emit('SEND BLOB', base64EncodedData)
        }
        reader.readAsDataURL(event.data)
      }
    }
    this.mediaRecorder.start(1000)
    this.setState({ mediaState: this.mediaRecorder.state })
  }).catch(err => {
    console.log(err.name)
    switch (err.name) {
      case 'NotAllowedError':
        message.error('候选人端未授权录屏权限')
        this.setState({ mediaState: "Aborting" })
        break;
      default:
        message.error('系统异常,请联系管理员')
        this.setState({ mediaState: "Aborting" })
        break;
    }
  })
}
stopMedia = () => {
  if (this.mediaStream) {
    this.mediaStream.getTracks().forEach((track) => {
      if (track.readyState === 'live') {
        track.stop()
        this.candidateVideoRef.current.style.display = 'none';
      }
    })
  }
  if (this.screenSharingStream) {
    this.mediaRecorder.stop()
    this.setState({ mediaState: this.mediaRecorder.state })
  }
}

服务端代码

socket.on("SEND BLOB", chunk => {
  try {
    const fileExtension = '.webm'
    const dataBuffer = new Buffer(chunk, 'base64');
    const fileStream = fs.createWriteStream(
      path.join(__dirname, './videos/candidate/', candidateID + '-' + roundTest + fileExtension),
      { flags: 'a' }
    );
    fileStream.write(dataBuffer);
  } catch (e) {
    console.log(e)
  }
})

内容的提问来源于stack exchange,提问作者KelNguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 13:36:10