首页 > 解决方案 > 如何将流分成可以使用 Media Source API 播放的块?

问题描述

我能够生成使用 MediaRecorder API 记录的数据块。使用 MediaSource API 存储和播放它们。如果我以正确的顺序将所有块附加到 sourceBuffer,这可以正常工作。

async function recordScreen() {
  recordedChunks = []
  stream = await navigator.mediaDevices.getDisplayMedia(getDisplayMediaOptions)
  mediaRecorder = new MediaRecorder(stream)

  mediaRecorder.ondataavailable = event => {
    if (event.data.size > 0) {
      recordedChunks.push(event.data)
    }
  }
  const interval = setInterval(() => {
    if (isRecording) {
      mediaRecorder.requestData()
    } else {
      clearInterval(interval)
    }
  }, 1000)
  mediaRecorder.start()
  isRecording = true
}

function replay(chunks) {
  const mediaSource = new MediaSource()
  video.src = URL.createObjectURL(mediaSource)

  mediaSource.addEventListener('sourceopen', () => {
    const sourceBuffer = mediaSource.addSourceBuffer()
    const appendChunk = chunk => chunk.arrayBuffer().then(data => sourceBuffer.appendBuffer(data))
    sourceBuffer.addEventListener('updateend', () => {
      if (chunks[i]) {
        appendChunk(chunks[i++])
      } else {
        mediaSource.endOfStream()
      }
    })
    appendChunk(chunks[i++])
  })
}

js文件

但是,当我尝试不附加所有块时,问题就开始了。

我知道录制的媒体不仅包含原始视频数据,还包含某种标题信息。但在这一点上,我没有计划我在做什么。也许你们可以帮助我:

我的目标是抓取任何记录的块,然后播放其中的视频数据。如果不知何故缺少一个块,它应该继续播放以下块。

背景

我正在尝试开发一个与 webRTC 一起使用 p2p 的实时流媒体解决方案。我知道我可以将流直接放入 RtcConnection 中。但据我所知,这意味着每个对等点只能与另一个对等点共享一个完整的流。如果每个对等方能够更灵活地为直播流做出贡献,例如共享 1.5 个流,那就太好了。所以我认为通过 RtcDataChannels 共享这些数据是有意义的,收集它们并通过 MediaSource API 播放它。如果你们对如何做到这一点有任何其他想法,我将不胜感激。

标签: javascriptwebrtcmedia-sourceweb-mediarecorder

解决方案


但是,当我尝试不附加所有块时,问题就开始了。

你不能那样做™。

这些 MediaRecorder 流以一堆头信息开始,这些信息是在 MediaSource 中启动解码所必需的。他们不会重复这些信息。

而且,该标头信息与传递给ondataavailable. 叹。

更重要的是,压缩视频(您从 getDisplayMedia / MediaRecorder 获得的内容)由关键帧和帧间组成。没有关键帧,帧间没有意义。

有可能解析出流以捕获标头信息。在Matroska中,它是EMBL head元素和Segment序幕。然后,您也许可以仅将其发送到 MediaSource,然后是最新的Cluster元素。但我不知道有谁这样做过。

而且,如果您尝试进行多对多会话(所谓的“群”),您的客户端将需要将所有数据发送给其他所有客户端。这让带宽很快变得令人望而却步。

mediasoup和其他所谓的选择性转发单元为此提供了面向服务器的 WebRTC 解决方案。WebRTC 包含各种让流数据源刷新的东西——按需发送关键帧。


推荐阅读