前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TRTC iOS 屏幕分享功能实践(一)

TRTC iOS 屏幕分享功能实践(一)

原创
作者头像
GF
修改2020-11-04 15:54:06
3K0
修改2020-11-04 15:54:06
举报
文章被收录于专栏:腾讯云终端专家服务

一、iOS屏幕共享方案

实现直播过程中共享屏幕分为两个步骤:屏幕数据采集和流媒体数据推送。前对于iOS来说,屏幕采集需要系统的权限,受制于iOS系统的限制,第三方app并没有直接录制屏幕的权限,必须通过系统的功能来实现。不同的版本之间有一些差异,下面做个简单的介绍。(注:由于iOS 10和之前的系统只支持App内录制屏幕,所以只做简单的介绍,不做详细说明)

iOS 8 和以前

古老的iOS8和以前,系统没有提供相应的功能,通过破解系统的功能调用私有的API来实现。由于iOS8太过古老而且运行iOS8系统的设备也基本上支撑不起来直播的功能,我们这里不做详细讨论,有兴趣的可以研究一下。

iOS 9

Apple在iOS 9 推出了ReplayKit框架,提供了录屏功能,但是限制是只能录制本App内的屏幕。录制完成后会生成一个视频文件,只能通过RPPreviewViewController来预览,编译生成的文件,录制过程中无法获取数据。

iOS 10

iOS 10 Apple 推出了Broadcast Upload Extention 和 Broadcast Setup UI Extention,来解决录屏的问题。

首先介绍一下App Extension,官方文档(Extension的官方文档)。Extension是对App的扩展,在一定程度上打破了沙盒的限制,提供了应用间通信的可能。Extension是一个独立运行的进程,有自己的生命周期。下图所示:

摘自Apple官方文档
摘自Apple官方文档

这里有两个概念:

Containing app:an app that contains one or more extensions is called acontaining app.

很好理解,包含Extension的app就是Containing app。Extension不能单独发布安装,需要伴随着Containing app的安装而安装。

一个Containing app可以包含多个Extension。Extension可以单独运行,在Containing app没有启动的时候依然可以启动运行。Extension可以单独被系统调用,也可以被其它App调用。

Host app:An app that a user employs to choose an app extension is called a host app. A host app defines the context provided to the extension and kicks off the extension life cycle when it sends a request in response to a user action. An extension typically terminates soon after it completes the request it received from the host app.

Host app也容易理解,Extension一般由用户在某个app内启动,这个启动Extension的app就是host app。Host app提供了Extension运行所需的环境,通过request/response方式启动或者结束Extension的运行。交互过程如下:

来自Apple官方文档
来自Apple官方文档

iOS 10 通过Extension提供了录屏的功能,我们可以通过添加Extension来实现屏幕录制分享,可以实时读取到录制的缓存数据从而进行实时直播。但是iOS 10仅提供了录制本app内的功能。对在线会议这样的场景来说还是不够。

iOS 10的主要限制:只能录制本app内的数据。

iOS 11

到了iOS 11 Apple终于良心发现了,提供了跨app录屏的功能,可以实现录取整个屏幕的功能,当然还是通过集成ReplayKit (iOS11升级为ReplayKit2)的Extension来实现(这也是为什么腾讯的TRTC iOS屏幕分享功能最低支持到iOS11的原因)。但是还是有很大的限制,无法直接在app内部启动录制屏幕,需要用户点击控制中心的屏幕录制功能(如果控制中心中没有录屏按钮,需要在设置-》控制中心中添加),然后在弹出的选框中选择我们的Extension进行录屏。

iOS 11限制:app内无法直接启动屏幕录制,需要用户手动在控制中心启动。

iOS 12

iOS 12 在iOS11的基础上提供了RPSystemBroadcastPickerView,在弹出的界面可以选择启动Broadcast Upload Extention

来录制屏幕,用户无需在控制中心手动启动。

实现代码:

代码语言:txt
复制
let pickerView = RPSystemBroadcastPickerView(frame: CGRect(x: 100, y: 100, width: 200, height: 200))
pickerView.preferredExtension = "test.app.extension.screen"
pickerView.showsMicrophoneButton = true
self.view.addSubview(pickerView)    

Broadcast Upload Extention通过Xcode-》File-》New-》Target,然后选择Broadcast Upload Extention即可。

项目配置方式参考:https://cloud.tencent.com/document/product/647/45750

创建完成后会生成SampleHandler的类

实现代码:

代码语言:javascript
复制
import ReplayKit

class SampleHandler: RPBroadcastSampleHandler {

    override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) {
        // User has requested to start the broadcast. Setup info from the UI extension can be supplied but optional. 
    }
    
    override func broadcastPaused() {
        // User has requested to pause the broadcast. Samples will stop being delivered.
    }
    
    override func broadcastResumed() {
        // User has requested to resume the broadcast. Samples delivery will resume.
    }
    
    override func broadcastFinished() {
        // User has requested to finish the broadcast.
    }
    
    override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
        switch sampleBufferType {
        case RPSampleBufferType.video:
            // Handle video sample buffer
            break
        case RPSampleBufferType.audioApp:
            // Handle audio sample buffer for app audio
            break
        case RPSampleBufferType.audioMic:
            // Handle audio sample buffer for mic audio
            break
        @unknown default:
            // Handle other sample buffer types
            fatalError("Unknown type of sample buffer")
        }
    }
}

1、broadcastStarted(withSetupInfo setupInfo:[String : NSObject]?)

这是录制屏幕开始的回调,这里我们通常做一些初始化的工作,比如数据处理等的初始化。

2、broadcastPaused()、broadcastResumed()、broadcastFinished()这三个方法是录制状态的变化,通常我们会把状态通知到Host app处理。

3、processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType)

终于来到了最重要的方法了,前面介绍那么多内容就是为了拿到这个数据。其中sampleBuffer是返回的数据,sampleBufferType

是数据的类型,包括三种video:视频数据、audioApp:app音频数据、audioMic:麦克风的音频数据。拿到这些数据以后可以做进一步的处理,可以将数据写入文件,也可以直接推流,也可以通过一定的方式发送到host app做进一步的处理。但是要注意ReplayKit系统给了50M内存的限制,所以直接推流需要限制视频质量。一般我们会把数据通过进程间数据传输的方式推给host app在做后续处理。

Extension和Extension通信

1、通过配置app group的方式共享文件或者UserDefault。

2、进程间通知:CFNotificationCenter,一般开启关闭等可以通过通知实现。

3、通过Socket传输,像屏幕分享这样的场景比较适合这么做。

下一篇文章将介绍TRTC的实现方案。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、iOS屏幕共享方案
    • iOS 8 和以前
      • iOS 9
        • iOS 10
          • iOS 11
          相关产品与服务
          云直播
          云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档