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

React单Web应用中通过AWS IVS同时推送多路流的问题

解决同一React实例中AWS IVS同时推送摄像头/屏幕流时的覆盖问题

核心问题分析

同一标签页中后启动的流覆盖先启动的,本质是IVSBroadcastClient实例未完全隔离,或媒体轨道被多实例复用导致抢占。以下是针对性解决步骤:

1. 为每个频道创建完全独立的IVSBroadcastClient实例

不能复用或共享同一个Client对象,必须为摄像头流和屏幕流分别初始化全新实例,绑定各自的频道密钥与推流地址:

import { IVSBroadcastClient } from 'amazon-ivs-web-broadcast';
import { useState } from 'react';

function StreamComponent() {
  // 用独立状态存储两个Client实例
  const [cameraClient, setCameraClient] = useState(null);
  const [screenClient, setScreenClient] = useState(null);

  // 初始化摄像头推流Client
  const initCameraStream = async (cameraStreamKey, ingestEndpoint) => {
    const cameraClient = IVSBroadcastClient.create({
      ingestEndpoint,
      streamKey: cameraStreamKey
    });
    setCameraClient(cameraClient);
  };

  // 初始化屏幕推流Client
  const initScreenStream = async (screenStreamKey, ingestEndpoint) => {
    const screenClient = IVSBroadcastClient.create({
      ingestEndpoint,
      streamKey: screenStreamKey
    });
    setScreenClient(screenClient);
  };
}

2. 隔离媒体流与轨道,禁止跨实例复用

摄像头流和屏幕流必须分别独立获取,不能共享同一媒体轨道(哪怕是同一设备的轨道):

// 获取独立的摄像头流
const getCameraStream = async () => {
  return navigator.mediaDevices.getUserMedia({
    video: { width: 1920, height: 1080 },
    audio: true
  });
};

// 获取独立的屏幕流
const getScreenStream = async () => {
  return navigator.mediaDevices.getDisplayMedia({
    video: { width: 1920, height: 1080 },
    // 若不需要屏幕音频可省略
    audio: false
  });
};

3. 为每个Client单独配置输入源

为两个Client分别绑定对应流的轨道,确保输入源ID完全独立:

// 配置摄像头Client
const configureCameraClient = async (cameraClient, cameraStream) => {
  const cameraConfig = {
    streamConfig: IVSBroadcastClient.STANDARD_LANDSCAPE,
    audio: {
      sources: [{ deviceId: cameraStream.getAudioTracks()[0].id }]
    },
    video: {
      sources: [{ deviceId: cameraStream.getVideoTracks()[0].id }]
    }
  };
  cameraClient.configure(cameraConfig);
};

// 配置屏幕Client
const configureScreenClient = async (screenClient, screenStream) => {
  const screenConfig = {
    streamConfig: IVSBroadcastClient.STANDARD_LANDSCAPE,
    video: {
      sources: [{ deviceId: screenStream.getVideoTracks()[0].id }]
    }
  };
  screenClient.configure(screenConfig);
};

4. 启动推流的正确流程

按「实例化Client → 获取独立媒体流 → 配置输入源 → 启动推流」的顺序分别执行两个流的操作:

// 启动摄像头推流
const startCameraBroadcast = async () => {
  const cameraStream = await getCameraStream();
  await initCameraStream('CAMERA_STREAM_KEY', 'INGEST_ENDPOINT');
  await configureCameraClient(cameraClient, cameraStream);
  cameraClient.startBroadcast();
};

// 启动屏幕推流
const startScreenBroadcast = async () => {
  const screenStream = await getScreenStream();
  await initScreenStream('SCREEN_STREAM_KEY', 'INGEST_ENDPOINT');
  await configureScreenClient(screenClient, screenStream);
  screenClient.startBroadcast();
};

5. 调试验证要点

  • 推流前打印两个Client的instanceId和对应轨道ID,确认实例与轨道完全独立;
  • 监听每个Client的error事件,排查是否存在轨道抢占或配置错误:
    cameraClient.addEventListener('error', (err) => console.error('摄像头推流错误:', err));
    screenClient.addEventListener('error', (err) => console.error('屏幕推流错误:', err));
    
  • 在AWS IVS控制台实时查看两个频道的流内容,确认无覆盖情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 16:25:15