Created
February 8, 2023 01:56
-
-
Save leafney/f14edffbc05902b75df7ddb4926b2777 to your computer and use it in GitHub Desktop.
Cloud music player implemented by Node-Red and HomeAssistant
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[{"id":"0d1d65f7ba1553ca","type":"tab","label":"云音乐播放器","disabled":false,"info":"","env":[]},{"id":"33759b693780be63","type":"inject","z":"0d1d65f7ba1553ca","name":"手动启动/停止","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":250,"y":240,"wires":[["dbc207429b6f6dc0"]]},{"id":"e9211b0583476c26","type":"function","z":"0d1d65f7ba1553ca","name":"设置音乐类别","func":"// 发起请求\nmsg.headers = {\n \"Content-Type\": \"application/json\"\n};\n\n// 随机类别 热歌榜|新歌榜|飙升榜|抖音榜|电音榜\nvar arr = ['热歌榜','热歌榜','新歌榜','飙升榜','抖音榜']\n\n// 随机获取一项\nvar random_type = arr[Math.floor(Math.random() * arr.length)];\n\nmsg.payload = {\n // \"sort\":\"热歌榜\",\n // 'mid':1, // 歌单ID\n \"sort\":random_type,\n \"format\":\"json\"\n}\n\n// 显示类别\nnode.status({fill:\"blue\",shape:\"dot\",text:random_type});\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":760,"y":340,"wires":[["722779911f306151"]]},{"id":"722779911f306151","type":"http request","z":"0d1d65f7ba1553ca","name":"请求音乐信息","method":"GET","ret":"obj","paytoqs":"query","url":"https://api.uomg.com/api/rand.music","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":760,"y":400,"wires":[["73636bcf6853a1f4"]]},{"id":"18b5f3a109361730","type":"api-call-service","z":"0d1d65f7ba1553ca","name":"播放音乐","server":"3cd209f0e02bc9b8","version":5,"debugenabled":false,"domain":"media_player","service":"play_media","areaId":[],"deviceId":[],"entityId":["media_player.mopidy"],"data":"msg.payload","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":980,"y":620,"wires":[["33472c39781a68a1","c838eb7ba78b9a48"]]},{"id":"68fa5a5589d0413e","type":"function","z":"0d1d65f7ba1553ca","name":"解析音乐信息","func":"// 解析\nvar data = msg.data_info;\nvar url = msg.responseUrl;\n\n// 显示播放歌曲名称\nnode.status({fill:\"green\",shape:\"dot\",text:`${data.name}-${data.artistsname}`});\n\n// 设置播放器参数\nmsg.payload={\n \"media_content_id\":url,\n \"media_content_type\":\"music\",\n \"announce\":\"true\"\n}\n\n// 当前歌曲正常播放标识\nflow.set('cloud_music_played',true);\n\n// 等待一下,防止冲突\nsetTimeout(function(){\n // 设置启动标识 (用于切歌模式下,停止播放)\n global.set('cloud_music_start',true,'file');\n},2000);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":760,"y":560,"wires":[["18b5f3a109361730","e5bd51033ff6c35e"]]},{"id":"55c7de619e4bcbf3","type":"trigger-state","z":"0d1d65f7ba1553ca","name":"上一曲播放完毕","server":"3cd209f0e02bc9b8","version":2,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"media_player.mopidy","entityidfiltertype":"exact","debugenabled":false,"constraints":[{"targetType":"this_entity","targetValue":"","propertyType":"previous_state","propertyValue":"old_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"playing"},{"targetType":"this_entity","targetValue":"","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"off"}],"inputs":0,"outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","enableInput":false,"x":260,"y":500,"wires":[["f6b40acd0cd79ecd"],[]]},{"id":"858eab131136b164","type":"api-call-service","z":"0d1d65f7ba1553ca","name":"停止播放","server":"3cd209f0e02bc9b8","version":5,"debugenabled":false,"domain":"media_player","service":"media_stop","areaId":[],"deviceId":[],"entityId":["media_player.mopidy"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":980,"y":300,"wires":[["3be1104b41134ac0"]]},{"id":"c6b61ba2983f9cf0","type":"inject","z":"0d1d65f7ba1553ca","name":"手动切歌","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"str","x":240,"y":360,"wires":[["bba82e0449fc619d"]]},{"id":"f6b40acd0cd79ecd","type":"delay","z":"0d1d65f7ba1553ca","name":"限制频率","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"10","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":480,"y":460,"wires":[["35238c82ee9ad38b"]]},{"id":"7027b91f3df00544","type":"server-state-changed","z":"0d1d65f7ba1553ca","name":"双击启动/停止","server":"3cd209f0e02bc9b8","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.0x54ef4410004c084d_action","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"button_6_double","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[],"x":250,"y":280,"wires":[["dbc207429b6f6dc0"],[]]},{"id":"8560476076d9ec2e","type":"server-state-changed","z":"0d1d65f7ba1553ca","name":"单击切歌","server":"3cd209f0e02bc9b8","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.0x54ef4410004c084d_action","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"button_6_single","halt_if_type":"str","halt_if_compare":"is","outputs":2,"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":240,"y":400,"wires":[["bba82e0449fc619d"],[]]},{"id":"67ed4b93f820eb6b","type":"switch","z":"0d1d65f7ba1553ca","name":"校验音乐链接","property":"responseUrl","propertyType":"msg","rules":[{"t":"regex","v":"^http(.*)?music\\.163\\.com([/#]*)?404$","vt":"str","case":true},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":760,"y":520,"wires":[["ed37f750b32c53d5"],["68fa5a5589d0413e"]]},{"id":"14bb74c3871d2a0d","type":"link out","z":"0d1d65f7ba1553ca","name":"link out 6","mode":"link","links":["6eb4074c79524195"],"x":935,"y":500,"wires":[]},{"id":"6eb4074c79524195","type":"link in","z":"0d1d65f7ba1553ca","name":"link in 5","links":["14bb74c3871d2a0d"],"x":325,"y":460,"wires":[["f6b40acd0cd79ecd"]]},{"id":"73636bcf6853a1f4","type":"function","z":"0d1d65f7ba1553ca","name":"提取音乐链接","func":"// 临时存储音乐信息\nmsg.data_info = msg.payload.data;\n\n// 返回的音乐链接\nvar url = msg.payload.data.url;\n\n// 有些音乐链接请求后返回404,需要先校验一下链接是否有效\n\n// var url = \"http://music.163.com/song/media/outer/url?id=29774171\";\n// var url = \"https://music.163.com/song/media/outer/url?id=1992712131\";\n\nmsg.url = url;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":760,"y":440,"wires":[["d8434f54c95fcfb7"]]},{"id":"d8434f54c95fcfb7","type":"http request","z":"0d1d65f7ba1553ca","name":"请求音乐链接","method":"GET","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":760,"y":480,"wires":[["67ed4b93f820eb6b"]]},{"id":"33472c39781a68a1","type":"api-call-service","z":"0d1d65f7ba1553ca","name":"播放器音量 40%","server":"3cd209f0e02bc9b8","version":5,"debugenabled":false,"domain":"media_player","service":"volume_set","areaId":[],"deviceId":[],"entityId":["media_player.mopidy"],"data":"{\"volume_level\":0.4}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1000,"y":680,"wires":[[]]},{"id":"4eb44e04ca269500","type":"function","z":"0d1d65f7ba1553ca","name":"设置自动续播标识","func":"\n// 设置自动续播标识\nglobal.set('cloud_music_next',true,'file');\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":510,"y":340,"wires":[["e9211b0583476c26"]]},{"id":"70f47ee1b26c68c6","type":"function","z":"0d1d65f7ba1553ca","name":"移除云音乐播放标识","func":"\n// 移除自动续播标识\nglobal.set('cloud_music_next',undefined,'file');\n\n// 移除启动标识\nglobal.set('cloud_music_start',undefined,'file');\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":780,"y":300,"wires":[["858eab131136b164"]]},{"id":"cdb7084fb8e04e8f","type":"function","z":"0d1d65f7ba1553ca","name":"设置切歌标识","func":"\n// 手动切歌标识\nflow.set('cloud_music_cut',true);\n\n// // 设置启动标识 (用于切歌模式下,停止播放)\n// global.set('cloud_music_start',true,'file');\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":500,"y":420,"wires":[["e9211b0583476c26"]]},{"id":"e5bd51033ff6c35e","type":"delay","z":"0d1d65f7ba1553ca","name":"歌曲播放1分钟后","pauseType":"delay","timeout":"1","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"minute","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":1010,"y":540,"wires":[["627c5f4abdd8fe68"]]},{"id":"627c5f4abdd8fe68","type":"function","z":"0d1d65f7ba1553ca","name":"移除切歌标识","func":"\n// 歌曲正常播放一段时间后,移除切歌标识\nflow.set('cloud_music_cut',undefined);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1000,"y":580,"wires":[[]]},{"id":"35238c82ee9ad38b","type":"function","z":"0d1d65f7ba1553ca","name":"自动播放下一曲","func":"// 判断是否处于自动播放下一曲模式\nvar music_next = global.get('cloud_music_next','file') || false;\n\n// 判断当前播放器暂停状态是否由切歌操作触发\n// (切歌会导致播放器状态变化,从而导致触发下一曲,这里要限制)\nvar music_cut = flow.get('cloud_music_cut') || false;\n\n// 上一曲是否正常播放\nvar music_played = flow.get('cloud_music_played') || false;\n\n// 播放状态\nvar music_start = global.get('cloud_music_start','file') || false;\n\n// 当处于自动下一曲模式时,继续下一曲;\n// 切歌模式下,不触发自动下一曲;但如果播放失败,则触发下一曲\n// if(music_next && !music_cut){\n// node.send(msg);\n// }\n\n// 优化\nif(music_next){\n if(!music_cut){\n node.send(msg);\n }\n}else{\n // 非自动续播状态下,如果上一曲没有正常播放,则再播放一次\n if(!music_played){\n node.send(msg);\n }\n \n // 单曲模式下,播放完毕移除播放标识\n if (music_start){\n global.set('cloud_music_start',false,'file');\n }\n \n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":500,"y":500,"wires":[["e9211b0583476c26"]]},{"id":"d5d26d42dbaaeefe","type":"comment","z":"0d1d65f7ba1553ca","name":"当前链接无法播放,自动下一曲","info":"","x":1050,"y":420,"wires":[]},{"id":"05afa3423ece0963","type":"comment","z":"0d1d65f7ba1553ca","name":"云音乐播放器","info":"## 功能说明\n\n- 支持手动触发开启、停止、切歌操作\n- 支持自动触发,例如使用小米无线开关执行\n - 双击 开启或停止\n - 单击 切歌\n- 支持自动连播模式和单曲播放模式\n","x":250,"y":180,"wires":[]},{"id":"bba82e0449fc619d","type":"delay","z":"0d1d65f7ba1553ca","name":"限制频率","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"5","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":480,"y":380,"wires":[["cdb7084fb8e04e8f"]]},{"id":"dbc207429b6f6dc0","type":"function","z":"0d1d65f7ba1553ca","name":"启动状态","func":"\n// 判断启动状态\nvar music_start = global.get('cloud_music_start','file') || false;\n\nmusic_start = !music_start;\n\n// global.set('cloud_music_start',music_start,'file');\n\nmsg.payload = music_start;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":480,"y":260,"wires":[["8c539921f7c54d23"]]},{"id":"8c539921f7c54d23","type":"switch","z":"0d1d65f7ba1553ca","name":"判断状态","property":"payload","propertyType":"msg","rules":[{"t":"false"},{"t":"true"}],"checkall":"true","repair":false,"outputs":2,"x":480,"y":300,"wires":[["70f47ee1b26c68c6"],["4eb44e04ca269500"]]},{"id":"ed37f750b32c53d5","type":"change","z":"0d1d65f7ba1553ca","name":"标记播放失败","rules":[{"t":"set","p":"cloud_music_played","pt":"flow","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":1000,"y":460,"wires":[["14bb74c3871d2a0d","bbec98c169504538"]]},{"id":"3be1104b41134ac0","type":"debug","z":"0d1d65f7ba1553ca","name":"调试1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1130,"y":300,"wires":[]},{"id":"bbec98c169504538","type":"debug","z":"0d1d65f7ba1553ca","name":"调试2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1170,"y":460,"wires":[]},{"id":"c838eb7ba78b9a48","type":"debug","z":"0d1d65f7ba1553ca","name":"调试3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1130,"y":620,"wires":[]},{"id":"3cd209f0e02bc9b8","type":"server","name":"Home Assistant","version":5,"addon":false,"rejectUnauthorizedCerts":true,"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}] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment