Flutter PIP 插件 ---- iOS Video Call

以下是一篇关于在 iOS 中实现画中画(PiP)功能的技术博客:

iOS 画中画(PiP)功能实现指南

简介

画中画(Picture in Picture, PiP)是一项允许用户在使用其他应用时继续观看视频内容的功能。本文将详细介绍如何在 iOS 应用中实现 PiP 功能。

系统要求

  • iOS 15.0 及以上版本
  • AVKit 框架

核心组件

实现 PiP 功能主要涉及以下几个核心组件:

  1. AVPictureInPictureController - 负责管理 PiP 会话
  2. AVPictureInPictureControllerContentSource - 定义 PiP 内容源
  3. AVPictureInPictureVideoCallViewController - 控制 PiP 窗口的视图控制器

实现步骤

1. 检查设备支持

首先需要检查设备是否支持 PiP 功能:

- (BOOL)isSupported {if (@available(iOS 15.0, *)) {return [AVPictureInPictureController isPictureInPictureSupported];}return NO;
}

2. 创建 PiP 视图

需要创建一个自定义视图来显示 PiP 内容:

@interface PipView : UIView
@end@implementation PipView
+ (Class)layerClass {return [AVSampleBufferDisplayLayer class];
}
@end

3. 配置 PiP 控制器

设置 PiP 控制器需要以下步骤:

- (BOOL)setup:(PipOptions *)options {if (!self.isSupported) {return NO;}if (@available(iOS 15.0, *)) {// 创建 PiP 视图_pipView = [[PipView alloc] init];// 创建视图控制器AVPictureInPictureVideoCallViewController *pipViewController = [[AVPictureInPictureVideoCallViewController alloc] init];pipViewController.preferredContentSize = options.preferredContentSize;[pipViewController.view addSubview:_pipView];// 创建内容源AVPictureInPictureControllerContentSource *contentSource =[[AVPictureInPictureControllerContentSource alloc]initWithActiveVideoCallSourceView:options.sourceContentViewcontentViewController:pipViewController];// 初始化 PiP 控制器_pipController = [[AVPictureInPictureController alloc]initWithContentSource:contentSource];_pipController.delegate = self;_pipController.canStartPictureInPictureAutomaticallyFromInline = options.autoEnterEnabled;return YES;}return NO;
}

4. 控制 PiP 会话

启动 PiP:
- (BOOL)start {if (!self.isSupported) {return NO;}dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 0.1),dispatch_get_main_queue(), ^{if (self->_pipController.isPictureInPicturePossible) {[self->_pipController startPictureInPicture];}});return YES;
}
停止 PiP:
- (void)stop {if (self->_pipController.isPictureInPictureActive) {[self->_pipController stopPictureInPicture];}
}
释放资源:
- (void)dispose {if (@available(iOS 15.0, *)) {self->_pipController.contentSource = nil;}if (self->_isPipActived) {self->_isPipActived = NO;[self->_pipStateDelegate pipStateChanged:PipStateStopped error:nil];}
}

5. 实现状态回调

通过实现 AVPictureInPictureControllerDelegate 协议来处理 PiP 状态变化:

- (void)pictureInPictureControllerDidStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {_isPipActived = YES;[_pipStateDelegate pipStateChanged:PipStateStarted error:nil];
}- (void)pictureInPictureControllerDidStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {_isPipActived = NO;[_pipStateDelegate pipStateChanged:PipStateStopped error:nil];
}- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureControllerfailedToStartPictureInPictureWithError:(NSError *)error {[_pipStateDelegate pipStateChanged:PipStateFailed error:error.description];
}

注意事项

  1. PiP 功能仅支持 iOS 15.0 及以上版本
  2. 启动 PiP 时需要适当延迟以确保正常显示
  3. 自动进入 PiP 模式需要在 setup 时配置 autoEnterEnabled 选项
  4. 释放资源时建议使用 contentSource = nil 而不是直接调用 stopPictureInPicture
  5. PiP 窗口的默认大小建议设置为至少 100x100,否则可能导致启动失败

