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; }
注意事项
- 给每个视频元素设置唯一ID(比如
agora-main-${uid}),避免Agora播放时DOM冲突。 - 类组件需注意绑定
switchMainVideo的this指向(可在constructor中绑定或使用箭头函数)。 - 多人通话场景下,可保留原均分逻辑,或扩展为支持切换任意用户为主窗口。
内容的提问来源于stack exchange,提问作者Dasun Dola
相关产品推荐
相关产品推荐

