iOS ReplayKit 屏幕共享,屏幕直播实现

news2025/1/19 23:12:10

使用replayKit iOS12 之后相关 api 完成系统/app 内 屏幕采集直播视频数据, 采用 socket进行进程间Broadcast Unload Extension 向 宿主 app 传输数据, 后台保活持续采集屏幕数据, 摄像头采集, 数据编码解码

编译环境 Xcode14.2, iOS12

  • 系统屏幕数据采集
  • app 内屏幕共享
  • 使用socket 由 Broadcast Unload Extension 向宿主 app 传输数据
  • 视频解码
  • 程序永久保活
  • 创建 framework 供 Broadcast Unload Extension 和宿主 app 调用共用类

文章目录

      • 1. 第一步创建 Broadcast Unload Extension
      • 2. FIAgoraSampleHandlerSocketManager 关于数据传输的类 都放到一个framework 当中
      • 3. 宿主 App

1. 第一步创建 Broadcast Unload Extension

步骤: File -> new -> Target

截屏2023-01-06 17.39.39

创建好之后生成 一个扩展 App, 自动生成如图的一个 sampleHandr类

截屏2023-01-06 17.41.55

- (void)broadcastStartedWithSetupInfo:(NSDictionary<NSString *,NSObject *> *)setupInfo {
    // User has requested to start the broadcast. Setup info from the UI extension can be supplied but optional.
  	// 宿主 app开始直播屏幕的时候这里会走一次
  	// 设置 socket
  	// 其中 FIAgoraSampleHandlerSocketManager这个类可以看 Demo 的实现
    [[FIAgoraSampleHandlerSocketManager sharedManager] setUpSocket];
}

- (void)broadcastPaused {
    // User has requested to pause the broadcast. Samples will stop being delivered.
}

- (void)broadcastResumed {
    // User has requested to resume the broadcast. Samples delivery will resume.
}

- (void)broadcastFinished {
    // User has requested to finish the broadcast.
}

