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

如何将getDisplayMedia与getUserMedia获取的两路媒体流合并为一路

两路媒体流合并方案

核心合并逻辑分为两种场景,可根据你的使用需求选择:

基础合并(直接打包轨道,无内容混合)

如果你只需要把两路流的所有音视频轨道整合到同一个MediaStream对象中,不需要做画面叠加、音频混音,直接提取所有轨道传入新的MediaStream构造函数即可:

// 先获取两路独立媒体流
const displayStream = await navigator.mediaDevices.getDisplayMedia({ audio: true, video: true });
const cameraStream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });

// 合并轨道生成新流
const mixedStream = new MediaStream([
  ...displayStream.getTracks(),
  ...cameraStream.getTracks()
]);

注意:该方案生成的流会包含2条视频轨道、2条音频轨道,如果你后续需要推流、用MediaRecorder录制,大多数播放器/录制工具默认只会读取第一条音视频轨道,这种场景需要使用进阶混合方案。

进阶混合(生成单音轨单视频轨的标准流)

如果需要输出仅有1条视频轨、1条音频轨的标准媒体流,需要分别做画面合成和音频混音:

1. 视频画面混合(支持摄像头画面叠加到屏幕共享)

用Canvas绘制两路视频画面,再通过captureStream()获取混合后的视频轨:

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// 初始化画布尺寸和屏幕共享分辨率一致
const displayVideo = document.createElement('video');
displayVideo.srcObject = displayStream;
await displayVideo.play();
canvas.width = displayVideo.videoWidth;
canvas.height = displayVideo.videoHeight;

// 初始化摄像头播放元素
const cameraVideo = document.createElement('video');
cameraVideo.srcObject = cameraStream;
await cameraVideo.play();

// 循环绘制混合画面
function drawFrame() {
  // 绘制底层屏幕共享画面
  ctx.drawImage(displayVideo, 0, 0, canvas.width, canvas.height);
  // 绘制右下角小窗口摄像头画面,尺寸为画布1/4
  const cameraWidth = canvas.width / 4;
  const cameraHeight = canvas.height / 4;
  ctx.drawImage(cameraVideo, canvas.width - cameraWidth - 20, canvas.height - cameraHeight - 20, cameraWidth, cameraHeight);
  requestAnimationFrame(drawFrame);
}
drawFrame();

// 获取混合后的视频轨
const mixedVideoTrack = canvas.captureStream().getVideoTracks()[0];

2. 音频混音

用AudioContext混合两路音频后输出混合音频轨:

const audioCtx = new AudioContext();
// 创建两路音频源
const displayAudioSource = audioCtx.createMediaStreamSource(displayStream);
const cameraAudioSource = audioCtx.createMediaStreamSource(cameraStream);
// 创建混音输出节点
const mixOutput = audioCtx.createMediaStreamDestination();
// 连接到混音节点
displayAudioSource.connect(mixOutput);
cameraAudioSource.connect(mixOutput);

// 获取混合后的音频轨
const mixedAudioTrack = mixOutput.stream.getAudioTracks()[0];

3. 生成最终单路流

const finalMixedStream = new MediaStream([mixedVideoTrack, mixedAudioTrack]);

内容的提问来源于stack exchange,提问作者Abdul in a Hellcat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 11:39:03