news 2026/8/23 16:13:41

iOS悬浮窗通话怎么做?react-native-agora画中画(PiP)完整实现指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
iOS悬浮窗通话怎么做?react-native-agora画中画(PiP)完整实现指南

iOS悬浮窗通话怎么做?react-native-agora画中画(PiP)完整实现指南

【免费下载链接】react-native-agoraReact Native around the Agora RTC SDKs for Android and iOS agora项目地址: https://gitcode.com/gh_mirrors/re/react-native-agora

react-native-agora是 Agora RTC SDK 的 React Native 封装库,帮你在移动 App 中快速搭建音视频通话。本文以iOS 悬浮窗通话为例,讲解如何用它的**画中画(Picture-in-Picture,PiP)**能力,让用户在 App 切到后台时仍保留一个视频小窗继续通话——看完即可跑通一套完整、合规的 PiP 悬浮通话方案。

一、为什么通话类 App 需要画中画(PiP)悬浮窗?

  • 📱 用户切出去回消息、刷其他 App,通话不断线、小窗常亮
  • 🧩 悬浮窗由系统托管,不占用你的 App 界面,拖拽/缩放/恢复都开箱即用
  • 🚀 平台支持广:iOS 15.0+、Android 8.0+,且 react-native-agorav4.6.2+已把两端 API 统一封装,一套 TS 代码写双端

二、快速认识 PiP 核心 API

react-native-agora 的 PiP 能力集中在engine.getAgoraPip()返回的控制器上:

方法作用
pipIsSupported()当前设备是否支持画中画
pipIsAutoEnterSupported()是否支持应用切后台自动进入 PiP
pipSetup(options)配置悬浮窗(尺寸、内容、布局、控件)
pipStart()/pipStop()启动 / 停止画中画
pipDispose()释放 PiP 控制器资源(防内存泄漏)
registerPipStateChangedObserver()监听 PiP 状态变化

状态枚举共三种:pipStateStarted(已启动)、pipStateStopped(已停止)、pipStateFailed(失败)。完整定义见 src/IAgoraPip.ts。

三、iOS 前置配置:这 3 步不做,悬浮窗出不来 ⚠️

1️⃣ 开启 Background Modes 能力(必须)

在 Xcode 中选择 App Target →Signing & Capabilities→ 点+ Capability→ 添加Background Modes→ 勾选“Audio, AirPlay, and Picture in Picture”

2️⃣ 在 Info.plist 中声明后台音频模式(必须)

UIBackgroundModes中加入audio,示例工程的配置如下:Info.plist

3️⃣ 多任务下保留摄像头(可选)

如果你希望在悬浮窗里显示本地摄像头画面,iOS 处于多任务(PiP)模式时需要com.apple.developer.avfoundation.multitasking-camera-accessentitlement(iOS 16 以下需向 Apple 申请;iOS 16+ 可将捕获会话的multitaskingCameraAccessEnabled设为 true)。不展示本地流可跳过此步。

四、5 步实现 iOS 悬浮窗通话(核心代码不到 30 行)

// Step 1: 创建引擎 + 注册 PiP 状态监听器 const engine = createAgoraRtcEngine(); engine.initialize({ appId, channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting }); engine.registerEventHandler(this); engine.getAgoraPip().registerPipStateChangedObserver(this); // Step 2: 入会(广播者角色,发送视频流) await engine.joinChannel(token, channelId, uid, { clientRoleType: ClientRoleType.ClientRoleBroadcaster, }); // Step 3: 配置画中画(iOS) const options: AgoraPipOptions = { preferredContentWidth: 960, // 悬浮窗首选宽度 preferredContentHeight: 540, // 悬浮窗首选高度 sourceContentView: 0, // 0 = 根视图,用于进出场动画 contentView: 0, // 0 = SDK 自动托管视频流(推荐) contentViewLayout: { row: 1, column: 0, spacing: 2 }, // 网格布局 videoStreams, // 要显示的本地/远端视频流 controlStyle: 2, // 只保留“关闭”和“恢复”按钮 }; engine.getAgoraPip().pipSetup(options); // Step 4: 启动画中画(⚠️ iOS 必须由用户点击触发) engine.getAgoraPip().pipStart(); // Step 5: 离开频道 / 页面卸载时释放,防止内存泄漏 engine.getAgoraPip().pipDispose(); engine.getAgoraPip().release();

💡 本地流和远端流都要显示时,把它们都放进videoStreams数组即可,SDK 会按网格自动排布并管理原生视图。

五、iOS 专属参数详解:controlStyle 到底选几?

参数说明推荐值
preferredContentWidth/Height悬浮窗初始尺寸,建议与视频视图一致960 × 540
sourceContentView进出场动画源视图,0 = App 根视图0
contentView0 = SDK 自动托管视频流;传自定义视图 ID 则需自己管理内容0
contentViewLayout网格布局:row行数、column每行列数、spacing间距单流1×0
controlStyle系统控件样式,见下表2

controlStyle四档可选:

效果
0显示全部系统控件(默认)
1隐藏快进/快退按钮
2隐藏播放/暂停与进度条,仅保留关闭和恢复(视频会议场景推荐 ✅)
3隐藏所有控件

六、状态监听:通话悬浮窗的“保险丝” 🔌

实现onPipStateChanged回调,是生产环境必备的一步:

onPipStateChanged(state: AgoraPipState, error: string | null) { if (state === AgoraPipState.pipStateFailed) { // 失败时立即释放控制器,避免后续操作报错 this.engine?.getAgoraPip().pipDispose(); } this.setState({ pipState: state }); }

两个易被忽略的细节(示例工程中的真实做法,见 PictureInPicture.tsx):

  • 🧠远端用户加入/退出后要重新pipSetup:窗口渲染是异步的,示例用setTimeout等渲染完成后再 setup;
  • 🧹离开频道时主动pipDispose()onLeaveChannel回调和组件卸载时都要释放,失败态同理。

七、常见坑点自查清单 ✅

  1. iOS 上 PiP 必须由用户操作发起——程序自动启动可能被 App Store 拒审,务必绑在按钮点击上;
  2. 忘记加 Background Modes是“悬浮窗不出来”的头号原因,Xcode 能力 + Info.plist 缺一不可;
  3. iOS 的悬浮窗由原生UIView托管,无需自己画 UI;而 Android 走 Activity,需自行处理界面(详见官方说明 PictureInPicture.md);
  4. pipDispose()会造成内存泄漏
  5. 想跑通全流程,克隆仓库后直接看示例:git clone https://gitcode.com/gh_mirrors/re/react-native-agora

八、相关模块路径速查

模块路径
完整 PiP 示例(双端)examples/expo/app/examples/advanced/PictureInPicture/PictureInPicture.tsx
PiP 功能说明文档examples/expo/app/examples/advanced/PictureInPicture/PictureInPicture.md
PiP 类型定义src/IAgoraPip.ts
PiP TS 层实现src/internal/AgoraPipInternal.ts
iOS 原生模块(PiP 桥接)ios/AgoraRtcNg.mm

小结:iOS 悬浮窗通话 = 后台音频能力 + 5 步 API 调用 + 状态监听兜底。照着本文配置 Background Modes、设置contentView: 0让 SDK 托管视频流、controlStyle: 2精简控件,你就能得到一个既流畅又符合审核规范的画中画通话体验。🎬

【免费下载链接】react-native-agoraReact Native around the Agora RTC SDKs for Android and iOS agora项目地址: https://gitcode.com/gh_mirrors/re/react-native-agora

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/23 16:12:20

dingo 数据质量评估:给 LLM 训练数据做体检

dingo 数据质量评估:给 LLM 训练数据做体检 【免费下载链接】dingo Dingo: A Comprehensive AI Data, Model and Application Quality Evaluation Tool 项目地址: https://gitcode.com/gh_mirrors/dingo5/dingo 语料里混着重复文档、乱码、身份证号&#xff…

作者头像 李华
网站建设 2026/8/23 16:12:00

如何10分钟快速部署Sunshine:从零开始的游戏串流完整指南

如何10分钟快速部署Sunshine:从零开始的游戏串流完整指南 【免费下载链接】foundation-sunshine Sunshine fork: an enhanced sunshine, a self-hosted game streaming host for Moonlight with HDR10/HDR Vivid, virtual displays, advanced audio, optimized enco…

作者头像 李华
网站建设 2026/8/23 16:10:22

如何用LLaMA-Factory微调MiniCPM-o-2_6:全模态模型领域适配完整教程

如何用LLaMA-Factory微调MiniCPM-o-2_6:全模态模型领域适配完整教程 【免费下载链接】MiniCPM-o-2_6 项目地址: https://ai.gitcode.com/OpenBMB/MiniCPM-o-2_6 MiniCPM-o-2_6 是 OpenBMB 开源的 8B 全模态多模态模型,支持图像、视频、音频理解与…

作者头像 李华
网站建设 2026/8/23 16:05:28

ol-plot 入门使用指南:三步把标绘工具接到 OpenLayers 地图上

ol-plot 入门使用指南:三步把标绘工具接到 OpenLayers 地图上 【免费下载链接】ol-plot :art: | openalyers 3 / 4 / 5 / 6 / 7 扩展标绘 项目地址: https://gitcode.com/gh_mirrors/ol/ol-plot ol-plot 是一个面向 OpenLayers 的地图标绘扩展插件&#xff0…

作者头像 李华