// 实时采集数据
- (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType {

    switch (sampleBufferType) {
        case RPSampleBufferTypeVideo:
            // Handle video sample buffer
        		// 发送视频数据导宿主 App
            [[FIAgoraSampleHandlerSocketManager sharedManager] sendVideoBufferToHostApp:sampleBuffer];
            break;
        case RPSampleBufferTypeAudioApp:
            // Handle audio sample buffer for app audio
            break;
        case RPSampleBufferTypeAudioMic:
            // Handle audio sample buffer for mic audio
            break;

        default:
            break;
    }
}

2. FIAgoraSampleHandlerSocketManager 关于数据传输的类 都放到一个framework 当中

  • 步骤: File -> new -> Target 创建 framework, 如图 1
  • 创建好之后在宿主 app 和 extension 分别引用, 如图 2

截屏2023-01-06 17.46.46

1672998592654

3. 宿主 App

  • 手动启动直播
  • 需要永久保活
  • 监测数据回调
  • 编码
  • 推流
  1. 初始化开启直播的按钮
// 设置系统的广播 Picker 视图
- (void)setupSystemBroadcastPickerView
{
    // 兼容 iOS12 或更高的版本
    if (@available(iOS 12.0, *)) {
        self.broadcastPickerView = [[RPSystemBroadcastPickerView alloc] initWithFrame:CGRectMake(50, 200, 100, 100)];
        self.broadcastPickerView.preferredExtension = @"summerxx.com.screen-share-ios.broadcast-extension";
        self.broadcastPickerView.backgroundColor = UIColor.cyanColor;
        self.broadcastPickerView.showsMicrophoneButton = NO;
        [self.view addSubview:self.broadcastPickerView];
    }
		// 改变系统提供的按钮的 UI, 这里有个风险, 以后可能会失效, 暂时用没有什么问题
    UIButton *startButton = [UIButton buttonWithType:UIButtonTypeCustom];
    startButton.frame = CGRectMake(50, 310, 100, 100);
    startButton.backgroundColor = UIColor.cyanColor;
    [startButton setTitle:@"开启摄像头" forState:UIControlStateNormal];
    [startButton setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
    [startButton addTarget:self action:@selector(startAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:startButton];
}
  1. 保活

截屏2023-01-06 17.57.10

监听
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(didEnterBackGround) name:UIApplicationDidEnterBackgroundNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(willEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];

- (void)willEnterForeground
{
  	// 这里具体可看 Demo
    [[FJDeepSleepPreventerPlus sharedInstance] stop];
}

- (void)didEnterBackGround
{
    [[FJDeepSleepPreventerPlus sharedInstance] start];
}
  1. 数据回调
    __weak __typeof(self) weakSelf = self;
    [FIAgoraClientBufferSocketManager sharedManager].testBlock = ^(NSString * testText, CMSampleBufferRef sampleBuffer) {
        
        // 进行视频编码
        [weakSelf.h264code encodeSampleBuffer:sampleBuffer H264DataBlock:^(NSData * data) {
            NSLog(@"%@", data);
          	// 编码后可进行推流流程
        }];
    };

到此就基本结束了

其中 数据传输的方式, 还可以用 App Group 的方式 我也实现了

Demo App Group
https://github.com/summerxx27/ReplayKitShareScreen

Demo socket 实现数据传输
https://github.com/summerxx27/ReplayKitShareScreen-socket

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FPGA与数字IC求职知识准备 - 数字电路知识总结

前言 本文整理了数字电路课程中的相关基本的知识点和较为重要的知识点&#xff0c;用于求职的数电部分的知识准备&#xff0c;差缺补漏。 二进制数的算术运算 无符号二进制数的算术运算 加法&#xff1a;同十进制加法&#xff0c;逢二进一&#xff0c;无符号二进制数的加法…

Redis源码篇(8)——集群模式

1、集群模式的启动和初始化 当开启了cluster-enabled&#xff0c;在初始化服务initServer方法中会调用clusterInit方法将redis带入cluster模式。 clusterInit void clusterInit(void) {int saveconf 0;//初始化clusterState结构 server.cluster zmalloc(sizeof(clusterSta…

LaTeX代码宏包listings的使用

LaTeX代码宏包listings的使用 文章目录LaTeX代码宏包listings的使用1 需求2 verbatim环境简介3 listings设置代码高亮4 代码样式和颜色5 为listings添加题注6 listings支持的语言格式7 附录 listings样式的自定义参数1 需求 LaTeX\LaTeXLATE​X适合用来进行结构化文档的编辑。如…

[5]. 最长回文子串

[5]. 最长回文子串题目算法设计&#xff1a;双指针算法设计&#xff1a;Manacher 算法题目 传送门&#xff1a;https://leetcode.cn/problems/longest-palindromic-substring/ 算法设计&#xff1a;双指针 检查回文串的通用解决方案是&#xff0c;双指针。 寻找回文串的思…

什么是地理围栏

一、地理围栏算法简介 地理围栏&#xff08;Geo-fencing&#xff09;是LBS的一种典型应用&#xff0c;就是用一个虚拟的栅栏围出一个虚拟地理边界。地理围栏更侧重于对区域边界的界定&#xff0c;不再是以某点为圆心向外等距离画圆&#xff0c;而是准确勾勒出小区、写字楼等特…

wpf实现FFmpeg获取摄像头实时画面

gitee地址如下源码地址如何获取摄像头验证码和ip首先获取摄像头底部的验证码及ip(测试使用的是萤石摄像头&#xff0c;需要PC下载萤石客户端查看ip)未连接之前可以通过VLC进行测试在左上角&#xff08;媒体&#xff09;--》&#xff08;流&#xff09;--》&#xff08;网络&…

openGauss中Schema赋权小试

目录 概述 1.关于public的权限要点&#xff1a; 2.关于用户同名的schema的权限要点&#xff1a; 3.关于普通schema的权限要点&#xff1a; 概述 下面是openGauss官网对Schema的介绍&#xff1a; Schema又称作模式。通过管理Schema&#xff0c;允许多个用户使用同一数据库而…

MATLAB-二维线性插值运算

二维插值在图像处理和数据可视化方面得到了大量的应用&#xff0c;二维插值的基本原理与一维插值一样&#xff0c;但二维插值是对两个变量进行函数的插值。在MATLAB中&#xff0c;主要使用interp2()函数进行二维插值的实现&#xff0c;其调用格式如下&#xff0c;zi interp2(z,…

Nodejs也能做文本数据处理了,快来看看吧!

随着汉语言的广泛应用&#xff0c;中文信息处理成了一个重要的研究课题&#xff0c;常见于搜索引擎&#xff1a;信息检索、中外文自动翻译、数据挖掘技术、自然语言处理等领域。在处理的过程中&#xff0c;中文分词是最基础的一环。 nodejieba 简介 nodeJieba 是结巴中文分词…

安装thinkphp

[TOC]目录 1. 安装composer 方法&#xff1a;https://www.kancloud.cn/manual/thinkphp6_0/1037481 官网教程中安装composer 2. 配置文件 在命令行中 阿里云&#xff1a; composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ 华为云&#x…

axios基础学习——通过 Vue + axios 获取接口数据的小demo

文章目录 &#x1f4cb;前言 &#x1f3af;关于axios概要 ❓什么是axios &#x1f9e9;axios特性 &#x1f9e9;axios浏览器支持情况 &#x1f3af;axios安装与使用 &#x1f9e9;axios请求方法 &#x1f9e9;axios的使用方法&#xff08;以get为例子&#xff09; &am…

[C语言]进一步的来了解指针(多多多图详解)

本文章进一步的来讲解指针&#xff0c;如果是第一次接触指针的可以先看一下对于指针的初步理解 &#xff1a; [C语言]初步的来了解一下指针&#xff08;多图详解&#xff09;_HY_PIGIE的博客-CSDN博客 目录 1.字符指针 2.指针数组 2.1指针数组&#xff1a;char*类型举例说明 2…

Thawte旗下通配符SSL证书都有什么区别

Thawte由南非Mark Shuttleworth创立&#xff0c;Thawte SSL证书产品占据了全球SSL数字证书市场的40&#xff05;&#xff0c;是全球第三大数字证书颁发机构&#xff08;CA&#xff09;。随后VeriSign于2000年2月1日以5.75亿美元对Thawte换股完成收购&#xff0c;互相合作&#…

GDI对象泄漏导致程序UI界面绘制异常的问题排查

目录 1、问题说明 2、初步分析 3、查看任务管理器&#xff0c;并使用GDIView工具分析 5、采用历史版本比对法&#xff0c;确定初次出现问题的时间点&#xff0c;并查看前一天的代码修改记录 6、将修改的代码与测试现象结合起来&#xff0c;最终定位问题 7、事后的思考 8…

Simulating Content Consistent Vehicle Datasets with Attribute Descent(略读)

提出了一个大型的3D合成数据集VehicleX。其中各个3D模型都有现实世界的车型对应。整个数据集有1362个id&#xff0c;其中包括11种主流车型。 论文&#xff1a;https://arxiv.org/pdf/1912.08855.pdf 摘要 本文使用图形引擎来模拟带有免费注释的大量训练数据。 在合成数据和真…

回归预测 | MATLAB实现RF随机森林多输入单输出回归预测(含回归树,误差柱状图,多指标)

回归预测 | MATLAB实现RF随机森林多输入单输出回归预测(含回归树,误差柱状图,多指标) 目录 回归预测 | MATLAB实现RF随机森林多输入单输出回归预测(含回归树,误差柱状图,多指标)效果分析基本介绍输出结果程序设计学习总结参考资料效果分析

Mars3D Studio平台发布

近日我们基于提供丰富及智能化功能&#xff0c;助力团队做出精美的交互场景的理念&#xff0c;研发了Mars3D Studio平台&#xff0c;于2023年1月10日正式发布上线&#xff01;欢迎大家访问http://studio.mars3d.cn/ 网站进行体验。一、资源广场团队公开的丰富资源数据&#xff…

LeetCode题目笔记——1658. 将 x 减到 0 的最小操作数

文章目录题目描述题目难度——中等方法一&#xff1a;反向思考&#xff0c;双指针求最长子数组代码/Python代码/C方法二&#xff1a;滑动窗口代码总结我把这篇也归到面试题那一栏&#xff0c;因为觉得这题的思路和思考方式还挺好的&#xff0c;或许能用到其他题上 题目描述 给…

基于Node.js Vue清新严选助农电商平台/电商平台/购物平台

摘 要网络技术的快速发展给各行各业带来了很大的突破&#xff0c;也给各行各业提供了一种新的管理模块&#xff0c;对于清新严选助农电商将是又一个传统管理到智能化信息管理的改革&#xff0c;设计清新严选助农电商平台的目的就是借助计算机让复杂的购买商品操作变简单&#x…

gcc和gdb的使用——Linux

Linux学习全部合集点击即可订阅 “人生得意须尽欢” 这里是目录标题gcc的基本操作gcc处理代码的步骤预处理编译汇编链接头文件和库静态库动态库gdb调试makefile什么是makefile&#xff1f;进度条的实现缓冲区回车和换行git的使用.gitigonregcc的基本操作 编写代码的最基本操作…