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

如何使用JavaScript合并video.webm与audio.webm音视频文件?

能否用JavaScript合并video.webm和audio.webm文件?

可以在浏览器环境中用JavaScript实现这个需求,但绝对不能像示例里那样直接把两个Blob相加——Blob是二进制对象,这种操作只会得到字符串拼接的无效结果,完全达不到音视频合并的目的。你需要借助浏览器的MediaRecorder API和HTMLMediaElement来完成音视频流的同步合并。

实现步骤说明

  1. 创建隐藏的video和audio元素,分别加载对应的Blob资源
  2. 通过MediaStream将视频轨道和音频轨道合并为一个流
  3. 用MediaRecorder录制合并后的流,最终导出完整的音视频Blob

完整示例代码

async function mergeVideoAndAudio(videoBlob, audioBlob) {
  // 创建视频元素并加载视频Blob
  const videoEl = document.createElement('video');
  videoEl.src = URL.createObjectURL(videoBlob);
  videoEl.muted = true; // 避免播放时干扰
  await new Promise(resolve => videoEl.onloadedmetadata = resolve);

  // 创建音频元素并加载音频Blob
  const audioEl = document.createElement('audio');
  audioEl.src = URL.createObjectURL(audioBlob);
  await new Promise(resolve => audioEl.onloadedmetadata = resolve);

  // 创建合并的MediaStream
  const combinedStream = new MediaStream();
  // 添加视频轨道(兼容不同浏览器的API)
  if (videoEl.captureStream) {
    combinedStream.addTrack(videoEl.captureStream().getVideoTracks()[0]);
  } else if (videoEl.mozCaptureStream) {
    combinedStream.addTrack(videoEl.mozCaptureStream().getVideoTracks()[0]);
  }
  // 添加音频轨道
  combinedStream.addTrack(audioEl.captureStream().getAudioTracks()[0]);

  // 初始化MediaRecorder录制合并流
  const recorder = new MediaRecorder(combinedStream, { mimeType: 'video/webm; codecs=vp9,opus' });
  const chunks = [];

  recorder.ondataavailable = (e) => chunks.push(e.data);
  recorder.onstop = () => {
    const finalBlob = new Blob(chunks, { type: 'video/webm' });
    // 示例:下载合并后的文件
    const downloadLink = document.createElement('a');
    downloadLink.href = URL.createObjectURL(finalBlob);
    downloadLink.download = 'merged-video.webm';
    downloadLink.click();

    // 清理资源,避免内存泄漏
    URL.revokeObjectURL(videoEl.src);
    URL.revokeObjectURL(audioEl.src);
    URL.revokeObjectURL(downloadLink.href);
    combinedStream.getTracks().forEach(track => track.stop());
  };

  // 开始录制,同时播放音视频保证同步
  recorder.start();
  videoEl.play();
  audioEl.play();

  // 等音视频都播放完毕后停止录制
  await Promise.all([
    new Promise(resolve => videoEl.onended = resolve),
    new Promise(resolve => audioEl.onended = resolve)
  ]);
  recorder.stop();
}

// 调用示例
(async () => {
  const videoRes = await fetch('video.webm');
  const videoBlob = await videoRes.blob();
  
  const audioRes = await fetch('audio.webm');
  const audioBlob = await audioRes.blob();
  
  await mergeVideoAndAudio(videoBlob, audioBlob);
})();

关键注意事项

  • 该方案仅适用于浏览器环境,Node.js环境需要使用ffmpeg.wasm这类库实现
  • 必须保证音视频时长一致,否则会出现其中一个播放完毕后录制提前终止的情况
  • 不同浏览器对MediaRecorder的编码格式支持有差异,示例中video/webm; codecs=vp9,opus是主流浏览器兼容的格式
  • 必须在用户交互(比如按钮点击)触发函数,否则浏览器会阻止自动播放音视频

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 16:35:21