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

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-agorareact-native-agora是 Agora RTC SDK 的 React Native 封装库帮你在移动 App 中快速搭建音视频通话。本文以iOS 悬浮窗通话为例讲解如何用它的**画中画Picture-in-PicturePiP**能力让用户在 App 切到后台时仍保留一个视频小窗继续通话——看完即可跑通一套完整、合规的 PiP 悬浮通话方案。一、为什么通话类 App 需要画中画PiP悬浮窗 用户切出去回消息、刷其他 App通话不断线、小窗常亮 悬浮窗由系统托管不占用你的 App 界面拖拽/缩放/恢复都开箱即用 平台支持广iOS 15.0、Android 8.0且 react-native-agorav4.6.2已把两端 API 统一封装一套 TS 代码写双端二、快速认识 PiP 核心 APIreact-native-agora 的 PiP 能力集中在engine.getAgoraPip()返回的控制器上方法作用pipIsSupported()当前设备是否支持画中画pipIsAutoEnterSupported()是否支持应用切后台自动进入 PiPpipSetup(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.plist3️⃣ 多任务下保留摄像头可选如果你希望在悬浮窗里显示本地摄像头画面iOS 处于多任务PiP模式时需要com.apple.developer.avfoundation.multitasking-camera-accessentitlementiOS 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 × 540sourceContentView进出场动画源视图0 App 根视图0contentView0 SDK 自动托管视频流传自定义视图 ID 则需自己管理内容0contentViewLayout网格布局row行数、column每行列数、spacing间距单流1×0controlStyle系统控件样式见下表2controlStyle四档可选值效果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回调和组件卸载时都要释放失败态同理。七、常见坑点自查清单 ✅iOS 上 PiP 必须由用户操作发起——程序自动启动可能被 App Store 拒审务必绑在按钮点击上忘记加 Background Modes是“悬浮窗不出来”的头号原因Xcode 能力 Info.plist 缺一不可iOS 的悬浮窗由原生UIView托管无需自己画 UI而 Android 走 Activity需自行处理界面详见官方说明 PictureInPicture.md不pipDispose()会造成内存泄漏想跑通全流程克隆仓库后直接看示例git clone https://gitcode.com/gh_mirrors/re/react-native-agora八、相关模块路径速查模块路径完整 PiP 示例双端examples/expo/app/examples/advanced/PictureInPicture/PictureInPicture.tsxPiP 功能说明文档examples/expo/app/examples/advanced/PictureInPicture/PictureInPicture.mdPiP 类型定义src/IAgoraPip.tsPiP TS 层实现src/internal/AgoraPipInternal.tsiOS 原生模块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),仅供参考