本帖最后由 silas3082 于 2023-11-23 10:24 编辑
你们要的小爱同学让电视播放任意电影实现观影自有的教程来了。 首先说明,我实在群晖docker安装的homeassistant和nodered,部署在其他服务器上的可参考修改。
2.在homeassistant中将你家的电视通过dlna接入。
3.在群晖创建一个文件夹挂载 nodered的root目录。
4.群晖开启ssh,并进入nodered容器内部:
docker exec -it nodered /bin/bash
我这里以新docker部署的nr为例
安装http请求及解析需要的库:
python3 -m ensurepip --upgrade
python3 -m pip install requests
python3 -m pip install bs4
安装完就可以到nr里边操作了。
5.在nodered中,将我的流导入:并将第一步说的小雅的网址改为自己的
[
{
"id": "ce7ae6436c0af95a",
"type": "file",
"z": "5641ce060432f122",
"name": "存储在root目录下",
"filename": "/root/查询小雅电影url.py",
"filenameType": "str",
"appendNewline": true,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 430,
"y": 1740,
"wires": [
[
"6d47d72d49f59618"
]
]
},
{
"id": "6d47d72d49f59618",
"type": "exec",
"z": "5641ce060432f122",
"command": "python3 /root/查询小雅电影url.py",
"addpay": "payload",
"append": "",
"useSpawn": "false",
"timer": "",
"winHide": false,
"oldrc": false,
"name": "",
"x": 740,
"y": 1740,
"wires": [
[
"05f6b97e57de70a4",
"931f4e09ee722274"
],
[],
[]
]
},
{
"id": "1b5f9bfbd0bce847",
"type": "api-call-service",
"z": "5641ce060432f122",
"name": "主卧电视",
"server": "598f8fe7bc05621b",
"version": 5,
"debugenabled": false,
"domain": "media_player",
"service": "play_media",
"areaId": [
"wo_shi"
],
"deviceId": [],
"entityId": [
"media_player.zhu_wo_dian_shi"
],
"data": "{\t "media_content_id": msg.payload[0],\t "media_content_type":"video",\t "announce":"true"\t}",
"dataType": "jsonata",
"mergeContext": "",
"mustacheAltTags": false,
"outputProperties": [],
"queue": "none",
"x": 1680,
"y": 1700,
"wires": [
[
"6ffd3c1403904fc6"
]
]
},
{
"id": "6ffd3c1403904fc6",
"type": "debug",
"z": "5641ce060432f122",
"name": "debug 18",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1960,
"y": 1800,
"wires": []
},
{
"id": "2e0618eb53503ab3",
"type": "debug",
"z": "5641ce060432f122",
"name": "debug 20",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1460,
"y": 1600,
"wires": []
},
{
"id": "030138d8effd759f",
"type": "template",
"z": "5641ce060432f122",
"name": "python 脚本",
"field": "payload",
"fieldType": "msg",
"format": "python",
"syntax": "mustache",
"template": "import requests\nfrom bs4 import BeautifulSoup\n\n# 定义URL\nurl = "http://192.168.1.222:6789/search?box={{payload}}&type=video&url="\n\n# 发送GET请求获取页面内容\nresponse = requests.get(url)\n\n# 检查响应状态码\nif response.status_code == 200:\n html = response.text\n\n # 使用Beautiful Soup解析HTML\n soup = BeautifulSoup(html, 'html.parser')\n\n # 找到所有的<a>标签\n a_tags = soup.find_all('a')\n\n # 初始化路径列表,用于存储尝试的路径\n paths_to_try = [a['href'] for a in a_tags[2:]]\n\n # 用于记录是否找到匹配的文件名\n found = False\n\n # 检查列表中是否包含".mkv"或".mp4"的结果\n for path in paths_to_try:\n if ".mkv" in path or ".mp4" in path:\n # 拼接新的URL\n new_url = f"http://192.168.1.222:6789/d/{path}"\n print(new_url)\n found = True\n break\n\n if not found:\n while paths_to_try and not found:\n path = paths_to_try.pop(0) # 弹出列表中的第一个路径\n\n # 定义URL\n api_url = "http://192.168.1.222:6789/api/fs/list"\n\n # 定义请求参数\n params = {\n "path": path,\n "password": "",\n "page": 1,\n "per_page": 30,\n "refresh": False\n }\n\n # 发送POST请求获取JSON响应\n response = requests.post(api_url, json=params)\n\n # 检查响应状态码\n if response.status_code == 200:\n data = response.json()\n\n # 尝试获取content中的项目,如果出现异常则跳出当前循环\n try:\n content = data.get("data", {}).get("content")\n except AttributeError:\n # print(f"在路径 {path} 下发生异常,跳过该路径")\n continue\n\n if content is not None:\n # 查找第一个包含“.mp4”或“.mkv”的name\n found_name = None\n for item in content:\n name = item.get("name", "")\n if ".mp4" in name or ".mkv" in name:\n found_name = name\n break\n\n # 如果找到了匹配的name\n if found_name:\n # 拼接完整的网址\n full_url = f"http://192.168.1.222:6789/d/{path}/{found_name}"\n print(full_url)\n found = True\n else:\n print(f"在路径 {path} 下未找到匹配的文件名")\n else:\n print(f"JSON响应中没有'content'字段")\n else:\n print(f"无法访问指定URL: {api_url}")\n\n if not found:\n print("没有找到包含'.mp4'或'.mkv'的文件名")\nelse:\n print("无法访问指定URL")\n",
"output": "str",
"x": 210,
"y": 1760,
"wires": [
[
"ce7ae6436c0af95a"
]
]
},
{
"id": "0e62fca7ed5d9b7b",
"type": "inject",
"z": "5641ce060432f122",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "速度与激情10",
"payloadType": "str",
"x": 130,
"y": 1680,
"wires": [
[
"030138d8effd759f"
]
]
},
{
"id": "05f6b97e57de70a4",
"type": "debug",
"z": "5641ce060432f122",
"name": "debug 21",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 940,
"y": 1840,
"wires": []
},
{
"id": "561da383e0140cab",
"type": "join",
"z": "5641ce060432f122",
"name": "",
"mode": "custom",
"build": "array",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": false,
"timeout": "",
"count": "",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "",
"reduceFixup": "",
"x": 1230,
"y": 1720,
"wires": [
[
"2e0618eb53503ab3",
"081e66e145ad4ade",
"65545ddaebf3e8a4"
]
]
},
{
"id": "c3e5a779dfee461f",
"type": "split",
"z": "5641ce060432f122",
"name": "",
"splt": "\\n",
"spltType": "str",
"arraySplt": 1,
"arraySpltType": "len",
"stream": false,
"addname": "",
"x": 1130,
"y": 1780,
"wires": [
[
"561da383e0140cab"
]
]
},
{
"id": "4d24b8ce856620bf",
"type": "function",
"z": "5641ce060432f122",
"name": "function 10",
"func": "\nmsg.payload=encodeURI(msg.payload).slice(0, -3);\n\n\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1630,
"y": 1600,
"wires": [
[
"1b5f9bfbd0bce847"
]
]
},
{
"id": "ef5d923092afd21d",
"type": "comment",
"z": "5641ce060432f122",
"name": "电影url",
"info": "",
"x": 110,
"y": 1600,
"wires": []
},
{
"id": "ebde0123b4902e43",
"type": "server-state-changed",
"z": "5641ce060432f122",
"name": "小爱对话",
"server": "598f8fe7bc05621b",
"version": 4,
"exposeToHomeAssistant": false,
"haConfig": [
{
"property": "name",
"value": ""
},
{
"property": "icon",
"value": ""
}
],
"entityidfilter": "sensor.xiaomi_lx5a_7d9b_conversation",
"entityidfiltertype": "exact",
"outputinitially": false,
"state_type": "str",
"haltifstate": "",
"halt_if_type": "str",
"halt_if_compare": "is",
"outputs": 1,
"output_only_on_state_change": true,
"for": "0",
"forType": "num",
"forUnits": "minutes",
"ignorePrevStateNull": false,
"ignorePrevStateUnknown": false,
"ignorePrevStateUnavailable": false,
"ignoreCurrentStateUnknown": false,
"ignoreCurrentStateUnavailable": false,
"outputProperties": [
{
"property": "payload",
"propertyType": "msg",
"value": "",
"valueType": "entityState"
},
{
"property": "data",
"propertyType": "msg",
"value": "",
"valueType": "eventData"
},
{
"property": "topic",
"propertyType": "msg",
"value": "",
"valueType": "triggerId"
}
],
"x": 120,
"y": 2000,
"wires": [
[
"2f2c89887be9e04e"
]
]
},
{
"id": "2f2c89887be9e04e",
"type": "switch",
"z": "5641ce060432f122",
"name": "我想看",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "cont",
"v": "我想看",
"vt": "str"
},
{
"t": "else"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 310,
"y": 1980,
"wires": [
[
"b028350e4a8ff48d",
"2dc0658ed70d52dd"
],
[]
]
},
{
"id": "b028350e4a8ff48d",
"type": "split",
"z": "5641ce060432f122",
"name": "",
"splt": "想看",
"spltType": "str",
"arraySplt": "1",
"arraySpltType": "len",
"stream": false,
"addname": "",
"x": 510,
"y": 1980,
"wires": [
[
"2c27c3910bb47959"
]
]
},
{
"id": "2c27c3910bb47959",
"type": "join",
"z": "5641ce060432f122",
"name": "",
"mode": "custom",
"build": "array",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": false,
"timeout": "",
"count": "",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "",
"reduceFixup": "",
"x": 670,
"y": 1980,
"wires": [
[
"cfb73ae3d376c74a"
]
]
},
{
"id": "cfb73ae3d376c74a",
"type": "function",
"z": "5641ce060432f122",
"name": "",
"func": "msg.payload = msg.payload[1]\n\nreturn msg;",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 790,
"y": 1980,
"wires": [
[
"030138d8effd759f",
"f4f391a64858ac59"
]
]
},
{
"id": "df9356cc80c6bfb0",
"type": "inject",
"z": "5641ce060432f122",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "我想看我和我的祖国",
"payloadType": "str",
"x": 210,
"y": 2100,
"wires": [
[
"2f2c89887be9e04e"
]
]
},
{
"id": "2dc0658ed70d52dd",
"type": "xiaoai-mediaplayer",
"z": "5641ce060432f122",
"name": "",
"xiaoai": "09b787bdbe3ed75d",
"action": "pause",
"device": "",
"x": 550,
"y": 2100,
"wires": [
[],
[]
]
},
{
"id": "f23f85e17f7d3a33",
"type": "api-call-service",
"z": "5641ce060432f122",
"name": "",
"server": "598f8fe7bc05621b",
"version": 5,
"debugenabled": false,
"domain": "media_player",
"service": "play_media",
"areaId": [],
"deviceId": [],
"entityId": [
"media_player.chuang_wei_ke_ting_dian_shi_g6_7f6_dlna"
],
"data": "{\t "media_content_id": msg.payload[0],\t "media_content_type":"video",\t "announce":"true"\t}",
"dataType": "jsonata",
"mergeContext": "",
"mustacheAltTags": false,
"outputProperties": [],
"queue": "none",
"x": 1790,
"y": 1860,
"wires": [
[
"6ffd3c1403904fc6"
]
]
},
{
"id": "3798846de5c7f949",
"type": "server-state-changed",
"z": "5641ce060432f122",
"name": "电影名称",
"server": "598f8fe7bc05621b",
"version": 4,
"exposeToHomeAssistant": false,
"haConfig": [
{
"property": "name",
"value": ""
},
{
"property": "icon",
"value": ""
}
],
"entityidfilter": "input_text.dian_ying_ming_cheng",
"entityidfiltertype": "exact",
"outputinitially": false,
"state_type": "str",
"haltifstate": "",
"halt_if_type": "str",
"halt_if_compare": "is",
"outputs": 1,
"output_only_on_state_change": true,
"for": "0",
"forType": "num",
"forUnits": "minutes",
"ignorePrevStateNull": false,
"ignorePrevStateUnknown": false,
"ignorePrevStateUnavailable": false,
"ignoreCurrentStateUnknown": false,
"ignoreCurrentStateUnavailable": false,
"outputProperties": [
{
"property": "payload",
"propertyType": "msg",
"value": "",
"valueType": "entityState"
},
{
"property": "data",
"propertyType": "msg",
"value": "",
"valueType": "eventData"
},
{
"property": "topic",
"propertyType": "msg",
"value": "",
"valueType": "triggerId"
}
],
"x": 100,
"y": 1880,
"wires": [
[
"030138d8effd759f"
]
]
},
{
"id": "081e66e145ad4ade",
"type": "api-call-service",
"z": "5641ce060432f122",
"name": "",
"server": "598f8fe7bc05621b",
"version": 5,
"debugenabled": false,
"domain": "media_player",
"service": "media_stop",
"areaId": [],
"deviceId": [],
"entityId": [
"media_player.chuang_wei_ke_ting_dian_shi_g6_7f6_dlna"
],
"data": "",
"dataType": "jsonata",
"mergeContext": "",
"mustacheAltTags": false,
"outputProperties": [],
"queue": "none",
"x": 1250,
"y": 1860,
"wires": [
[]
]
},
{
"id": "e6304a814503d679",
"type": "debug",
"z": "5641ce060432f122",
"name": "debug 301",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1550,
"y": 1960,
"wires": []
},
{
"id": "2162eb85046df316",
"type": "delay",
"z": "5641ce060432f122",
"name": "",
"pauseType": "delay",
"timeout": "2",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 1640,
"y": 1780,
"wires": [
[
"f23f85e17f7d3a33"
]
]
},
{
"id": "3e5669590088e34d",
"type": "function",
"z": "5641ce060432f122",
"name": "function 17",
"func": "// 获取输入的URL\nvar originalURL = msg.payload;\n\n// 使用encodeURI函数转换URL\nvar encodedURL = encodeURI(originalURL);\n\n// 删除末尾的逗号\nvar cleanedURL = encodedURL.replace(/,+$/, '');\n\n// 将清理后的URL存储在msg.payload中\nmsg.payload = cleanedURL;\n\n// 返回msg对象以传递到下一个节点\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1470,
"y": 1840,
"wires": [
[
"2162eb85046df316",
"e6304a814503d679"
]
]
},
{
"id": "65545ddaebf3e8a4",
"type": "switch",
"z": "5641ce060432f122",
"name": "",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "cont",
"v": "%20",
"vt": "str"
},
{
"t": "else"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 1410,
"y": 1680,
"wires": [
[
"2162eb85046df316"
],
[
"3e5669590088e34d"
]
]
},
{
"id": "3a5605c9317eb24f",
"type": "api-call-service",
"z": "5641ce060432f122",
"name": "",
"server": "598f8fe7bc05621b",
"version": 5,
"debugenabled": false,
"domain": "xiaomi_miot",
"service": "intelligent_speaker",
"areaId": [],
"deviceId": [],
"entityId": [
"media_player.xiaomi_lx5a_7d9b_play_control"
],
"data": "{"text":"没有找到您所说的电影,可以去tv,box找找"}",
"dataType": "jsonata",
"mergeContext": "",
"mustacheAltTags": false,
"outputProperties": [],
"queue": "none",
"x": 1030,
"y": 1520,
"wires": [
[]
]
},
{
"id": "931f4e09ee722274",
"type": "switch",
"z": "5641ce060432f122",
"name": "",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "cont",
"v": "没有找到包含",
"vt": "str"
},
{
"t": "else"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 850,
"y": 1620,
"wires": [
[
"3a5605c9317eb24f"
],
[
"c3e5a779dfee461f",
"38da2c94e298a6f6",
"8b39e6f4e4fa8774"
]
]
},
{
"id": "1ee4cc39ad69ee40",
"type": "inject",
"z": "5641ce060432f122",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 990,
"y": 1920,
"wires": [
[
"081e66e145ad4ade"
]
]
},
{
"id": "dac6af55d7290b5e",
"type": "api-call-service",
"z": "5641ce060432f122",
"name": "",
"server": "598f8fe7bc05621b",
"version": 5,
"debugenabled": false,
"domain": "xiaomi_miot",
"service": "intelligent_speaker",
"areaId": [],
"deviceId": [],
"entityId": [
"media_player.xiaomi_lx5a_7d9b_play_control"
],
"data": "{"text":msg.name}",
"dataType": "jsonata",
"mergeContext": "",
"mustacheAltTags": false,
"outputProperties": [],
"queue": "none",
"x": 1410,
"y": 1520,
"wires": [
[]
]
},
{
"id": "38da2c94e298a6f6",
"type": "function",
"z": "5641ce060432f122",
"name": "function 18",
"func": "\n\n\nmsg.name = "正在为您播放 " + global.get("moviename")+"请稍后";\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1030,
"y": 1580,
"wires": [
[
"dac6af55d7290b5e"
]
]
},
{
"id": "f4f391a64858ac59",
"type": "function",
"z": "5641ce060432f122",
"name": "function 19",
"func": "\n\nglobal.set("moviename", msg.payload);\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 930,
"y": 2020,
"wires": [
[]
]
},
{
"id": "8b39e6f4e4fa8774",
"type": "debug",
"z": "5641ce060432f122",
"name": "debug 302",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1130,
"y": 1660,
"wires": []
},
{
"id": "598f8fe7bc05621b",
"type": "server",
"name": "Home Assistant",
"version": 5,
"addon": false,
"rejectUnauthorizedCerts": false,
"ha_boolean": "y|yes|true|on|home|open",
"connectionDelay": true,
"cacheJson": true,
"heartbeat": false,
"heartbeatInterval": "30",
"areaSelector": "friendlyName",
"deviceSelector": "friendlyName",
"entitySelector": "friendlyName",
"statusSeparator": ": ",
"statusYear": "hidden",
"statusMonth": "short",
"statusDay": "numeric",
"statusHourCycle": "default",
"statusTimeFormat": "h:m",
"enableGlobalContextStore": false
},
{
"id": "09b787bdbe3ed75d",
"type": "xiaoai-tts-configurator",
"name": ""
}
]
在nr输入一个你想看的电影,如果出现下边的url就说明成功了。恭喜你,可以随心看电影了。
如果上边的流导入有问题就直接下载附件
|