『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 18083|回复: 101

[进阶教程] 小爱音箱播放会员音乐-NAS本地音乐篇

  [复制链接]

78

主题

537

帖子

3534

积分

论坛元老

Rank: 8Rank: 8

积分
3534
金钱
2997
HASS币
0
发表于 2023-9-22 08:45:46 | 显示全部楼层 |阅读模式
本帖最后由 silas3082 于 2023-9-22 08:52 编辑

之前写了一个帖子ha播放小爱音箱的会员歌曲 - 『HomeAssistant』综合讨论区 - 『瀚思彼岸』» 智能家居技术论坛 - Powered by Discuz! (hassbian.com),实现了小爱音箱如果遇到会员歌曲,会用云音乐替换,然后再在其他蓝牙设备或接入ha的设备上播放;

这次受小爱音箱播放NAS音乐 - 『HomeAssistant』综合讨论区 - 『瀚思彼岸』» 智能家居技术论坛 - Powered by Discuz! (hassbian.com)大佬启发,小爱可以播放URL的音乐了,大佬没有给出具体实现教程,经过一番努力,终于实现了适合我的小爱音箱替换会员歌曲。

把我的实现方法分享给大家:

1.把nas音乐通过SMB挂载到alist里边;如图1

2.在nodered里边用Python脚本抓取音乐名字,并保存在本地的一个txt中。

我是把nr的root文件夹映射了出来,放在nas-docker-nr2-root文件夹中,如图2

Python代码如下:
import requests
import json

# 请求URL和负载数据
url = "http://192.168.1.222:5244/api/fs/list"
payload = {
    "path": "/nas music/无损音乐一千多首",
    "password": "",
    "page": 1,
    "per_page": 0,
    "refresh": False
}

# 请求头信息,包括JWT令牌
headers = {
    "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InNpbGFzMzA4MiIsImV4cCI6MTY5NTQ2NTkxNSwibmJmIjoxNjk1MjkzMTE1LCJpYXQiOjE2OTUyOTMxMTV9.MA6rTdWcLXZyTE5WQ8YVGd9rCUcro18DVBisfXQT74U"
}

# 发送POST请求,包括请求头
response = requests.post(url, json=payload, headers=headers)





# 检查响应状态码
if response.status_code == 200:
    try:
        # 解析响应数据
        data = response.json()

        # 调试输出响应数据
        print("响应数据:")
        print(json.dumps(data, indent=4))

        # 获取歌曲名字
        song_names = [item["name"] for item in data["data"]["content"]]

        # 保存歌曲名字到本地文件
        with open("/root/song_names2.txt", "w", encoding="utf-8") as file:
            for song_name in song_names:
                file.write(song_name + "\n")

        print("歌曲名字已保存到 song_names.txt 文件中。")
    except json.JSONDecodeError:
        print("响应数据格式不正确,无法解析 JSON 数据。")
else:
    print(f"请求失败,状态码: {response.status_code}")


