注册

Android -- 投屏


本文从Android开发者的角度出发,介绍投屏的方式、常见的一些投屏方案及应用,最后详细介绍适合在Android手机上应用的一套方案:DLNA。



1. 投屏方式



  • 按照投屏后,展示端的数据来源,可以划分成两种主要的方式:推送投屏(Screencasting)镜像投屏(ScreenMirroring)
  • 通过一个表格看看两者的区别
    推送投屏镜像投屏
    数据源发送端向展示端发送url,此后由展示端从服务器获取媒体数据。展示端从发送端获取数据,实时展示发送端画面。
    优缺点投屏后,手机使用不受限制,可以离开当前页面进行其他活动。但部分资源如文本等可能无法投屏。实时展示手机画面,可以突破资源使用限制。但是手机不能离开当前页面。
    使用场景投屏多为音视频资源,主要应用在娱乐场景。如爱奇艺视频投屏等app内置投屏。因不受资源限制,可以进行ppt展示等,主要应用在办公场景。如mac镜像等。



2. 投屏方案



  • 2.1 Airplay

    • Airplay是Apple推出的无线显示标准,因此其应用主要局限于Apple的生态之中。国内也有电视厂商实现了对Airplay的破解,使得Apple设备可以投屏到安卓电视上。
    • 支持推送投屏和镜像投屏。


  • 2.2 DLNA

    • DLNA(Digital Living Network Alliance)是Sony于2003年发起的非营利性标准化组织,旨在制定在局域网内部进行多媒体文件及其信息共享的通信协议标准。DLNA的应用范围比较广泛,涵盖数字媒体设备、数字电视、车载娱乐等领域。大部分App内置投屏就是用的这个方案。
    • 支持推送投屏。


  • 2.3 Miracast

    • Miracast是2012年首次由WiFi Alliance发布,其底层采用了WiFi Direct技术(点对点无线技术),因此不需要通过路由器,可以直接在两个设备之间建立P2P连接。目前对Miracast支持最好的生态就是MircoSoft的Windows系统了。
    • 支持镜像投屏。


  • 2.4 Chromecast

    • Google推出了ChromecastChromecast是一款插在电视机HDMI接口上的无线设备,内置WIFI,可以通过WIFI与其他设备连接以及访问外网,类似一个迷你机顶盒。为了推广Chromecast,Google还专门推出GoogleCastSDK帮助APP开发者整合Chromecast的推送功能。不过GoogleCastSDK依赖于Google服务,在国内受到限制。
    • 支持推送投屏。


  • 2.5 乐播投屏

    • 乐播投屏是一套投屏技术方案,据官网称市面上90%的电视已采用乐播乐联协议,App开发者只需要接入乐播发送端SDK,即可同时支持AirplayDLNA乐联(lelink)等协议,兼容程度较高。但从2022年5月30日起,乐播投屏停止对旧版SDK的维护,新版SDK需要收费,按投屏日活进行收费。
    • 详细内容可上官网查看:乐播



3. DLNA详解


DLNA(Digital Living Network Alliance)是一个组织并不是一个协议,这个组织定义了一套由基础协议组成的标准,所以常用DLNA指代投屏的一种实现方案。


