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

如何正确录制Canvas视频?解决时长异常与WhatsApp分享失真问题

Canvas录制视频时长过短+WhatsApp分享失真解决方案

问题背景

使用Media Recorder API录制HTML Canvas,完成后上传服务器,再通过Web Share API分享至WhatsApp等应用。已实现基础录制与上传功能,但存在两个核心问题:

  • 录制的视频时长过短,与实际操作时长不符
  • 分享至WhatsApp后视频画面失真

问题1:录制视频时长过短的修复

核心原因

  1. 在ondataavailable回调中错误设置e.target.videoBitsPerSecond=10,极低码率导致录制数据异常
  2. 依赖setTimeout+手动计时计算视频时长,未等待MediaRecorder完成数据收尾
  3. Canvas未持续绘制时,captureStream会停止推送帧,导致流中断

修复代码

let recording = false;
let mediaRecorder;
let recordedChunks = [];

recordBtn.addEventListener("click", () => {
  recording = !recording;
  if(recording){
    recordBtn.textContent = "Stop";
    
    // 维持Canvas持续绘制,避免流中断
    const drawLoop = () => {
      if(recording) requestAnimationFrame(drawLoop);
    };
    drawLoop();
    
    const stream = can.captureStream(25);
    // 初始化时设置合理编码参数,优先选兼容性更好的VP8
    mediaRecorder = new MediaRecorder(stream, {
      mimeType: 'video/webm;codecs=vp8',
      ignoreMutedMedia: true,
      videoBitsPerSecond: 4000000,
      audioBitsPerSecond: 128000
    });
    recordedChunks = [];
    
    mediaRecorder.ondataavailable = e => {
      if(e.data.size > 0){
        recordedChunks.push(e.data);
      }
    };
    
    // 监听stop事件,确保所有数据块收集完成再处理
    mediaRecorder.onstop = () => {
      const blob = new Blob(recordedChunks, { type: "video/webm" });
      const data = new FormData();
      data.append('file', blob, 'canvas-recording.webm');
      
      $.ajax({
        type: 'POST',
        data: data,
        contentType: false,
        processData: false,
        url: 'http://hthbeats.pythonanywhere.com/file' 
      }).then(function( data ) {
        console.log('上传成功', data);
      });
    };
    
    mediaRecorder.start();
  } else {
    recordBtn.textContent = "Record";
    mediaRecorder.stop();
  }
});

问题2:WhatsApp分享视频失真的修复

核心原因

  1. VP9编码的WebM格式在WhatsApp中兼容性差,平台转码时易导致画面失真
  2. WebM并非社交平台主流支持格式,优先选择H.264编码的MP4格式

修复方案

方案1:直接录制MP4(浏览器支持时)

先检测浏览器支持的MIME类型,优先选择H.264编码的MP4:

function getSupportedMimeType() {
  const options = [
    'video/mp4;codecs=h264',
    'video/webm;codecs=vp8',
    'video/webm;codecs=vp9'
  ];
  for(const mimeType of options) {
    if(MediaRecorder.isTypeSupported(mimeType)) {
      return mimeType;
    }
  }
  return null;
}

// 录制时使用
const stream = can.captureStream(25);
const mimeType = getSupportedMimeType();
mediaRecorder = new MediaRecorder(stream, {
  mimeType,
  ignoreMutedMedia: true,
  videoBitsPerSecond: 4000000,
  audioBitsPerSecond: 128000
});

方案2:前端转码为MP4(浏览器不支持直接录制时)

使用FFmpeg.wasm将WebM转码为MP4:

mediaRecorder.onstop = async () => {
  const webmBlob = new Blob(recordedChunks, { type: "video/webm" });
  
  const ffmpeg = FFmpeg.createFFmpeg({ log: true });
  await ffmpeg.load();
  
  ffmpeg.FS('writeFile', 'input.webm', await fetch(webmBlob).then(r => r.arrayBuffer()));
  // H.264编码+AAC音频,适配WhatsApp
  await ffmpeg.run('-i', 'input.webm', '-c:v', 'libx264', '-crf', '23', '-preset', 'medium', '-c:a', 'aac', '-b:a', '128k', 'output.mp4');
  
  const mp4Data = ffmpeg.FS('readFile', 'output.mp4');
  const mp4Blob = new Blob([mp4Data.buffer], { type: 'video/mp4' });
  
  // 上传转码后的MP4
  const data = new FormData();
  data.append('file', mp4Blob, 'canvas-recording.mp4');
  
  $.ajax({
    type: 'POST',
    data: data,
    contentType: false,
    processData: false,
    url: 'http://hthbeats.pythonanywhere.com/file' 
  }).then(function( data ) {
    console.log('上传成功', data);
  });
};

修改分享代码(适配MP4)

async function m(){
  try {
    let blob = await fetch("https://hthbeats.pythonanywhere.com/static/t.mp4").then(r => r.blob());
    const file = new File([blob], "canvas-recording.mp4", {type: 'video/mp4'});
    const filesArray = [file];
    
    const shareData = {
      files: filesArray,
      title: 'HTh-Beats',
      text: 'Video sharing ',
      url: "https://hthbeats.pythonanywhere.com/static/t.mp4"
    };
    
    await navigator.share(shareData);
    console.log('分享成功');
  } catch(err) {
    console.log('分享取消或失败', err);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 20:39:24