情况是这样的,手机要投屏就离不开投屏服务。DLNA基本上已覆盖非苹果设备,但还无法满足国内平台厂商的特殊业务需求,所以几家大的视频网站基于DLNA做了不少升级,比如投屏后可以用遥控器选集、选清晰度,可以上报历史记录等等,这都是标准DLNA服务不支持的。那么问题来了,如果爱奇艺手机版投屏到电视机厂家预置的DLNA服务上,定制版的功能就瞎了,标准DLNA不支持这些操作。
每家的业务需求不同,让DLNA满足所有人的需求是不现实的。比较好的解决思路是谁请求谁服务,标准服务兜底。比如:爱奇艺手机版的投屏请求,由爱奇艺大屏版处理;腾讯手机版的投屏请求,由腾讯大屏版处理;没有大屏端的手机客户端的请求,系统调用预置的服务处理。简单讲就是“各回各家,各找各妈”。
如何实现呢?
协议上很简单,就是加入Prefer参数指定接收方。众所周知,DLNA是一组协议组成的协议栈,CP(Control Point)遵循SSDP(简单服务发现协议)搜索局域网中可用的设备和服务。请求的格式如下所示:
M-SEARCH * HTTP/1.1 //协议名称和版本号
MX: 1 //设备响应的最长等待时间
ST: upnp:rootdevice //搜索的设备类型,还可以是ssdp:all/uuid:device-UUID/urn:schemas-upnp-org:device:device-Type:version
MAN: "ssdp:discover" //协议查询的类型,必须是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
EXT:
LOCATION: http://190.2.9.152:42152/TxMediaRenderer_desc.xml //设备描述文件DDD的地址
Server: search target
USN: uuid:3c970e3c0c0d0000_MR::upnp:rootdevice //composite identifier for the advertisment
BOOTID.UPNP.ORG: 1487062102 //number increased each time device sends an initial announce or an update message
CONFIGID.UPNP.ORG: 499354 //number used for caching description information
SEARCHPORT.UPNP.ORG: number identifies port on which device responds to unicast M-SEARCH
ST: upnp:rootdevice //设备类型
这样,作为控制点的手机就知道了:有一台设备可以提供DLNA服务,它的IP地址和端口号是什么、在什么位置(LOCATION
)、设备ID是什么(USN
)。但它具体能提供什么服务,我们还不清楚。所以还要根据LOCATION获取DDD(Device Description Document),了解具体的服务项。后面的步骤就放下不表了。
在第一段代码的尾部加入了Prefer参数,指定希望谁来为自己提供服务。比如:
Prefer: com.gitvdemo.video //希望银河奇艺果(爱奇艺大屏版)提供投屏服务
电视机厂家的系统服务根据Prefer参数查找系统中的应用包名,把该请求丢给银河奇异果的DLNA服务去处理,没有就丢给系统默认的DLNA服务处理。当然,如果某个手机客户端的老板特别喜欢大屏爱奇艺提供的增强投屏服务的话,也可以指定爱奇艺处理。
DLNA协议栈的其它部分可以完全不做任何修改,向下兼容。
DLNA-Prefer对内容平台方的好处:
- 可定制的、更丰富的投屏交互功能;
- 更可靠的投屏服务(只信自己);
DLNA-Prefer对大屏设备(电视机、盒子、投影)厂商的好处:
- 更好的用户投屏体验;
- 更多的广告库存;
DLNA-Prefer对播控平台的好处:更安全的内容播控。
我也需要这样的东西,同求!