3.在nr中实现查询音乐,并播放功能;
流程如下:
[
    {
        "id": "4f81332edf8333b1",
        "type": "tab",
        "label": "流程 2",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "d97c77314c7ff79d",
        "type": "template",
        "z": "4f81332edf8333b1",
        "name": "python 脚本",
        "field": "payload",
        "fieldType": "msg",
        "format": "python",
        "syntax": "mustache",
        "template": "# 导入必要的模块\nimport os\n\n# 输入要查找的歌名\n\nsearch_term = '{{payload}}'\n# 读取歌曲列表文件的路径\nfile_path = r'/root/song_names2.txt'\n\n# 初始化一个变量,用于标记是否找到了匹配的歌曲\nfound = False\n\n# 打开文件并逐行查找\ntry:\n    with open(file_path, 'r', encoding='utf-8') as file:\n        for line in file:\n            # 去除行尾的换行符\n            line = line.strip()\n            # 如果歌名包含搜索词,则打印歌名并标记为找到\n            if search_term in line:\n                print(line)\n                found = True\n                break\n\n\n    # 如果没有找到匹配的歌曲,打印提示\n    if not found:\n        print(\"没有找到此歌曲\")\nexcept FileNotFoundError:\n    print(f\"文件 {file_path} 未找到\")\nexcept Exception as e:\n    print(f\"发生错误: {str(e)}\")",
        "output": "str",
        "x": 470,
        "y": 260,
        "wires": [
            [
                "10e1ba4d6c365922"
            ]
        ]
    },
    {
        "id": "c518e9de96ef7557",
        "type": "inject",
        "z": "4f81332edf8333b1",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "橄榄树",
        "payloadType": "str",
        "x": 250,
        "y": 260,
        "wires": [
            [
                "d97c77314c7ff79d"
            ]
        ]
    },
    {
        "id": "9ca67af87259793b",
        "type": "exec",
        "z": "4f81332edf8333b1",
        "command": "python3 /root/查询歌曲.py",
        "addpay": "payload",
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 990,
        "y": 240,
        "wires": [
            [
                "9de76d91021f45ea"
            ],
            [],
            []
        ]
    },
    {
        "id": "10e1ba4d6c365922",
        "type": "file",
        "z": "4f81332edf8333b1",
        "name": "存储在root目录下",
        "filename": "/root/查询歌曲.py",
        "filenameType": "str",
        "appendNewline": true,
        "createDir": true,
        "overwriteFile": "true",
        "encoding": "none",
        "x": 730,
        "y": 240,
        "wires": [
            [
                "9ca67af87259793b"
            ]
        ]
    },
    {
        "id": "0f9dcb2d32fd6cb6",
        "type": "comment",
        "z": "4f81332edf8333b1",
        "name": "小爱播放本地音乐",
        "info": "1.写入python文件\n2.构建文件的程序",
        "x": 250,
        "y": 200,
        "wires": []
    },
    {
        "id": "9de76d91021f45ea",
        "type": "function",
        "z": "4f81332edf8333b1",
        "name": "function 8",
        "func": "var a;\nvar b;\n\n\na = \"http://192.168.1.222:5244/d/nas music/无损音乐一千多首/\" + msg.payload\nb =encodeURI(a);\nmsg.payload = b.slice(0, -3);\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1220,
        "y": 220,
        "wires": [
            [
                "c8c6b93753f9b725"
            ]
        ]
    },
    {
        "id": "c8c6b93753f9b725",
        "type": "api-call-service",
        "z": "4f81332edf8333b1",
        "name": "",
        "server": "598f8fe7bc05621b",
        "version": 5,
        "debugenabled": false,
        "domain": "media_player",
        "service": "play_media",
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "media_player.xiaomi_lx5a_7d9b_play_control"
        ],
        "data": "{\t   \"media_content_id\":msg.payload,\t   \"media_content_type\":\"music\",\t   \"announce\":\"true\"\t}",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 1450,
        "y": 220,
        "wires": [
            []
        ]
    },
    {
        "id": "2348d19c1c188aa8",
        "type": "inject",
        "z": "4f81332edf8333b1",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 1130,
        "y": 340,
        "wires": [
            [
                "c8c6b93753f9b725"
            ]
        ]
    },
    {
        "id": "f5a8cc39be8e35dd",
        "type": "switch",
        "z": "4f81332edf8333b1",
        "name": "判断是否为绿钻歌曲",
        "property": "data.new_state.attributes.answers[0].tts.text",
        "propertyType": "msg",
        "rules": [
            {
                "t": "cont",
                "v": "试听版",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 480,
        "y": 480,
        "wires": [
            [
                "4aa98c8c6e97b309"
            ],
            []
        ]
    },
    {
        "id": "4aa98c8c6e97b309",
        "type": "split",
        "z": "4f81332edf8333b1",
        "name": "",
        "splt": "播放",
        "spltType": "str",
        "arraySplt": "1",
        "arraySpltType": "len",
        "stream": false,
        "addname": "",
        "x": 670,
        "y": 440,
        "wires": [
            [
                "1732a0343b314274"
            ]
        ]
    },
    {
        "id": "1732a0343b314274",
        "type": "join",
        "z": "4f81332edf8333b1",
        "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": 810,
        "y": 440,
        "wires": [
            [
                "fb20b7b5ad6597c9"
            ]
        ]
    },
    {
        "id": "fb20b7b5ad6597c9",
        "type": "function",
        "z": "4f81332edf8333b1",
        "name": "",
        "func": "msg.payload = msg.payload[1]\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 950,
        "y": 440,
        "wires": [
            [
                "d97c77314c7ff79d"
            ]
        ]
    },
    {
        "id": "a05f73afffedf255",
        "type": "server-state-changed",
        "z": "4f81332edf8333b1",
        "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": 220,
        "y": 400,
        "wires": [
            [
                "f5a8cc39be8e35dd"
            ]
        ]
    },
    {
        "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
    }
]
其中包含一个查找歌曲的Python代码,如图3


这样就实现了,当小爱有会员歌曲时,会从本地查找,直接通过小爱音箱播放出来。当然这个适合我,并不能完全照抄,有些地方需要结合自己的配置修改。


screenshot20230922.png
screenshot20230922 (1).png
screenshot20230922 (2).png

评分

参与人数 5金钱 +37 收起 理由
gthh62d + 2 高手,这是高手!
隔壁的王叔叔 + 10 感谢分享。
q873139535 + 5 大神666!
DDDear + 10 大神666!
sorrypqa + 10 大神666!

查看全部评分

回复

使用道具 举报

51

主题

1340

帖子

5600

积分

论坛DIY达人

积分
5600
金钱
4260
HASS币
20
发表于 2023-9-22 09:49:46 | 显示全部楼层
高手全是玩代码,佩服佩服!!
回复

使用道具 举报

0

主题

608

帖子

2516

积分

金牌会员

Rank: 6Rank: 6

积分
2516
金钱
1908
HASS币
0
发表于 2023-9-22 10:53:28 | 显示全部楼层
太牛逼了
回复

使用道具 举报

16

主题

131

帖子

748

积分

高级会员

Rank: 4

积分
748
金钱
617
HASS币
0
发表于 2023-9-22 14:13:46 | 显示全部楼层
卡在了第一步,怎么获取无损音乐一千多首
回复

使用道具 举报

78

主题

537

帖子

3534

积分

论坛元老

Rank: 8Rank: 8

积分
3534
金钱
2997
HASS币
0
 楼主| 发表于 2023-9-22 14:24:39 | 显示全部楼层
jfmm 发表于 2023-9-22 14:13
卡在了第一步,怎么获取无损音乐一千多首

具体卡在哪个地方
回复

使用道具 举报

16

主题

131

帖子

748

积分

高级会员

Rank: 4

积分
748
金钱
617
HASS币
0
发表于 2023-9-22 14:33:22 | 显示全部楼层
silas3082 发表于 2023-9-22 14:24
具体卡在哪个地方

哪里可以下载无损的版权音乐
回复

使用道具 举报

78

主题

537

帖子

3534

积分

论坛元老

Rank: 8Rank: 8

积分
3534
金钱
2997
HASS币
0
 楼主| 发表于 2023-9-22 14:39:07 | 显示全部楼层
jfmm 发表于 2023-9-22 14:33
哪里可以下载无损的版权音乐

这个........不要被这种小事阻挡了前进的脚步
回复

使用道具 举报

10

主题

1332

帖子

4252

积分

论坛元老

Rank: 8Rank: 8

积分
4252
金钱
2920
HASS币
0
发表于 2023-9-22 14:49:47 | 显示全部楼层
能抓音乐就能抓电影了,岂不是前面帖子的电视轮播什么的都可以搞定啦,点赞
回复

使用道具 举报

78

主题

537

帖子

3534

积分

论坛元老

Rank: 8Rank: 8

积分
3534
金钱
2997
HASS币
0
 楼主| 发表于 2023-9-22 15:06:29 | 显示全部楼层
隔壁的王叔叔 发表于 2023-9-22 14:49
能抓音乐就能抓电影了,岂不是前面帖子的电视轮播什么的都可以搞定啦,点赞 ...

好建议,我之前用nr写了一个电视轮播的流,可以参考。

我觉的是不是可以用对小爱音箱说我想看“”XXXX”,小爱获取连接然后通过dlna设备投屏,不知道能不能实现
回复

使用道具 举报

10

主题

1332

帖子

4252

积分

论坛元老

Rank: 8Rank: 8

积分
4252
金钱
2920
HASS币
0
发表于 2023-9-22 15:55:36 | 显示全部楼层
本帖最后由 隔壁的王叔叔 于 2023-9-22 15:56 编辑
silas3082 发表于 2023-9-22 15:06
好建议,我之前用nr写了一个电视轮播的流,可以参考。

我觉的是不是可以用对小爱音箱说我想看“”XXXX” ...

可以的,就是这个思路,先获得链接地址,存起来,就像上面的音乐,然后检测到我想看某某电影的关键词,然后去地址里查询,取出来,然后通过dlna传给电视,原来的瓶颈在于如何获取alist里的地址,但现在你上面的爬虫都写完了,障碍就清除了嘛。期待你的成品,我来抄作业。哈哈哈哈,算盘打的可响了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-11-24 22:33 , Processed in 0.074906 second(s), 35 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表