最佳实践

  1. 在初始化时检查设备是否支持 PiP 功能
  2. 实现适当的错误处理和状态回调
  3. 在应用进入后台时,如果启用了自动进入选项,PiP 会自动启动
  4. 注意内存管理,及时释放不需要的资源

总结

iOS 的 PiP 功能实现主要依赖于 AVKit 框架,通过合理配置 AVPictureInPictureController 及其相关组件,可以为用户提供流畅的画中画体验。在实现过程中需要注意版本兼容性、状态管理和资源释放等问题。

参考

  • Adopting Picture in Picture for video calls

PS

本次实现还不太全面,出来的PIP窗口只是一个背景黑色,还没有实现视频的显示,后续会持续更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/16699.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TDengine 产品由哪些组件构成

目 录 背景产品生态taosdtaosctaosAdaptertaosKeepertaosExplorertaosXtaosX Agent应用程序或第三方工具 背景 了解一个产品,最好从了解产品包括哪些内容开始,我这里整理了一份儿 TDegnine 产品包括有哪些组件,每个组件作用是什么的说明&a…

实现限制同一个账号最多只能在3个客户端(有电脑、手机等)登录(附关键源码)

如上图,我的百度网盘已登录设备列表,有一个手机,2个windows客户端。手机设备有型号、最后登录时间、IP等。windows客户端信息有最后登录时间、操作系统类型、IP地址等。这些具体是如何实现的?下面分别给出android APP中采集手机信…

使用 Docker 安装 Open WebUI 并集成 Ollama 的 DeepSeek 模型

文章目录 使用 Docker 安装 Open WebUI 并集成 Ollama 的 DeepSeek 模型前提条件1. 安装ollama2. 拉取deepseek的模型3. Open-WebUI 说明4. 启动容器文档的方法如下优化命令(可选)1. 增加了健康检查机制(--health-cmd)2. 使 WebUI…

Untiy3d 铰链、弹簧,特殊的物理关节

