|
本帖最后由 airhog 于 2018-9-5 20:05 编辑
应用篇力求简洁,易上手。
学习篇算是应用篇的幕后和补充,怎么罗嗦怎么来,事无巨细多留下点线索,说不定以后就用上了,说不定就有人需要呢。
“微改虫子DLNA,让小度上岗(应用篇)”
https://bbs.hassbian.com/thread-4734-1-1.html
预警,又臭又长,请直接跳到“总结分析”看答案。
起因:
因为DLNA才买了小度,结果没用起来,虫子的DLNA找不到设备,丢在一边吃灰。
无奈又开始折腾蓝牙。
初步搞定了蓝牙(插预告:免安装,即插即用)。
蓝牙已经可以对付着用了,开始收拾DLNA。
初试失败:
新版HA内置了DLNA,看官方文档,貌似很简单的样子。
https://www.home-assistant.io/components/media_player.dlna_dmr/
media_player:
- platform: dlna_dmr
url: http://192.168.0.10:9197/dmr
但是无论将ip改为HA的,还是DLNA设备的,都不行。
意外收获:
继续看文档,按照指引来到MiniDLNA官网。
接着用“MiniDLNA”关键字好一番搜索,看起来都是建DLNA媒体服务的,不是想要的。
再看文档,来到https://www.dlna.org/官网,想下个 DLNA Test Tools,还要认证购买,罢了。
先搜“DLNA Test”,再换“DLNA scan”,像是找着点北了。
意外收获
https://github.com/StevenLooman/home-assistant-dlna-dmr
discovery:
enable:
- dlna_dmr
修改配置文件configuration.yaml,将discovery,media_player配置如上即可使用内置的DLNA播放器了。
但是小度DLNA还是没戏,和虫子的一样无法找到设备。
详见:
新版(0.76-0.77)HA之DLNA配置方法
https://bbs.hassbian.com/thread-4713-1-1.html
继续探索:
为了小度,继续努力,搜到了nanodlna,很不错的一个小程序,文档写的一点不偷懒。
https://github.com/gabrielmagno/nano-dlna
进入docker容器终端
docker exec -it Hass /bin/bash
先更新 pip
pip install --upgrade pip
再安装
pip install nanodlna
查找DLNA接收端
nanodlna list
结果如下,找到了安装DLNA的手机,没有小度。
Device 1:
{
"location": "http://192.168.2.23:58347/upnp/dev/kx_cast_media_renderer643a2c79-f1f9-44b8-8e2d-7c1266e4aa47/desc",
"hostname": "192.168.2.23",
"friendly_name": "KXCast_HUAWEI C8950D",
"action_url": "http://192.168.2.23:58347/upnp/dev/kx_cast_media_renderer643
a2c79-f1f9-44b8-8e2d-7c1266e4aa47/svc/upnp-org/AVTransport/action",
"st": "urn:schemas-upnp-org:service:AVTransport:1"
}
想要放弃:
反复多次运行,还是没有找到小度。
查看相关源码,和虫子的很相似。
再搜,看到了huex在百度留下的足迹
“发现小度dlna UDN uuid格式并非是8-4-4-4-12。导致python下无法发现,请问是否可以修复”
http://xiaodu.baidu.com/forum/topic/show/264113
https://developer.baidu.com/forum/topic/show/264113
百度没有回应,好无望,想放弃。
看见希望:
但是想想群晖的AudioStations能正常发现设备,控制设备,没有道理啊。
再战,调整关键字“小度+dlna+格式”,找到下文
https://bbs.hassbian.com/thread-4516-1-1.html
文中tang5275提到HA的ssdp.py,能搜到。据此关键字找到官网。
https://github.com/home-assistan ... er/netdisco/ssdp.py
下载,直接在docker容器终端中测试
python ssdp.py
root@homeassistant-home-assistant:/usr/src/app# python /config/programs/ssdp.py
Scanning SSDP..
<UPNPEntry http://192.168.2.102:8000/6076c6 ... 5df6271d/device.xml - ssdp:all>,
<UPNPEntry http://192.168.2.102:8000/6076c6 ... 5df6271d/device.xml - upnp:rootdevice>,
<UPNPEntry http://192.168.2.226:50655/upnp/ ... a-50673a56bb4c/desc - upnp:rootdevice>,
......
果然找到了小度和手机(换了一个),兴奋。
用之前的nanodlna测试播放
nanodlna play /config/music/dingding.mp3 -d "http://192.168.2.226:50655/"
失败,地址必须写全
nanodlna play /config/music/dingding.mp3 -d "http://192.168.2.226:50655/upnp/dev/kx_cast_media_renderer6aa1f7c7-08e7-48e4-aaca-50673a56bb4c/desc"
ok,听到了熟悉的声音。
按照tang5275文
https://bbs.hassbian.com/thread-4700-1-1.html
复制http://192.168.2.102:8000/6076c6 ... 5df6271d/device.xml地址配置并重启,结果还是没有小度的身影。
停下想了想,nanodlna播放测试证实小度可用,问题只是设备未能被发现。
又把三个py的源码看了一遍,没找到头绪。
放大招,关键字“dlna+发现+设备”,果然在茫茫文海之中找到此文
“基于DLNA实现iOS,Android投屏:SSDP发现设备”
https://eliyar.biz/DLNA_with_iOS ... _Device_Using_SSDP/
突击学习:
文章不错,学习一下。
SSDP:Simple Sever Discovery Protocol,简单服务发现协议。(顾名思义)
SSDP有两种发现方式:主动通知和搜索响应方式。(就是它了)
保留的多播地址:239.255.255.250:1900 (很眼熟)
服务类型:UPnP_AVTransport1 urn:schemas-upnp-org:service:AVTransport:1 (有印象)
多播搜索消息:
M-SEARCH * HTTP/1.1 // 请求头 不可改变
MAN: "ssdp:discover" // 设置协议查询的类型,必须是:ssdp:discover
MX: 5 // 设置设备响应最长等待时间,设备响应在0和这个值之间随机选择响应延迟的值。这样可以为控制点响应平衡网络负载。
HOST: 239.255.255.250:1900 // 设置为协议保留多播地址和端口,必须是:239.255.255.250:1900(IPv4)或FF0x::C(IPv6
ST: upnp:rootdevice // 设置服务查询的目标,它必须是下面的类型:
// ssdp:all 搜索所有设备和服务
// upnp:rootdevice 仅搜索网络中的根设备
如果需要实现投屏,则设备类型 ST 为 urn:schemas-upnp-org:service:AVTransport:1
再一次看到“AVTransport”,眼神确认,没跑了。
问题解决:
回想刚才用ssdp.py搜到了一堆的设备,有小度,但是偏偏没看到这个关键字“AVTransport”。
将源码
# Devices only, some devices will only respond to this query
ST_ROOTDEVICE = "upnp:rootdevice"
修改为
ST_ROOTDEVICE = "urn:schemas-upnp-org:service:AVTransport:1"
python ssdp.py
试一试,如我所愿,再次找到了小度。
打开nanodlna的devices.py源码
找到def get_devices(timeout=3.0)下的
try:
info = [a.split(":", 1)
for a in data.decode("UTF-8").split("\r\n")[1:]]
device = dict([(a[0].strip().lower(), a[1].strip())
for a in info if len(a) >= 2])
devices.append(device)
print(device) 插入此行以观察发现的设备
except Exception:
pass
devices_urls = [dev["location"]
for dev in devices if "AVTransport" in dev["st"]] *划重点*
devices = [register_device(location_url) for location_url in devices_urls]
根据上面划重点语句判定,小度其实已被发现,只是又被抛弃掉了。
让我们在源码中插入print(device) 观察一下。
python devices.py
猜对了,又一次发现了小度。
接下来就简单了,对HA动手脚没把握,nanodlna的代码和虫子的很相似。
对虫子下黑手,将"ST: ssdp:all"改为
"ST: urn:schemas-upnp-org:service:AVTransport:1"
一切顺利,见到了久违的小度,听到了熟悉的dingding声。
总结分析:
What?Why?How?
搜索过程,原有程序
对着网络吼一声(发送多播搜索),DLNA设备都吱一声。
A设备
吱(我是根设备:rootdevice),我还是投屏设备哦(AVTransport)
小度
吱(我是根设备:rootdevice)
因为小度很高冷就吱了一声,啥也没多说。结果我们抓到了它(print(device)),又放了它(上面*划重点*的语句)
改后的程序
对着网络吼一声,投屏设备都吱一声。
A设备
吱(投屏设备:AVTransport)
小度
吱(投屏设备:AVTransport)
好了,这次小度跑不了了。
感谢你耐心看完。
致敬:
https://github.com/charleyzhu/HomeAssistant_Components
https://github.com/gabrielmagno/nano-dlna
https://eliyar.biz/DLNA_with_iOS ... _Device_Using_SSDP/
https://eliyar.biz/DLNA_with_iOS_Android/
https://github.com/home-assistan ... er/netdisco/ssdp.py
https://github.com/StevenLooman/home-assistant-dlna-dmr
https://blog.csdn.net/linearhit/article/details/40736003
http://peirenlei.iteye.com/blog/1695516
https://www.jianshu.com/p/fbc7c700cdb5
http://liuweiqiang.win/%E7%BD%91 ... /29/DLNA-Cling.html
https://bbs.hassbian.com/thread-4516-2-1.html
http://xiaodu.baidu.com/forum/topic/show/264113
|
评分
-
查看全部评分
|