微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将流划分为可以使用 Media Source API 播放的块?

如何解决如何将流划分为可以使用 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++])
  })
}

jsfidle

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

  • 如何跳过录制视频的开头?
  • 如果丢失了一个块,在新的块到达之前视频是不是可能会一片空白?

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

  • 如何检查这些标头信息(非视频数据)?
  • 我可以编辑或添加它们吗?有没有关于如何做到这一点的好资源?

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

背景

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

解决方法

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

你不能那样做™。

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

而且,头信息与传递给 ondataavailable 的块没有很好地对齐。叹气。

此外,压缩视频(您从 getDisplayMedia / MediaRecorder 获得的)由关键帧和帧间组成。没有关键帧,帧间就毫无意义。

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。