You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于HLS/MPEG-DASH实现类Loom的浏览器长时录屏功能

实现类Loom的长时长浏览器/Chrome扩展录屏方案

一、核心思路(针对5小时+录制需求)

长时长录制绝对不能把整个视频存在浏览器内存里,直接会崩,所以必须走分片录制+边录边传的路子——和你推测的Loom逻辑一致:

  • 用浏览器的MediaRecorder API按固定时长(比如10-30秒)切割视频片段,每生成一个分片就立刻上传到服务器,彻底避免内存溢出;
  • 关于HLS/DASH:如果选HLS,服务器端要把上传的分片转成.ts格式并生成.m3u8索引文件;如果是DASH(对应你问的MPD文件),MPD的生成更适合放在服务器端做,浏览器JS基本不直接生成MPD,因为它要处理分片时长、码率、时序这些复杂元数据,服务器用工具生成更靠谱。

二、浏览器端录屏核心代码示例

1. 获取屏幕+音频流

先把屏幕流和麦克风流合并(如果需要录声音):

async function getCombinedStream() {
  const screenStream = await navigator.mediaDevices.getDisplayMedia({ 
    video: { displaySurface: 'monitor' }, 
    audio: true 
  });
  const micStream = await navigator.mediaDevices.getUserMedia({ audio: true });
  // 合并音视频轨道
  return new MediaStream([
    ...screenStream.getVideoTracks(),
    ...micStream.getAudioTracks()
  ]);
}

2. 分片录制

配置timeslice参数指定分片间隔,每到时间就触发分片生成:

const stream = await getCombinedStream();
// 用VP9编码,比H.264省一半空间,适合长录制
const recorder = new MediaRecorder(stream, { mimeType: 'video/webm; codecs=vp9' });
const recordingId = self.crypto.randomUUID(); // 生成唯一标识,区分不同录制任务

recorder.ondataavailable = (e) => {
  if (e.data.size === 0) return;
  // 立刻上传分片,带上录制ID和时间戳作为分片标识
  uploadChunk(e.data, recordingId, Date.now());
};

// 每30秒生成一个分片
recorder.start(30000);

3. 分片上传

用FormData把分片传给服务器,注意带上唯一录制ID,方便服务器后续拼接:

async function uploadChunk(chunk, recordingId, timestamp) {
  const formData = new FormData();
  formData.append('chunk', chunk, `${recordingId}_${timestamp}.webm`);
  formData.append('recordingId', recordingId);

  try {
    await fetch('/your-upload-endpoint', {
      method: 'POST',
      body: formData
    });
  } catch (err) {
    // 上传失败存到本地,后续重试
    localStorage.setItem(`failed-chunk-${recordingId}_${timestamp}`, chunk);
  }
}

三、Loom的实际实现逻辑(基于反向工程分析)

Loom确实是客户端分片录制+实时上传的路子,还加了这些优化:

  • 客户端会对分片做轻量编码优化,优先用VP8/VP9减少体积;
  • 服务器接收分片后,会后台完成转码、合并,生成HLS的.m3u8或DASH的.mpd索引文件,方便后续流畅播放;
  • 做了断点续传:客户端会记录已上传的分片ID,万一录制中断,重启后可以从断点继续上传,不用重录整个视频。

四、关于MPD文件的生成

浏览器JS几乎不会直接生成MPD,因为MPD需要处理多码率适配、分片时序、分辨率这些复杂逻辑,建议在服务器端用FFmpeg完成:
当所有分片上传完成后,服务器先把分片合并成完整视频,再转成DASH格式生成MPD,比如用这条FFmpeg命令:

ffmpeg -i combined.webm -c:v libx264 -c:a aac -f dash output.mpd

五、关键注意事项

  • 内存清理:上传完分片后,要及时从内存中移除对应的Blob对象,避免长时间录制导致内存泄漏;
  • Chrome扩展权限:如果做扩展,必须在manifest.json里声明desktopCapture、audioCapture权限,还要加host_permissions允许访问你的上传服务器;
  • 错误重试:上传失败的分片要存在本地IndexedDB或localStorage,录制结束后统一重试;
  • 编码选择:优先用VP9/AV1编码,带宽和存储成本比H.264低很多,适合5小时以上的长视频。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 04:02:01