前言
目前已知的iOS中的投屏方案有如下几种:
- ReplyKit
- Airplay
- 乐播投屏
1.ReplayKit
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];
}