DLNA是目前大部分电视机支持的投屏方案,不需要收费且有一些成熟的开源框架支持开发者接入,支持的投屏方式为推送投屏,满足App投屏的需要。下面从几个角度详细介绍DLNA



  • 3.1 核心协议 DLNA依赖UPnP协议来完成发现设备、描述设备、控制设备;而UPnP协议依赖于SSDP协议来完成发现设备。下面简单了解下这两个协议。

    • UPnP
      UPnP是一种网络协议,其全称为“通用即插即用协议”(Universal Plug and Play)。它是一种基于TCP/IP协议栈的协议。它的主要目的是让网络中的不同设备能够自动发现和连接其他设备,从而实现网络设备间的通信和协作。

      UPnP的应用场景包括打印共享、音视频传输、远程控制等,适用于各种不同类型的网络设备,包括计算机、路由器、打印机、摄像头、音频设备等。


      UPnP的核心是定义了一系列标准化的协议和接口,包括设备发现服务描述设备控制等,让支持协议的设备能够自动发现和连接其他设备。


    • SSDP
      SSDP是一种基于UDP协议的网络协议,全称为“简单服务发现协议”(Simple Service Discovery Protocol)。它的主要目的是让网络中的设备能够自动发现和连接其他设备,从而实现设备间的通信和协作。

      SSDP适用于各种不同类型的网络设备,应用场景包括UPnP、AirPlay等。


      SSDP的核心是通过广播消息来实现设备的发现和服务的注册。




  • 3.2 核心角色 利用DLNA的体系,我们可以连接不同的网络设备(下面简称CP(Control Point))。在不同CP间进行数据传输、展示,这个过程中就分化出不同的角色:发送控制端DMC、接收端DMR、数据存储服务端DMS

    • DMRDigital Media Render 顾名思义就是渲染展示媒体数据的一端,比如我们的电视机。
    • DMSDigital Media Server 用于保存音视频文件的存储服务器,属于比较范的一个概念。
    • DMCDigital Media Controller 用于发现和控制的中间设备,发现局域网中存在的DMR,然后把DMS上的资源推送到DMR上进行播放。

    如果要把手机上的照片、视频文件推动到局域网内的电视上播放出来,手机就承担了DMS+DMC的角色,而电视则是一个DMR设备;


    而如果要在手机上控制电视播放B站的视频,手机就是DMC的角色,而电视就是DMR设备。


  • 3.3 投屏的主要步骤 了解核心协议、核心角色后,我们接下来以投屏为例,从DMC的角度出发,看看DMC如何发现、控制DMR,完成投屏。

    • 发现设备 当一个新的CP加入一个局域网时,为了获取当前网段里都有哪些智能设备,CP需要遵循SSDP向默认多播IP和端口发送获取信息的请求。请求的格式如下:
      M-SEARCH * HTTP/1.1

      MX: 1 //最大时间间隔数

      ST: upnp:rootdevice //搜索的设备类型

      MAN: "ssdp:discover"

      User-Agent: iOS 10.2.1 product/version

      Connection: close

      Host: 239.255.255.250 //多播地址

      如果请求成功则返回如下信息:


      HTTP/1.1 200 OK

      Cache-control: max-age=1800

      Date: Thu, 16 Feb 2017 09:09:45 GMT

      LOCATION: http://10.2.9.152:49152/TxMediaRenderer_desc.xml //URL for UPnP description for device

      ... 省略不重要的信息

      ST: upnp:rootdevice //device type

      其中LOCATION代表一个xml文件的链接,这个文件详细描述了当前局域网内CP的信息。


      至此投屏的第一步完成,新加入的CP可以发现其他CP


    • 描述设备 在上一步中,我们得到了一个xml链接,xml文件的内容如下:
      <root xmlns="urn:schemas-upnp-org:device-1-0" xmlns:dlna="urn:schemas-dlna-org:device-1-0" configId="499354">
      ...
      <device>
      <deviceType>urn:schemas-upnp-org:device:MediaRenderer:1</deviceType>
      <friendlyName>卧室的创维盒子Q+</friendlyName>
      ...
      <dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMR-1.50</dlna:X_DLNADOC>
      <serviceList>
      <service>
      <serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType>
      <serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
      <SCPDURL>/AVTransport/9c443d47158b-dmr/scpd.xml</SCPDURL>
      ...
      </service>
      ...
      </serviceList>
      </device>
      <device>
      ...
      </device>
      </root>


      • device device描述了一个CP的信息,每个device对应局域网内的一个CPdevice下的deviceType描述了当前CP的类型,MediaRenderer代表当前CP可以作为DMR用于展示媒体资源。
      • service service描述了当前CP支持的服务,一般会有多个。serviceSCPDURL指向另外一个xml文件,这个文件描述了当前service下支持的操作,如暂停、播放、快进等。

      至此投屏的第二步完成,我们获取到CP的详细描述,包括设备的类型、支持的服务等。


    • 控制设备 在上一步中,我们得到了SCPDURL这个xml链接,xml文件的内容如下:
      <scpd xmlns="urn:schemas-upnp-org:service-1-0">
      ...
      <actionList>
      <action>
      <name>SetAVTransportURI</name>
      <argumentList>
      <argument>
      <name>InstanceID</name>
      <direction>in</direction>
      <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
      </argument>
      <argument>
      <name>CurrentURI</name>
      <direction>in</direction>
      <relatedStateVariable>AVTransportURI</relatedStateVariable>
      </argument>
      <argument>
      <name>CurrentURIMetaData</name>
      <direction>in</direction>
      <relatedStateVariable>AVTransportURIMetaData</relatedStateVariable>
      </argument>
      </action>
      ...
      </scpd>


      • action 每个action代表一个操作,actionargument代表当前操作支持的参数。如上面的SetAVTransportURI就是设置媒体的url。

      执行这些action,需要按要求发起请求,请求的格式可以参考基于DLNA的移动端网络视频投屏技术初探


      至此投屏的第三步完成,我们知道目标CP支持哪些操作,利用这些操作便可以完成我们的投屏及控制。这个过程中发起投屏的CP便是DMC,展示媒体资源的CP便是DMS




  • 3.4 相关开源框架 前面我们了解了DLNA的原理,DLNA涉及的协议还是比较复杂的,人为的处理这些请求和响应,是比较麻烦的。所以社区中也有一些基于DLNA的第三方框架可供我们使用,如:

    • Platinum 是基于UPnPC++框架。
    • cling 是基于UPnPjava框架,对UPnP进行了简单的封装,不支持纯ipv6的网络。
    • cybergarage-upnp 是基于UPnPjava框架,对UPnP进行了简单的封装,不过代码结构不如cling且存在getAction方法返回一直为空的问题,需要自己把jar包拉下来,然后修改其中的代码。
    • DLNA-Cast 这个是目前发现比较完善的框架,是对cling的进一步封装,使用体验更好,目前还有在更新迭代,推荐使用。


  • 3.5 安全性问题




注意:DLNA基于UPnP,需要进行组内广播。如果某WIFI环境下一直搜不到设备,可能是WIFI不支持广播,可以切换WIFI环境再尝试。



参考文章



作者:小白鸽本鸽
来源:juejin.cn/post/7272566178446884923

0 个评论

要回复文章请先登录注册