导读:
本文集主要讲的是,dlna的投屏底层的原理,以及一步步的教你实现,对网络图片/视频或者本地的图片/视频的投屏到电视盒子上面(demo里面用的是电信的悦me盒子)
PS由于第一次接触投屏,我只讲我自己的理解,以及自己项目里面的所使用的功能模块,如有理解不到位的,可以一起交流学习下。
主要参考:
- 基于DLNA的移动端网络视频投屏技术初探
- UPnP的介绍和理解
- upnp中文文档
- iOS DLNA投屏功能了解一下
说明:
对于投屏功能,本文主要是利用的iOS DLNA投屏功能了解一下,里的框架,感谢作者的源码。
我是根据作者的代码,新增了一些实际需要的方法,以及实现了可讲本地图片、视频投影到盒子上面。
具体的代码见gitHubDemo里面的具体的包括实现都有具体的实现
我们从upnp中文文档,可大致可得出下面的流程
1.寻址
2.发现
3.描述
4.控制、事件、展示
下面我结合悦me盒子来做具体的描述
1.寻址:设备通过寻址来获得一个网络地址 (具体的说明见upnp中文文档)
这是设备和路由完成的
2.发现
当设备已经有自己的ip地址(步骤1),那么怎么样才能获取到设备呢?
我们可以通过udp请求,来喊话
发现设备:搜索请求消息字符串
NSData * sendData = [[self getSearchString] dataUsingEncoding:NSUTF8StringEncoding];
[_udpSocket sendData:sendData toHost:ssdpAddres port:ssdpPort withTimeout:-1 tag:1];
其中:getSearchString为:
[NSString stringWithFormat:
@"M-SEARCH * HTTP/1.1\r\nHOST: %@:%d\r\nMAN: \"ssdp:discover\"\r\nMX: 3\r\nST: %@\r\nUSER-AGENT: iOS UPnP/1.1 mccree/1.0\r\n\r\n",
ssdpAddres,
ssdpPort,
serviceType_AVTransport];
-----
ssdpAddres --> @"239.255.255.250";
ssdpPort --> 1900;
serviceType_AVTransport -->@"urn:schemas-upnp-org:service:AVTransport:1";
通过upd来发送消息,此时在同一个局域网的设备,会收到该消息,然后返回自己的设备信息,下面是悦me盒子返回的示例
HTTP/1.1 200 OK
Location: http://192.168.124.43:1266/
Cache-Control: max-age=1800
Server: UPnP/1.0 DLNADOC/1.50 Platinum/1.0.4.2
EXT:
USN: uuid:skyworth&208B3756FFED&192.168.124.43::urn:schemas-upnp-org:service:AVTransport:1
ST: urn:schemas-upnp-org:service:AVTransport:1
Date: Thu, 24 Jan 2019 02:38:18 GMT
3.描述 我们发现了设备,看第2步只会返回一些基本的信息,我们还需要去获取设备的详细的信息
我们通过向步骤2拿到的location发送get请求
get:http://192.168.124.43:1266/
返回信息如下:
{type:1 name:root xml:"
1
0
urn:schemas-upnp-org:device:MediaRenderer:1
YuemeTV
GeniusGitHub
https://github.com/geniusgithub
GeniusGitHub AV Media Renderer Device
Genius Software
https://github.com/geniusgithub
20130520
uuid:skyworth&208B3756FFED&192.168.124.43
DMR-1.50
urn:schemas-upnp-org:service:AVTransport:1
urn:upnp-org:serviceId:AVTransport
/AVTransport/skyworth&208B3756FFED&192.168.124.43/scpd.xml
/AVTransport/skyworth&208B3756FFED&192.168.124.43/control.xml
/AVTransport/skyworth&208B3756FFED&192.168.124.43/event.xml
urn:schemas-upnp-org:service:ConnectionManager:1
urn:upnp-org:serviceId:ConnectionManager
/ConnectionManager/skyworth&208B3756FFED&192.168.124.43/scpd.xml
/ConnectionManager/skyworth&208B3756FFED&192.168.124.43/control.xml
/ConnectionManager/skyworth&208B3756FFED&192.168.124.43/event.xml
urn:schemas-upnp-org:service:RenderingControl:1
urn:upnp-org:serviceId:RenderingControl
/RenderingControl/skyworth&208B3756FFED&192.168.124.43/scpd.xml
/RenderingControl/skyworth&208B3756FFED&192.168.124.43/control.xml
/RenderingControl/skyworth&208B3756FFED&192.168.124.43/event.xml
"}
这个格式很清晰地描述了设备的详细信息,比如设备的名字:YuemeTV,设备类型是媒体渲染播放器、制造商相关信息、UUID、以及它提供的服务列表,每个服务都有serviceType, serviceId, SCPDURL, controlURL和eventSubURL等
比如:serviceType为urn:schemas-upnp-org:service:AVTransport:1,表示这个服务提供的是音视频传输服务,版本号是1
4.接下来:我们怎么使用这些服务呢?
SCPDURL这个字段的内容就是提供的使用路径
将:前面拿到的设备 ip和端口 以及SCPDURL字段的内容,拼接成url即可
以 /AVTransport/skyworth&208B3756FFED&192.168.124.43/scpd.xml为例
发送请求:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
1
0
GetCurrentTransportActions
InstanceID
in
A_ARG_TYPE_InstanceID
Actions
out
CurrentTransportActions
GetDeviceCapabilities
InstanceID
in
A_ARG_TYPE_InstanceID
PlayMedia
out
PossiblePlaybackStorageMedia
RecMedia
out
PossibleRecordStorageMedia
RecQualityModes
out
PossibleRecordQualityModes
GetMediaInfo
InstanceID
in
A_ARG_TYPE_InstanceID
NrTracks
out
NumberOfTracks
MediaDuration
out
CurrentMediaDuration
CurrentURI
out
AVTransportURI
CurrentURIMetaData
out
AVTransportURIMetaData
NextURI
out
NextAVTransportURI
NextURIMetaData
out
NextAVTransportURIMetaData
PlayMedium
out
PlaybackStorageMedium
RecordMedium
out
RecordStorageMedium
WriteStatus
out
RecordMediumWriteStatus
GetPositionInfo
InstanceID
in
A_ARG_TYPE_InstanceID
Track
out
CurrentTrack
TrackDuration
out
CurrentTrackDuration
TrackMetaData
out
CurrentTrackMetaData
TrackURI
out
CurrentTrackURI
RelTime
out
RelativeTimePosition
AbsTime
out
AbsoluteTimePosition
RelCount
out
RelativeCounterPosition
AbsCount
out
AbsoluteCounterPosition
GetTransportInfo
InstanceID
in
A_ARG_TYPE_InstanceID
CurrentTransportState
out
TransportState
CurrentTransportStatus
out
TransportStatus
CurrentSpeed
out
TransportPlaySpeed
GetTransportSettings
InstanceID
in
A_ARG_TYPE_InstanceID
PlayMode
out
CurrentPlayMode
RecQualityMode
out
CurrentRecordQualityMode
Next
InstanceID
in
A_ARG_TYPE_InstanceID
Pause
InstanceID
in
A_ARG_TYPE_InstanceID
Play
InstanceID
in
A_ARG_TYPE_InstanceID
Speed
in
TransportPlaySpeed
Previous
InstanceID
in
A_ARG_TYPE_InstanceID
Seek
InstanceID
in
A_ARG_TYPE_InstanceID
Unit
in
A_ARG_TYPE_SeekMode
Target
in
A_ARG_TYPE_SeekTarget
SetAVTransportURI
InstanceID
in
A_ARG_TYPE_InstanceID
CurrentURI
in
AVTransportURI
CurrentURIMetaData
in
AVTransportURIMetaData
SetPlayMode
InstanceID
in
A_ARG_TYPE_InstanceID
NewPlayMode
in
CurrentPlayMode
Stop
InstanceID
in
A_ARG_TYPE_InstanceID
CurrentPlayMode
string
NORMAL
NORMAL
REPEAT_ONE
REPEAT_ALL
SHUFFLE
SHUFFLE_NOREPEAT
RecordStorageMedium
string
NOT_IMPLEMENTED
LastChange
string
RelativeTimePosition
string
CurrentTrackURI
string
CurrentTrackDuration
string
CurrentRecordQualityMode
string
NOT_IMPLEMENTED
CurrentMediaDuration
string
AbsoluteCounterPosition
i4
RelativeCounterPosition
i4
A_ARG_TYPE_InstanceID
ui4
AVTransportURI
string
TransportState
string
STOPPED
PAUSED_PLAYBACK
PLAYING
TRANSITIONING
NO_MEDIA_PRESENT
CurrentTrackMetaData
string
NextAVTransportURI
string
PossibleRecordQualityModes
string
NOT_IMPLEMENTED
CurrentTrack
ui4
0
65535
1
AbsoluteTimePosition
string
NextAVTransportURIMetaData
string
PlaybackStorageMedium
string
NONE
UNKNOWN
CD-DA
HDD
NETWORK
CurrentTransportActions
string
RecordMediumWriteStatus
string
NOT_IMPLEMENTED
PossiblePlaybackStorageMedia
string
NONE
UNKNOWN
CD-DA
HDD
NETWORK
AVTransportURIMetaData
string
NumberOfTracks
ui4
0
65535
A_ARG_TYPE_SeekMode
string
REL_TIME
TRACK_NR
A_ARG_TYPE_SeekTarget
string
PossibleRecordStorageMedia
string
NOT_IMPLEMENTED
TransportStatus
string
OK
ERROR_OCCURRED
TransportPlaySpeed
string
1
该服务提供了一个actionList即动作列表,一个服务会包含一个或多个功能请求动作,如actionList下这个SetAVTransportURI,顾名思义,这个请求的功能是将一个音视频资源的URI发送给渲染端。一个动作(Action)就好比一个API请求,你还需要传递一些要求的参数,这时就会用到该Action后面argumentList里规定的一些Argument。比如根据第一个参数
5.控制服务controlurl具体的信息
同理4
This XML file does not appear to have any style information associated with it. The document tree is shown below.
1
0
GetMute
InstanceID
in
A_ARG_TYPE_InstanceID
Channel
in
A_ARG_TYPE_Channel
CurrentMute
out
Mute
GetVolume
InstanceID
in
A_ARG_TYPE_InstanceID
Channel
in
A_ARG_TYPE_Channel
CurrentVolume
out
Volume
GetVolumeDB
InstanceID
in
A_ARG_TYPE_InstanceID
Channel
in
A_ARG_TYPE_Channel
CurrentVolume
out
VolumeDB
GetVolumeDBRange
InstanceID
in
A_ARG_TYPE_InstanceID
Channel
in
A_ARG_TYPE_Channel
MinValue
out
VolumeDB
MaxValue
out
VolumeDB
ListPresets
InstanceID
in
A_ARG_TYPE_InstanceID
CurrentPresetNameList
out
PresetNameList
SelectPreset
InstanceID
in
A_ARG_TYPE_InstanceID
PresetName
in
A_ARG_TYPE_PresetName
SetMute
InstanceID
in
A_ARG_TYPE_InstanceID
Channel
in
A_ARG_TYPE_Channel
DesiredMute
in
Mute
SetVolume
InstanceID
in
A_ARG_TYPE_InstanceID
Channel
in
A_ARG_TYPE_Channel
DesiredVolume
in
Volume
LastChange
string
A_ARG_TYPE_Channel
string
Master
A_ARG_TYPE_InstanceID
ui4
Volume
ui2
0
100
1
Mute
boolean
PresetNameList
string
FactoryDefaults
A_ARG_TYPE_PresetName
string
FactoryDefaults
VolumeDB
i2
-32767
32767
里面包含了:设置音量的动作指令:SetVolume、快退进Seek、获取音量GetVolume等等
下面具体怎么控制的呢?详见 DLNA(二)
友情链接:
- gitHub_DLNA
- DLNA(二)
- DLNA(三)