(一)铰链组件 1.创建一个立方体和角色胶囊 2.给角色胶囊挂在控制脚本和刚体 using System.Collections; using System.Collections.Generic; using UnityEngine;public class plyer : MonoBehaviour {// Start is called once before the first execut…

【NLP 21、实践 ③ 全切分函数切分句子】

当无数个自己离去,我便日益坦然 —— 25.2.9 一、jieba分词器 Jieba 是一款优秀的 Python 中文分词库,它支持多种分词模式,其中全切分方式会将句子中所有可能的词语都扫描出来。 1.原理 全切分方式会找出句子中所有可能的词语组合。对于一…

团结引擎 OpenHarmony 平台全面支持 UAAL,实现引擎能力嵌入原生应用

团结引擎1.4版本已于近日正式发布!在这一版本中,OpenHarmony 平台迎来了一个具有里程碑意义的更新:全面支持 Used as a Library(UAAL)。UAAL 这一技术方案,具有将引擎嵌入原生应用的独特能力,其…

自己部署DeepSeek 助力 Vue 开发:打造丝滑的标签页(Tabs)

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 自己…

DeepSeek渣机部署编程用的模型,边缘设备部署模型

DeepSeek渣机部署编程用的模型,边缘设备部署模型 文章目录 DeepSeek渣机部署编程用的模型,边缘设备部署模型前言一、python代码二、构建一个简单的前端来接入接口2.读入数据 总结 前言 也许大家伙都想完成一些部署DeepSeek的东西,不过部署并…

VS2019打开《喜缺全书算法册》附带代码的方法兼述单元测试

下载地址(大量的题目和测试用例) 下载:地址一,几乎实时更新 GitCode下载。 下载地址二,不定期更新csdn打包下载 如果这两个链接打不开,可能是这两个资源处于审核状态,快则几分钟,慢则2天。 可以加本文末的&#xff31…

急停信号的含义

前言: 大家好,我是上位机马工,硕士毕业4年年入40万,目前在一家自动化公司担任软件经理,从事C#上位机软件开发8年以上!我们在开发C#的运动控制程序的时候,一个必要的步骤就是确认设备按钮的急停…

小白学网络安全难吗?需要具备哪些条件?

作为一名零基础小白,想要转行IT学习一门新技术,且上手难度低、就业前景好、薪资待遇高、入行门槛低,网络安全是最值得的选择,掌握它之后你可以获得一份收入不错的工作。那么零基础学网络安全好学吗?以下是具体内容介绍。 首先&am…

IEEE期刊Word导出PDF注意事项

在系统上提交论文时候一般要求PDF文档,但是word直接转PDF可能存在一些问题: 部分图片不清晰。字体未嵌入PDF。间距发生了变化。字体发生了变化。一张图片显示不完全。 下面介绍word转PDF最稳妥的技巧以及如何实现全部字体的嵌入。 1. 操作流程 ① 另…

CEF132 编译指南 MacOS 篇 - depot_tools 安装与配置 (四)

1. 引言 在 CEF132(Chromium Embedded Framework)的编译过程中,depot_tools 扮演着举足轻重的角色。这套由 Chromium 项目精心打造的脚本和工具集,专门用于获取、管理和更新 Chromium 及其相关项目(包括 CEF&#xff…

【C++高并发服务器WebServer】-16:UDP简单实现

本文目录 一、UDP通信流程二、UDP API2.1 sendto()2.2 recvfrom() 一、UDP通信流程 UDP通信的流程比较简单&#xff0c;下面这张图可以总结。 二、UDP API 2.1 sendto() UDP相关头文件如下。 #include <sys/types.h> #include <sys/socket.h>ssize_t sendto(…

k8s管理工具之lens

什么是lens Lens 是当前市场上最强大的K8S IDE。它是一个独立的单机应用&#xff0c;可以同时运行在macOS、Windows和Linux上。 作为K8S IDE&#xff0c;该有的它基本都有了&#xff01; 集群管理 导入已有集群 首先&#xff0c;你需要在 Lens 中添加你的 Kubernetes 集群。点…

SynthDetoxM - 现代LLM是少样本的并行去毒化数据标注器

SynthDetoxM: Modern LLMs are Few-Shot Parallel Detoxification Data Annotators https://arxiv.org/html/2502.06394v1 1. 主要内容 这篇论文提出了一个 用于生成多语言平行去毒化数据的管道&#xff0c;并介绍了SynthDetoxM&#xff0c;一个包含16,000个高质量去毒化句子对…

云服务器流量包用尽(中病毒)

1. 情况 腾讯云提示我账号欠费了&#xff0c;服务器存在恶意文件。。。 一看&#xff0c;流量包用尽超额了&#xff0c;CPU直接爆了。 用iftop监测一下网络流量。可以看到向多个IP发送了大量的流量。 看来是中病毒了&#xff0c;被当成 “肉鸡”&#xff0c;纳入“僵尸网络”…

RK3588视觉控制器与AI 算法:开启工业视觉检测新境界

在实际应用中&#xff0c;工业相机拍摄产品的图像&#xff0c;RK3588 迅速接收并进行预处理。AI 算法随即对图像进行深入分析&#xff0c;提取特征并与预设的标准进行对比&#xff0c;从而准确判断是否存在缺陷。 例如&#xff0c;在电子元件生产线上&#xff0c;RK3588 和 AI…

android的ViewModel这个类就是业务逻辑层吗

android的ViewModel这个类就是业务逻辑层吗&#xff1f; 相似&#xff1a;业务逻辑代码应该放在ViewModel这个类吗&#xff1f; 嗯&#xff0c;我现在在学习Android架构组件&#xff0c;特别是ViewModel。用户问ViewModel是否就是业务逻辑层&#xff0c;我需要仔细思考这个问题…

Gui-Guider1.8.1 数字时钟控件找不到定义,无法编译

我们在Gui-Guider中使用的一些控件&#xff0c;生成后会发现在LVGL源码中找不到该控件的定义&#xff0c;这时因为Gui-Guider中的一些控件是其自己编写的而不是LVGL提供的&#xff0c;那么我们该如何应用呢&#xff1f;这里拿Digital Clock数字时钟控件举例&#xff1a; 这里我…