iOS中的投屏方案

董花蜂
2023-12-01

前言

目前已知的iOS中的投屏方案有如下几种:

  • ReplyKit
  • Airplay
  • 乐播投屏

1.ReplayKit

录屏直播ReplayKit Live与广播UI /上传扩展

iOS9中引入了ReplayKit, 让开发者有了一定的获取屏幕数据的能力. 并在iOS10和iOS11中继续扩展了ReplayKit的能力. 但还是有很大的限制, 比如在使用ReplayKit的api时只能录制当前应用的应用, 无法在应用进入后台之后继续录屏. 如果使用系统级别的屏幕录制,又无法获得每一帧的数据,只能获得最后录取的单个视频. 这样对第三方的开发有了非常大的限制.

2.Airplay

Airplay是苹果提供的一种多屏互动技术, 可以将音频照片,视频, 屏幕从iOS设备或者Mac电脑上投射到支持airplay接受的设备上,如Apple TV。这样可以将小屏映射到大屏,可以无线音乐,可以图片分享等等. 但是Airplay属于苹果私有协议方案,设备间的协商与传输过程都进行了加密处理,并不能用于其他平台中。我们已经完整的逆向了Airplay的全部协议栈,并破解了其加密方案,可以提供跨平台Airplay接收方案。这样可以方便实现跨平台的多屏共享。

3.乐播投屏 - 乐联协议

乐联协议支持三种协议:

  • 一是苹果原生自带的airplay,

  • 二是应用内的DLNA推送协议

  • 三是乐播自已研发的私有协议-“乐联”。

1·在安卓手机上,乐播用的是自己的私有协议,让安卓手机上实现跟airplay一样优越的镜像及推送功能。

2·乐联协议采用纯软件解决方案,厂商与用户都无需加购硬件。乐联协议独有直播流投屏技术,是一家能够将手机在线直播,实时无线投屏的方案商。

3·目前已经有7000万块的智能大屏出厂预装了乐播投屏的接收技术。因此无论从哪个视频APP发送的投屏请求,都能被电视大屏全格式接收。

4·支持全流媒体格式投屏,原来DLNA无法投屏电视格式的问题,也游刃而解。独自开发支持礼物流投屏,弹幕流投屏。

iOS AirPlay 投屏

苹果投屏功能主要基于 AirPlay,可以隔空播放音视频和图片。苹果原生的 AirPlay 有发送端接收端之分,分别为以下设备

  • 发送端:iPhone iPad iPod touch Mac
  • 接收端:Apple TV

按照常规的使用方法,只能投到 Apple TV 上面。

虽然 AirPlay 传输协议是苹果私有的,不过很多厂商逆向破解了 AirPlay 传输协议,所以只要国内的各种安卓电视盒子安装了对应的接收软件,也能够接收 iPhone 的投屏。

AirPlay 使用的时候有几种使用模式,在 iPhone 上目前主要分为两种模式:

  • Mirror device's screen (屏幕镜像)
  • AirPlay video (隔空播放音视频)

Mirror device’s screen

屏幕镜像模式是一种全局的操作,在手机的控制面板开启。一般来说,在该模式下,手机上显示什么,TV 上就显示什么,直接将手机内容展示到 TV 的显示器上面。

虽然这种模式叫镜像模式,但是,其实在这种模式下,APP 内部可以写代码检测是否开启了镜像模式,可以针对 Apple TV 的屏幕写一屏新的 UI,也就是手机和 TV 的显示屏展示内容可以不同,相当于外接了一个屏幕,展示新的内容。通过这种方法,可以把手机页面作为一个遥控器,真正展示内容可以放到 TV 的屏幕。

在使用镜像模式的时候,如果手机锁屏,TV 端也看不到任何内容了。也就是说,在这种模式下,手机必须一直是常亮的。个人认为这种模式比较适合用来做操作演示,不太适合用来播放视频。

镜像方式开启方法:https://support.apple.com/zh-cn/HT204289#mirroriOS

AirPlay video

隔空播放的方式其实是在嵌入在某个 APP 内部的,在 APP 内部进行操作之后,可以隔空将音视频和图片投送到 TV 上播放。

这种方式就像是把一个文件推送到 TV 端,然后用 TV 的屏幕进行播放,例如:

腾讯视频 APP 投视频 、得到 APP 投音频、 系统相册投图片 ;该方式需要 APP 开发者在软件内部写一些代码来支持投屏,比较适合单个视频的播放。比如用腾讯视频看电影的时候就可以把视频投到 TV 上去播放,这个时候手机是可以直接锁屏的,投放的效果也非常不错。

但是这种方式仅仅是对文件的隔空播放,尚未发现可以自定义 TV 端播放页面的 API。

隔空播放开启方法:https://support.apple.com/zh-cn/HT204289#iOS

Apple TV 之外的设备接收 AirPlay

一般来说只能用 Apple TV 作为接收端,不过有很多第三方破解了苹果的传输协议,所以很多平台通过安装一个接收端软件来模仿 Apple TV 接收 iPhone 等设备投送的数据。

以下为一些第三方接收软件

AirServer

该软件有 PC 和 Mac 版本的接收端,安装后可以直接接收 iPhone 投送的数据。如果想将 Mac 作为 AirPlay 接收端进行投屏,该软件是首选。

产品官网:https://www.airserver.com

