## 用于控制 MPD 服务器的 Node-RED 节点

[English README](README.md)

本项目用于控制 Music Player Daemon (MPD) 服务器，并接收来自服务器的状态更新（如当前播放的歌曲）。

我一直在使用 [node-red-contrib-mpd](https://flows.nodered.org/node/node-red-contrib-mpd)，该模块基于 mpd 模块，已有多年未更新。在使用过程中，连接经常中断。因此，我基于 mpd2 模块开发了本项目，以提高与音乐播放守护进程连接的稳定性。

---

### v1.1.0 更新：
- 兼容一些mpc命令

#### 您可以使用以下命令：

* msg.payload = "play" - 开始播放
* msg.payload = "stop" - 停止播放
* msg.payload = "toggle" - 播放/暂停切换（等同于 pause）
* msg.payload = "pause" - 暂停播放
* msg.payload = "next" - 播放下一首
* msg.payload = "prev" - 播放上一首
* msg.payload = "add example.mp3" - 添加本地音乐文件
* msg.payload = "add https://www.example.com/music.mp3" - 添加远程音乐 URL
* msg.payload = "setvol 80" - 设置音量（旧格式）
* msg.payload = "volume 80" - 设置音量80%
* msg.payload = "volume +5" - 音量增加5%
* msg.payload = "volume -10" - 音量减少10%
* msg.payload = "clear" - 清空播放列表
* msg.payload = "playlistinfo" - 查看播放列表信息
* msg.payload = "status" - 查看当前状态
* msg.payload = "currentsong" - 查看当前歌曲（等同于 current）
* msg.payload = "current" - 查看当前歌曲
* msg.payload = "ls" - 列出音乐库（等同于 lsinfo）
* msg.payload = "listall" - 递归列出所有歌曲
* msg.payload = "save myplaylist" - 保存播放列表
* msg.payload = "load myplaylist" - 加载播放列表
* msg.payload = "random on" - 开启随机播放
* msg.payload = "random off" - 关闭随机播放
* msg.payload = "repeat on" - 开启全部循环
* msg.payload = "repeat off" - 关闭循环
* msg.payload = "repeat 1" - 开启单曲循环
* msg.payload = "update" - 更新数据库
* ...

#### 如果有任何问题，可以在 [GitHub](https://github.com/iso-lib/node-red-contrib-mpd2) 上提交 issue

##### 示例

```
[
    {
        "id": "ba9d6a9211149b26",
        "type": "mpd2",
        "z": "4195b3120a14282d",
        "name": "",
        "server": "d6bc7cd732aa815f",
        "command": "",
        "x": 890,
        "y": 360,
        "wires": [
            [
                "76f07c969648eee2"
            ],
            [
                "5dc1add0e131ee24"
            ]
        ]
    },
    {
        "id": "b452ec03c66fb2f2",
        "type": "inject",
        "z": "4195b3120a14282d",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 330,
        "y": 440,
        "wires": [
            [
                "8806e7b76ac48b34"
            ]
        ]
    },
    {
        "id": "8806e7b76ac48b34",
        "type": "function",
        "z": "4195b3120a14282d",
        "name": "play",
        "func": "msg.payload = \"play\";\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 490,
        "y": 440,
        "wires": [
            [
                "ba9d6a9211149b26"
            ]
        ]
    },
    {
        "id": "679dca6c9a185e9f",
        "type": "inject",
        "z": "4195b3120a14282d",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 330,
        "y": 480,
        "wires": [
            [
                "9977815c72d2df4a"
            ]
        ]
    },
    {
        "id": "9977815c72d2df4a",
        "type": "function",
        "z": "4195b3120a14282d",
        "name": "stop",
        "func": "msg.payload = \"stop\";\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 490,
        "y": 480,
        "wires": [
            [
                "ba9d6a9211149b26"
            ]
        ]
    },
    {
        "id": "415b5546f995205c",
        "type": "inject",
        "z": "4195b3120a14282d",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 330,
        "y": 360,
        "wires": [
            [
                "666784dcc4a35689"
            ]
        ]
    },
    {
        "id": "666784dcc4a35689",
        "type": "function",
        "z": "4195b3120a14282d",
        "name": "添加本地音乐文件",
        "func": "//本地音乐文件需要在 MPD 服务器上设置音乐目录。配置文件通常为 /etc/mpd.conf\n\nmsg.payload = \"add example.mp3\";\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 530,
        "y": 360,
        "wires": [
            [
                "ba9d6a9211149b26"
            ]
        ]
    },
    {
        "id": "09344c63bc5a0e8f",
        "type": "inject",
        "z": "4195b3120a14282d",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 330,
        "y": 400,
        "wires": [
            [
                "5779c5f62841dbac"
            ]
        ]
    },
    {
        "id": "5779c5f62841dbac",
        "type": "function",
        "z": "4195b3120a14282d",
        "name": "添加远程音乐 URL",
        "func": "msg.payload = \"add https://www.example.com/music.mp3\";\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 540,
        "y": 400,
        "wires": [
            [
                "ba9d6a9211149b26"
            ]
        ]
    },
    {
        "id": "f45ce712545d2ee9",
        "type": "inject",
        "z": "4195b3120a14282d",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 330,
        "y": 520,
        "wires": [
            [
                "86be6fd6ebfd6de6"
            ]
        ]
    },
    {
        "id": "86be6fd6ebfd6de6",
        "type": "function",
        "z": "4195b3120a14282d",
        "name": "设置音量",
        "func": "msg.payload = \"setvol 80\";\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 510,
        "y": 520,
        "wires": [
            [
                "ba9d6a9211149b26"
            ]
        ]
    },
    {
        "id": "b45cfb66185feed2",
        "type": "inject",
        "z": "4195b3120a14282d",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 330,
        "y": 560,
        "wires": [
            [
                "83f988e68149f680"
            ]
        ]
    },
    {
        "id": "83f988e68149f680",
        "type": "function",
        "z": "4195b3120a14282d",
        "name": "查看播放列表",
        "func": "msg.payload = \"playlistinfo\";\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 510,
        "y": 560,
        "wires": [
            [
                "ba9d6a9211149b26"
            ]
        ]
    },
    {
        "id": "104c1fbc14ac9398",
        "type": "inject",
        "z": "4195b3120a14282d",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 330,
        "y": 600,
        "wires": [
            [
                "a93683d5197e546c"
            ]
        ]
    },
    {
        "id": "a93683d5197e546c",
        "type": "function",
        "z": "4195b3120a14282d",
        "name": "清空播放列表",
        "func": "msg.payload = \"clear\";\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 510,
        "y": 600,
        "wires": [
            [
                "ba9d6a9211149b26"
            ]
        ]
    },
    {
        "id": "38b4156b009987da",
        "type": "inject",
        "z": "4195b3120a14282d",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 330,
        "y": 640,
        "wires": [
            [
                "69cc7549ec7b231b"
            ]
        ]
    },
    {
        "id": "69cc7549ec7b231b",
        "type": "function",
        "z": "4195b3120a14282d",
        "name": "状态",
        "func": "msg.payload = \"status\";\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 490,
        "y": 640,
        "wires": [
            [
                "ba9d6a9211149b26"
            ]
        ]
    },
    {
        "id": "76f07c969648eee2",
        "type": "debug",
        "z": "4195b3120a14282d",
        "name": "信息",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1050,
        "y": 280,
        "wires": []
    },
    {
        "id": "5dc1add0e131ee24",
        "type": "debug",
        "z": "4195b3120a14282d",
        "name": "事件",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1050,
        "y": 420,
        "wires": []
    },
    {
        "id": "ccd26845a405f846",
        "type": "template",
        "z": "4195b3120a14282d",
        "name": "一次性输入",
        "field": "payload",
        "fieldType": "msg",
        "format": "handlebars",
        "syntax": "mustache",
        "template": "command_list_begin\nstop\nclear\nsetvol 60\nadd \"example.mp3\"\nplay\ncommand_list_end",
        "output": "str",
        "x": 520,
        "y": 200,
        "wires": [
            [
                "ba9d6a9211149b26"
            ]
        ]
    },
    {
        "id": "8c28f97dd43b4318",
        "type": "inject",
        "z": "4195b3120a14282d",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 320,
        "y": 200,
        "wires": [
            [
                "ccd26845a405f846"
            ]
        ]
    },
    {
        "id": "2fcc6b59540f9b99",
        "type": "function",
        "z": "4195b3120a14282d",
        "name": "当前歌曲",
        "func": "msg.payload = \"currentsong\";\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 510,
        "y": 680,
        "wires": [
            [
                "ba9d6a9211149b26"
            ]
        ]
    },
    {
        "id": "c1302ac7d00749a4",
        "type": "inject",
        "z": "4195b3120a14282d",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 330,
        "y": 680,
        "wires": [
            [
                "2fcc6b59540f9b99"
            ]
        ]
    },
    {
        "id": "d6bc7cd732aa815f",
        "type": "mpd2-server",
        "name": "我的 MPD 服务器",
        "host": "192.168.1.9",
        "port": "6600",
        "password": ""
    }
]
```
