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

Flutter中自定义Agora视频通话UI:实现大小视频切换

实现Agora双人通话主次视频窗切换

核心思路

通过维护一个状态变量跟踪当前主窗口的用户ID,动态调整视频渲染的容器大小和位置,同时给小窗口绑定切换事件,实现点击互换主次的效果。

步骤1:添加状态变量

在组件内部定义状态,用来记录当前主窗口显示的用户ID(默认优先远端用户):

// 以React函数组件为例
const [mainUid, setMainUid] = useState(null);
// 类组件则在state中定义:this.state = { mainUid: null }

步骤2:处理远端用户加入事件

当检测到远端用户加入时,自动将该用户设为主窗口,本地用户作为小窗:

// 监听Agora的用户加入事件
client.on('user-joined', async (user) => {
  // 假设本地用户ID为localUid,可从Agora实例中获取
  setMainUid(user.uid);
  // 执行订阅远端流等原有逻辑...
});

步骤3:修改_viewRows()渲染逻辑

重构渲染函数,根据用户数量和mainUid状态分配主次窗口:

function _viewRows() {
  const localStream = this.state.localStream;
  const remoteStreams = this.state.remoteStreams;
  const allStreams = [localStream, ...remoteStreams].filter(stream => stream);
  
  // 仅处理双人通话场景
  if (allStreams.length === 2) {
    const mainStream = allStreams.find(s => s.getId() === mainUid);
    const miniStream = allStreams.find(s => s.getId() !== mainUid);
    
    return (
      <div className="video-container">
        {/* 主窗口 */}
        <div className="main-video">
          <div className="agora-video" style={{ width: '100%', height: '100%' }}>
            {mainStream ? mainStream.play(`agora-main-${mainUid}`) : null}
          </div>
        </div>
        {/* 小窗口,绑定切换事件 */}
        <div 
          className="mini-video" 
          onClick={() => this.switchMainVideo(miniStream.getId())}
        >
          <div className="agora-video" style={{ width: '100%', height: '100%' }}>
            {miniStream ? miniStream.play(`agora-mini-${miniStream.getId()}`) : null}
          </div>
        </div>
      </div>
    );
  }
  
  // 单人/多人场景保留原均分渲染逻辑,这里粘贴你原有代码即可
  // ...
}

步骤4:实现切换函数

添加切换主窗口的方法,点击小窗时互换主次:

// 类组件示例
switchMainVideo(targetUid) {
  const localUid = this.state.localStream.getId();
  this.setState(prev => ({
    mainUid: prev.mainUid === targetUid ? localUid : targetUid
  }));
}

// 函数组件示例
const switchMainVideo = (targetUid) => {
  const localUid = localStream.getId();
  setMainUid(prev => prev === targetUid ? localUid : targetUid);
}

步骤5:添加CSS样式

给主次窗口设置布局,确保小窗固定在角落:

.video-container {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}

.main-video {
  width: 100%;
  height: 100%;
}

.mini-video {
  position: absolute;
  bottom: 20px;
  right: 20px;
  width: 22%;
  height: 22%;
  border: 2px solid #fff;
  border-radius: 6px;
  cursor: pointer;
  z-index: 10;
}

注意事项

  1. 给每个视频元素设置唯一ID(比如agora-main-${uid}),避免Agora播放时DOM冲突。
  2. 类组件需注意绑定switchMainVideo的this指向(可在constructor中绑定或使用箭头函数)。
  3. 多人通话场景下,可保留原均分逻辑,或扩展为支持切换任意用户为主窗口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:20:29