You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于getUserMedia实现网页端持续录制视频且仅保留最后2分钟内容的方案咨询

基于getUserMedia实现网页端持续录制视频且仅保留最后2分钟内容的方案咨询

嗨,这个台球复盘的场景我之前帮朋友做过类似的工具,核心思路是分段循环录制+缓存队列管理——不用一直录一个超大文件,而是拆成小片段只保留最近的2分钟内容,触发保存时再合并这些片段。下面给你具体的实现方案:

核心逻辑拆解

  • MediaRecorder把视频拆成固定时长的小片段(比如10秒一段,可根据需求调整)
  • 维护一个缓存队列,每次新片段生成就加入队列,同时检查总时长,超过2分钟就删掉最早的片段
  • 当你需要复盘时(比如用户点击“保存精彩时刻”按钮),把队列里的所有片段合并成一个完整的2分钟视频,提供下载或分析

具体代码实现

// 全局变量:缓存队列、录制器、每段时长、目标总时长
let chunkQueue = [];
let mediaRecorder = null;
const segmentDuration = 10 * 1000; // 每段10秒,可按需调整
const targetTotalDuration = 2 * 60 * 1000; // 目标保留2分钟

// 初始化获取媒体流并启动持续录制
async function initRecording() {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
    // 选择兼容的MIME类型,优先webm(大部分浏览器支持)
    const mimeType = MediaRecorder.isTypeSupported('video/webm;codecs=vp9') 
      ? 'video/webm;codecs=vp9' 
      : 'video/webm';
    
    mediaRecorder = new MediaRecorder(stream, { mimeType });
    
    // 每段录制完成时的回调
    mediaRecorder.ondataavailable = handleDataAvailable;
    // 录制结束后自动重启,实现持续录制
    mediaRecorder.onstop = () => {
      if (stream.active) {
        mediaRecorder.start(segmentDuration);
      }
    };

    // 开始第一次录制
    mediaRecorder.start(segmentDuration);
    console.log("持续录制已启动,将保留最后2分钟内容");
  } catch (err) {
    console.error("录制初始化失败:", err);
    alert("无法获取摄像头/麦克风权限,请检查浏览器设置");
  }
}

// 处理每段录制完成的片段
function handleDataAvailable(e) {
  if (e.data.size > 0) {
    // 加入缓存队列
    chunkQueue.push(e.data);
    
    // 计算当前队列总时长,超过2分钟则删除最早的片段
    const maxSegments = Math.ceil(targetTotalDuration / segmentDuration);
    if (chunkQueue.length > maxSegments) {
      chunkQueue.shift();
    }
  }
}

// 触发保存最后2分钟视频的函数
function saveLastTwoMinutes() {
  if (chunkQueue.length === 0) {
    alert("暂无可保存的录制内容");
    return;
  }
  
  // 合并所有片段成一个Blob
  const combinedBlob = new Blob(chunkQueue, { type: chunkQueue[0].type });
  // 创建下载链接
  const url = URL.createObjectURL(combinedBlob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `台球精彩瞬间_${new Date().toISOString().slice(0,19)}.webm`;
  a.click();
  // 释放URL对象,避免内存泄漏
  URL.revokeObjectURL(url);
}

// 停止录制的函数(可选)
function stopRecording() {
  if (mediaRecorder && mediaRecorder.state !== 'inactive') {
    mediaRecorder.stop();
    chunkQueue = [];
    console.log("录制已停止");
  }
}

// 页面加载完成后初始化
window.addEventListener('load', initRecording);

关键注意事项

  • MIME类型兼容:不同浏览器对视频编码的支持不同,建议优先用webm格式;如果需要MP4,部分浏览器支持video/mp4,但要提前用MediaRecorder.isTypeSupported检测
  • 内存管理:长时间运行后如果发现内存占用过高,可以手动清空队列并触发浏览器垃圾回收(需开启浏览器相关设置)
  • 触发时机:你可以把saveLastTwoMinutes绑定到按钮点击、键盘快捷键(比如按空格键),甚至可以做简单的运动检测(比如台球碰撞时自动触发)
  • 音频处理:如果不需要录制声音,把getUserMedia里的audio: true改成audio: false即可

备注:内容来源于stack exchange,提问作者DGi

火山引擎 最新活动