zoukankan      html  css  js  c++  java
  • iOS中的投屏方案:

    iOS中的投屏方案:

    1, ReplayKit

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

    2, Airplay

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

    乐联协议支持三种协议:

    一是苹果原生自带的airplay,

    二是应用内的DLNA推送协议

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

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

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

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

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

    image

    image

     

     

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

    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];
    }
  • 相关阅读:
    Android中的内部类引起的内存泄露
    Android的消息机制: Message/MessageQueue/Handler/Looper
    ArrayList/Vector的原理、线程安全和迭代Fail-Fast
    JVM中的Stack和Frame
    JVM中的垃圾收集算法和Heap分区简记
    无锁编程以及CAS
    简述Java内存模型的由来、概念及语义
    MQTT协议简记
    RabbitMQ的工作队列和路由
    RabbitMQ 入门
  • 原文地址:https://www.cnblogs.com/liuxiaokun/p/12684361.html
Copyright © 2011-2022 走看看