手游直播是直播行业中非常重要的一个垂直领域. 手游直播与其他移动直播相比主要是画面的来源不同, 手游直播其实是一种录屏技术. 游戏玩家在玩游戏的同时将画面内容实时地分享展示给其他观众, 在配上玩家自己的语音, 能够给观众带来比较有趣的观看体验. 手游直播与PC端游戏直播相比主要是设备的计算能力不同。 PC游戏直播有OBS等强大的第三方直播软件, 加上PC强劲有富余的计算能力, 使得PC游戏直播的门槛相对较低。 手游直播中由于Apple对个人隐私和安全性的重视, iOS手游直播相对于Android手游直播的难度又大了很多。

现有iOS录屏方案分析

为了解决iOS手游直播中视频数据采集的难题, 主要存在以下三种方案:

  • 通过私有API获取系统的IOSurface 这种方法效率比较高, 但是从iOS9 开始, 这个私有API的漏洞就被Apple堵上了, 新系统中无法使用;

  • Airplay Screen Mirroring. Airplay 是 Apple 提供的一种远程播放技术, 可以将iPhone、iPod touch、iPad及Mac上的音频,照片,ppt, 视频和系统界面镜像等内容传送到同一局域网中支持Airplay的设备(如:音箱、Apple TV)中播放. 其中Airplay Screen Mirroring 就是用于屏幕投影的功能,有iOS系统自身将屏幕内容进行采集压缩,通过网络投屏的其他设备上. 但 Airplay 是Apple的私有协议组, 并且为了安全考虑, 传输过程中音视频数据都是用Apple私有的Fairplay加密的, 因此要想获得这些数据, 必须破解Airplay的协议和并且破解Fairplay加密方式。 另外出于个人隐私保护和影视版权保护的考虑,Apple不允许录屏功能的软件上架 AppStore, 即使成功上架, 不久也会被强制下架。

  • ReplayKit
    ReplayKit ,Apple 注意到了广大用户对手游直播的呼声, 从iOS 9开始提供了ReplayKit, 给了用户主动对外分享屏幕内容的能力. 对与Replaykit, Apple在不断的增强, iOS9的时候还只能把特定App的画面录制成MP4的片段, 到iOS10 能够获取特定App的原始图像和声音, 到iOS11, 能够从系统级启动录制, 获得所有APP包括桌面的画面. 但是Replaykit是以APP扩展的方式存在的, 真正接受到画面, 进行压缩发送的部分, 并不是一个完整的应用程序, 而是一个在后台运行的扩展. Airplay则可以作为一个在后台运行的App, 相对来说, 完整App的稳定性和可控程度在现阶段可能要优于App扩展。

视频投屏是什么原理:

视频投屏的通道有DLNA投屏airplay投屏Lelink(乐播投屏协议)这三大协议通道。有了这三个协议通道。就好像蓝牙一样,手机和电视通过互相配对,建立了一个通道,连接之后,手机就可以不断地把视频地址发射给电视。从而电视播放视频。完成投屏。

iOS DLNA投屏 MRDLNA

Pod安装MRDLNA

一. 设置代理搜索设备

self.dlnaManager = [MRDLNA sharedMRDLNAManager];
self.dlnaManager.delegate = self;

调用开始搜索后就会搜索整个局域网中支持投视频的设备

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self.dlnaManager startSearch];
}

二.发现设备后的回调

发现设备后在代理中可以拿到

- (void)searchDLNAResult:(NSArray *)devicesArray{
    NSLog(@"发现设备");
    self.deviceArr = devicesArray;
    [self.dlnaTable reloadData];
}

//devicesArray中拿到的是CLUPnPDevice类型的对象复制代码 Demo中将搜索页面和投屏控制页面分开来的,所以在搜索页面搜索到设备后就把目标设备和播放Url设置给了dlnaManager

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    NSString *testUrl = @"http://223.110.239.40:6060/cntvmobile/vod/p_cntvmobile00000000000020150518/m_cntvmobile00000000000659727681";
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    if (indexPath.row < self.deviceArr.count) {
        CLUPnPDevice *model = self.deviceArr[indexPath.row];
        self.dlnaManager.device = model;
        self.dlnaManager.playUrl = testUrl;
        DLNAControlVC *controlVC = [[DLNAControlVC alloc] init];
        controlVC.model = model;
        [self.navigationController pushViewController:controlVC animated:YES];
    }
}

三.投屏

- (void)viewDidLoad {
    [super viewDidLoad];
    self.dlnaManager = [MRDLNA sharedMRDLNAManager];
    [self.dlnaManager startDLNA];
}

四.投屏后的播放控制

/**
 退出
 */
- (IBAction)closeAction:(id)sender {
    [self.dlnaManager endDLNA];
}
/**
 播放/暂停
 */
- (IBAction)playOrPause:(id)sender {
    if (_isPlaying) {
        [self.dlnaManager dlnaPause];
    }else{
        [self.dlnaManager dlnaPlay];
    }
    _isPlaying = !_isPlaying;
}
/**
 进度条seek单位是秒
 */
- (IBAction)seekChanged:(UISlider *)sender{
    NSInteger sec = sender.value * 60 * 60;
    NSLog(@"播放进度条======>: %zd",sec);
    [self.dlnaManager seekChanged:sec];
}
/**
 音量volume建议传0-100之间字符串
 */
- (IBAction)volumeChange:(UISlider *)sender {
    NSString *vol = [NSString stringWithFormat:@"%.f",sender.value * 100];
    NSLog(@"音量========>: %@",vol);
    [self.dlnaManager volumeChanged:vol];
}
/**
 切集
 */
- (IBAction)playNext:(id)sender {
    NSString *testVideo = @"http://wvideo.spriteapp.cn/video/2016/0328/56f8ec01d9bfe_wpd.mp4";
    [self.dlnaManager playTheURL:testVideo];
}
 类似资料: