Flutter PIP 插件 ---- iOS Video Call

devtools/2025/2/13 5:57:06/

以下是一篇关于在 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.ppmy.cn/devtools/158401.html

相关文章

Python:凯撒密码

题目内容: 凯撒密码是古罗马恺撒大帝用来对军事情报进行加密的算法,它采用了替换方法对信息中的每一个英文字符循环替换为字母表序列该字符后面第三个字符,对应关系如下: 原文:A B C D E F G H I J K L M N O P Q R …

OpenVINO 2025.0重磅升级:开启⽣成式AI全场景⾰命!

2025年2⽉6⽇,英特尔OpenVINO™ 2025.0版本震撼发布,本次升级堪称近三年最⼤规模技术⾰新!从⽣成 式AI性能跃升到全栈硬件⽀持,从开发者⼯具链优化到边缘计算突破,六⼤核⼼升级重新定义AI部署效率。 一,&a…

Flink-序列化

一、概述 几乎每个Flink作业都必须在其运算符之间交换数据,由于这些记录不仅可以发送到同一JVM中的另一个实例,还可以发送到单独的进程,因此需要先将记录序列化为字节。类似地,Flink的堆外状态后端基于本地嵌入式RocksDB实例&…

Django:构建高效Web应用的强大框架

在当今快速发展的Web开发领域,选择一个合适的框架对于项目的成功至关重要。Django,作为一个用Python编写的高级Web框架,凭借其强大的功能、灵活性和可扩展性,成为了众多开发者的首选。本文将深入探讨Django的特点、优势以及如何利…

PH热榜 | 2025-02-10

1. 2pr 标语:人工智能帮你把想法变成LinkedIn爆款 或者更口语化一点: AI帮你把点子变成LinkedIn上的热门帖子 介绍:用AI主持的访谈,把你的想法变成LinkedIn爆款帖子。录制你的想法,让AI帮你创作个性化、引人入胜的…

重构应用DeepSeek商城系统开发技术趋势

​在当今科技飞速发展的时代,AI人工智能已成为推动各行业变革的核心力量。DeepSeek 在短短一年多的时间里已经发布了多个版本的模型,包括 DeepSeek LLM、DeepSeek-V2、DeepSeek-V3 以及 DeepSeek-R1 等,每一次发布都在性能和功能上实现了重大…

STM32外设分类--最小系统引脚和GPIO引脚

简介: 本文将stm32f103外设按照功能分个类别,便于记忆。下面的几张图一定要熟悉,后期编写代码时能够快速找到想要的功能和对应的引脚。 使用的工具链是:使用CubeMX完成keil5工程搭建和引脚初始化功能,然后用Keil5编译和调…

【Linux】深入理解linux权限

🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:Linux 目录 前言 一、权限是什么 二、用户和身份角色 三、文件属性 1. 文件属性表示 2. 文件类型 3. 文件的权限属性 四、修改文件的权限属性和角色 1. …