How to cast mp3 local file in nodered as HA addons

Hi @Steve-Mcl ,

Already try as per your suggestion. it still the cast status node is play but have no any sound in speaker. and few minutes came error load media

image

but can play test.mp3 by accessing https://x.x.x.x:1880/endpoint/audio for now

image

So i think you are mixing up a few things. for example, your inject is sending a https URL and an endpoint of node-red:1880/audio/test.mp3 but your endpoint is clearly node-red:1880/endpoint/audio etc.

For the sake of getting this resolved, I'll jump ahead to the final solution.

follow the COMMENTS and adjust the names to suit.

chrome_N99xajgEYM

[{"id":"f31a598d.9fd2c8","type":"function","z":"01a5fce4debb676d","name":"Set base path","func":"//restrict to c:\\temp\\\nvar basePath = \"c:\\\\temp\\\\\"; // << update this to \"/config/node-red/audio/\"\nvar filename = msg.req.params.filename;\n\n\nif(!filename.toLowerCase().endsWith(\".mp3\")){\n    msg.payload = \"Only mp3 files are permitted\";\n    msg.statusCode = 405;//not allowed\n    return [null, msg];//fire output 2\n} else if(filename.includes(\"..\\\\\")){\n    msg.payload = \"Illegal file path\";\n    msg.statusCode = 405;//not allowed\n    return [null, msg];//fire output 2\n} else if(filename.includes(\"../\")){\n    msg.payload = \"Illegal file path\";\n    msg.statusCode = 405;//not allowed\n    return [null, msg];//fire output 2\n} \n//TODO: add more checks\n\nmsg.filename = basePath + filename;\nreturn [msg, null];//fire output 1\n\n\n","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1000,"y":560,"wires":[["34dc99e5.495466"],["98261154.3006","7b839e9487429e18"]]},{"id":"98261154.3006","type":"http response","z":"01a5fce4debb676d","name":"","statusCode":"","headers":{},"x":1370,"y":600,"wires":[]},{"id":"34dc99e5.495466","type":"file in","z":"01a5fce4debb676d","name":"","filename":"","format":"","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1200,"y":520,"wires":[["98261154.3006","dd8ab131477e6684"]]},{"id":"38d65d59.1d8aa2","type":"catch","z":"01a5fce4debb676d","name":"","scope":null,"uncaught":false,"x":820,"y":660,"wires":[["3b8014a.86ad8ec","5b18a8e7.fb8da8"]]},{"id":"3b8014a.86ad8ec","type":"function","z":"01a5fce4debb676d","name":"Set 404","func":"msg.payload = msg.error;\nmsg.statusCode = 404;//resource not found\nreturn msg;","outputs":1,"noerr":0,"x":1200,"y":660,"wires":[["98261154.3006"]]},{"id":"5b18a8e7.fb8da8","type":"debug","z":"01a5fce4debb676d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":850,"y":700,"wires":[]},{"id":"5de7cbb4.fa21a4","type":"comment","z":"01a5fce4debb676d","name":"Create endpoint   http://node-red-ip:port/audio/xxx  \\n where xxx is the file name to load","info":"","x":880,"y":516,"wires":[]},{"id":"b889a077e5d2e332","type":"http in","z":"01a5fce4debb676d","name":"","url":"/audio/:filename","method":"get","upload":false,"swaggerDoc":"","x":790,"y":560,"wires":[["f31a598d.9fd2c8","bcde1b6c9f0e8883"]]},{"id":"7eaa537bd18a5b65","type":"cast-to-client","z":"01a5fce4debb676d","name":"","url":"","contentType":"","message":"","language":"en","ip":"","port":"8009","volume":"50","x":1110,"y":760,"wires":[["d1a46dea9a5ba36a"]]},{"id":"93a5e2fcc495bd5e","type":"inject","z":"01a5fce4debb676d","name":"test.mp3 (open & edit ip and url)","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"ip\":\"192.168.1.19\",\"url\":\"http://192.168.1.32:1880/audio/test.mp3\",\"contentType\":\"audio/mp3\",\"volume\":70}","payloadType":"json","x":850,"y":760,"wires":[["7eaa537bd18a5b65"]]},{"id":"d1a46dea9a5ba36a","type":"debug","z":"01a5fce4debb676d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1290,"y":760,"wires":[]},{"id":"23cd7569e4e894cd","type":"comment","z":"01a5fce4debb676d","name":"Set \"IP\" to cast device IP \\n Set \"url\" to your node-red PC IP e.g. 192.168.0.2","info":"","x":877,"y":846,"wires":[]},{"id":"a05859d36ec523b6","type":"inject","z":"01a5fce4debb676d","name":"test2.mp3 (open & edit ip and url)","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"ip\":\"192.168.1.19\",\"url\":\"http://192.168.1.32:1880/audio/test2.mp3\",\"contentType\":\"audio/mp3\",\"volume\":70}","payloadType":"json","x":850,"y":800,"wires":[["7eaa537bd18a5b65"]]},{"id":"bcde1b6c9f0e8883","type":"debug","z":"01a5fce4debb676d","name":"req.params.filename","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"msg.req.params.filename","targetType":"msg","statusVal":"msg.req.params.filename","statusType":"auto","x":880,"y":600,"wires":[]},{"id":"dd8ab131477e6684","type":"debug","z":"01a5fce4debb676d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1370,"y":520,"wires":[]},{"id":"7b839e9487429e18","type":"debug","z":"01a5fce4debb676d","name":"bad request","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1110,"y":600,"wires":[]},{"id":"c4c7d9ec3e3a6eeb","type":"comment","z":"01a5fce4debb676d","name":"This demo expects the files   test.mp3     &    test2.mp3  \\n ... to be found in the base path (basepath set in function)","info":"","x":1080,"y":420,"wires":[]}]
  1. remove or disable other endpoints
  2. Import flow
  3. Read every comment & action them
    1. Update the base path in the "Set base path" function
    2. Update the inject nodes to match your PC IP and CAST IP

Already follow your step but still can not casting. The cast status node is play but have no any sound in speaker. and few minutes came error load media


How to make this not mixing up? Already try to change the file in node like below, it still works auto download test.mp3 if try access https://x.x.x.x:1880/endpoint/audio/test.mp3 in a browser

@mbonani Any advise about this?

image

[{"id":"01a5fce4debb676d","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"4e8121031854c065","type":"http in","z":"01a5fce4debb676d","name":"","url":"/audio","method":"get","upload":false,"swaggerDoc":"","x":290,"y":80,"wires":[["122a3ecd7775d97f","a82de37c21178ffb"]]},{"id":"122a3ecd7775d97f","type":"file in","z":"01a5fce4debb676d","name":"","filename":"test.mp3","format":"","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":550,"y":80,"wires":[["dd8a20a5580907a2","ee4e9408ac8af6a9"]]},{"id":"dd8a20a5580907a2","type":"http response","z":"01a5fce4debb676d","name":"","statusCode":"","headers":{"content-type":"audio/mp3"},"x":790,"y":80,"wires":[]},{"id":"a82de37c21178ffb","type":"debug","z":"01a5fce4debb676d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":300,"y":140,"wires":[]},{"id":"ee4e9408ac8af6a9","type":"debug","z":"01a5fce4debb676d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":580,"y":140,"wires":[]},{"id":"5d8b66fce47eb44b","type":"cast-to-client","z":"01a5fce4debb676d","name":"","url":"","contentType":"","message":"","language":"en","ip":"","port":"","volume":"50","x":540,"y":220,"wires":[["5e99d16a17a8d2be"]]},{"id":"1503885c909d3f21","type":"inject","z":"01a5fce4debb676d","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"ip\":\"x.x.x.x\",\"url\":\"https://x.x.x.x:1880/endpoint/audio/test.mp3\",\"contentType\":\"audio/mp3\",\"volume\":50}","payloadType":"json","x":360,"y":220,"wires":[["5d8b66fce47eb44b"]]},{"id":"5e99d16a17a8d2be","type":"debug","z":"01a5fce4debb676d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":740,"y":220,"wires":[]}]

RE: Mix-ups

  1. Your screenshot does not match your flow export
    image

  2. I gave you a 100% working example, with multiple re-use (will support multiple MP3s without a single modification) and I provided instructions - but you are still posting the NON working flow!

Did you even try the working flow I gave you?

Hi @Steve-Mcl

I don't know why not match. because check the http in node url is /audio but the display node always have [get] /endpoint/audio

image

I'm sorry and forget to posting your example with update from me. Let you know the flow with modification as per your instruction below.

As you can see why the display node (red box highlighted) change automatically to [get] /endpoint/audio/:filename

[{"id":"8a77cceadc6004b6","type":"tab","label":"Flow 2","disabled":false,"info":"","env":[]},{"id":"f31a598d.9fd2c8","type":"function","z":"8a77cceadc6004b6","name":"Set base path","func":"//restrict to c:\\temp\\\n//var basePath = \"c:\\\\temp\\\\\"; // << update this to \"/config/node-red/audio/\"\n\nvar basePath = \"/config/node-red/audio/\";\nvar filename = msg.req.params.filename;\n\n\nif(!filename.toLowerCase().endsWith(\".mp3\")){\n    msg.payload = \"Only mp3 files are permitted\";\n    msg.statusCode = 405;//not allowed\n    return [null, msg];//fire output 2\n} else if(filename.includes(\"..\\\\\")){\n    msg.payload = \"Illegal file path\";\n    msg.statusCode = 405;//not allowed\n    return [null, msg];//fire output 2\n} else if(filename.includes(\"../\")){\n    msg.payload = \"Illegal file path\";\n    msg.statusCode = 405;//not allowed\n    return [null, msg];//fire output 2\n} \n//TODO: add more checks\n\nmsg.filename = basePath + filename;\nreturn [msg, null];//fire output 1\n\n\n","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":560,"y":260,"wires":[["34dc99e5.495466"],["98261154.3006","7b839e9487429e18"]]},{"id":"98261154.3006","type":"http response","z":"8a77cceadc6004b6","name":"","statusCode":"","headers":{},"x":930,"y":300,"wires":[]},{"id":"34dc99e5.495466","type":"file in","z":"8a77cceadc6004b6","name":"","filename":"","format":"","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":760,"y":220,"wires":[["98261154.3006","dd8ab131477e6684"]]},{"id":"38d65d59.1d8aa2","type":"catch","z":"8a77cceadc6004b6","name":"","scope":null,"uncaught":false,"x":380,"y":360,"wires":[["3b8014a.86ad8ec","5b18a8e7.fb8da8"]]},{"id":"3b8014a.86ad8ec","type":"function","z":"8a77cceadc6004b6","name":"Set 404","func":"msg.payload = msg.error;\nmsg.statusCode = 404;//resource not found\nreturn msg;","outputs":1,"noerr":0,"x":760,"y":360,"wires":[["98261154.3006"]]},{"id":"5b18a8e7.fb8da8","type":"debug","z":"8a77cceadc6004b6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":410,"y":400,"wires":[]},{"id":"5de7cbb4.fa21a4","type":"comment","z":"8a77cceadc6004b6","name":"Create endpoint   http://node-red-ip:port/audio/xxx  \\n where xxx is the file name to load","info":"","x":440,"y":216,"wires":[]},{"id":"b889a077e5d2e332","type":"http in","z":"8a77cceadc6004b6","name":"","url":"/audio/:filename","method":"get","upload":false,"swaggerDoc":"","x":350,"y":260,"wires":[["f31a598d.9fd2c8","bcde1b6c9f0e8883"]]},{"id":"7eaa537bd18a5b65","type":"cast-to-client","z":"8a77cceadc6004b6","name":"","url":"","contentType":"","message":"","language":"en","ip":"","port":"8009","volume":"50","x":670,"y":460,"wires":[["d1a46dea9a5ba36a"]]},{"id":"93a5e2fcc495bd5e","type":"inject","z":"8a77cceadc6004b6","name":"test.mp3 (open & edit ip and url)","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"ip\":\"x.x.x.x\",\"url\":\"https://x.x.x.x:1880/audio/test.mp3\",\"contentType\":\"audio/mp3\",\"volume\":70}","payloadType":"json","x":410,"y":460,"wires":[["7eaa537bd18a5b65"]]},{"id":"d1a46dea9a5ba36a","type":"debug","z":"8a77cceadc6004b6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":850,"y":460,"wires":[]},{"id":"23cd7569e4e894cd","type":"comment","z":"8a77cceadc6004b6","name":"Set \"IP\" to cast device IP \\n Set \"url\" to your node-red PC IP e.g. 192.168.0.2","info":"","x":437,"y":546,"wires":[]},{"id":"a05859d36ec523b6","type":"inject","z":"8a77cceadc6004b6","name":"test2.mp3 (open & edit ip and url)","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"ip\":\"192.168.1.19\",\"url\":\"http://192.168.1.32:1880/audio/test2.mp3\",\"contentType\":\"audio/mp3\",\"volume\":70}","payloadType":"json","x":410,"y":500,"wires":[["7eaa537bd18a5b65"]]},{"id":"bcde1b6c9f0e8883","type":"debug","z":"8a77cceadc6004b6","name":"req.params.filename","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"msg.req.params.filename","targetType":"msg","statusVal":"msg.req.params.filename","statusType":"auto","x":440,"y":300,"wires":[]},{"id":"dd8ab131477e6684","type":"debug","z":"8a77cceadc6004b6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":930,"y":220,"wires":[]},{"id":"7b839e9487429e18","type":"debug","z":"8a77cceadc6004b6","name":"bad request","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":670,"y":300,"wires":[]},{"id":"c4c7d9ec3e3a6eeb","type":"comment","z":"8a77cceadc6004b6","name":"This demo expects the files   test.mp3     &    test2.mp3  \\n ... to be found in the base path (basepath set in function)","info":"","x":640,"y":120,"wires":[]}]

It imports normally on my node-red.

What version is your node-red?

Try this...

  1. remove every HTTP endpoint you have on your flows.
  2. restart node-red
  3. refresh your browser
  4. Import flow
  5. Read every comment & action them
    1. Update the base path in the "Set base path" function
    2. Update the inject nodes to match your PC IP and CAST IP

This is why

Note: In order to use the http_node you will need to expose Node-RED using
a network port in addition to ingress. The HTTP nodes will also be presented
under /endpoint/ as shown in the UI. If using the node-red-dashboard module
this will also be hosted under this path and will use any credentials set here.

Excerpt from the add-on documentation

Note the message in the footer of your screenshot

e25964fb7fdd7d7fc362592aefb68c355000a608

1 Like

Ah, this must be a HA thing (doesnt occur in a default node-red install)

@mrrobot the demo i gave you should work if you update the INJECT nodes to include /endpoint/

Hi @mbonani, Well noted, understood now.

Already check the configuration have no any set credentials set here but still can't cast. Any missed a HA thing again?

The cast status node is play but have no any sound in speaker. and few minutes came error load media

image

Hi @Steve-Mcl already try update inject nodes to include /endpoint/ but still can not cast.
https://x.x.x.x:1880/endpoint/audio/test.mp3

Does the link work in a browser?

More importantly, does the link work in a browser on a different computer or smartphone?

Can you share your flow as it is right now.

Hi @Steve-Mcl,

Yes I can play this url https://x.x.x.x:1880/endpoint/audio/test.mp3 directly to browser on different computer and smartphone. Only do add type header in the HTTP response.

I think no issue to play .mp3 file now but why still can not cast ?

Let you know the flow as right now below

image

[{"id":"176d195fcf8c8d6d","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"f31a598d.9fd2c8","type":"function","z":"176d195fcf8c8d6d","name":"Set base path","func":"//restrict to c:\\temp\\\n//var basePath = \"c:\\\\temp\\\\\"; // << update this to \"/config/node-red/audio/\"\n\nvar basePath = \"/config/node-red/audio/\";\nvar filename = msg.req.params.filename;\n\n\nif(!filename.toLowerCase().endsWith(\".mp3\")){\n    msg.payload = \"Only mp3 files are permitted\";\n    msg.statusCode = 405;//not allowed\n    return [null, msg];//fire output 2\n} else if(filename.includes(\"..\\\\\")){\n    msg.payload = \"Illegal file path\";\n    msg.statusCode = 405;//not allowed\n    return [null, msg];//fire output 2\n} else if(filename.includes(\"../\")){\n    msg.payload = \"Illegal file path\";\n    msg.statusCode = 405;//not allowed\n    return [null, msg];//fire output 2\n} \n//TODO: add more checks\n\nmsg.filename = basePath + filename;\nreturn [msg, null];//fire output 1\n\n\n","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":280,"wires":[["34dc99e5.495466"],["98261154.3006","7b839e9487429e18"]]},{"id":"98261154.3006","type":"http response","z":"176d195fcf8c8d6d","name":"","statusCode":"","headers":{"content-type":"audio/mp3"},"x":950,"y":320,"wires":[]},{"id":"34dc99e5.495466","type":"file in","z":"176d195fcf8c8d6d","name":"","filename":"","format":"","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":780,"y":240,"wires":[["98261154.3006","dd8ab131477e6684"]]},{"id":"38d65d59.1d8aa2","type":"catch","z":"176d195fcf8c8d6d","name":"","scope":null,"uncaught":false,"x":400,"y":380,"wires":[["3b8014a.86ad8ec","5b18a8e7.fb8da8"]]},{"id":"3b8014a.86ad8ec","type":"function","z":"176d195fcf8c8d6d","name":"Set 404","func":"msg.payload = msg.error;\nmsg.statusCode = 404;//resource not found\nreturn msg;","outputs":1,"noerr":0,"x":780,"y":380,"wires":[["98261154.3006"]]},{"id":"5b18a8e7.fb8da8","type":"debug","z":"176d195fcf8c8d6d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":430,"y":420,"wires":[]},{"id":"5de7cbb4.fa21a4","type":"comment","z":"176d195fcf8c8d6d","name":"Create endpoint   http://node-red-ip:port/audio/xxx  \\n where xxx is the file name to load","info":"","x":460,"y":236,"wires":[]},{"id":"b889a077e5d2e332","type":"http in","z":"176d195fcf8c8d6d","name":"","url":"/audio/:filename","method":"get","upload":false,"swaggerDoc":"","x":370,"y":280,"wires":[["f31a598d.9fd2c8","bcde1b6c9f0e8883"]]},{"id":"7eaa537bd18a5b65","type":"cast-to-client","z":"176d195fcf8c8d6d","name":"","url":"","contentType":"","message":"","language":"en","ip":"","port":"8009","volume":"50","x":690,"y":480,"wires":[["d1a46dea9a5ba36a"]]},{"id":"93a5e2fcc495bd5e","type":"inject","z":"176d195fcf8c8d6d","name":"test.mp3 (open & edit ip and url)","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"ip\":\"x.x.x.x\",\"url\":\"https://x.x.x.x:1880/endpoint/audio/test.mp3\",\"contentType\":\"audio/mp3\",\"volume\":70}","payloadType":"json","x":430,"y":480,"wires":[["7eaa537bd18a5b65"]]},{"id":"d1a46dea9a5ba36a","type":"debug","z":"176d195fcf8c8d6d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":870,"y":480,"wires":[]},{"id":"23cd7569e4e894cd","type":"comment","z":"176d195fcf8c8d6d","name":"Set \"IP\" to cast device IP \\n Set \"url\" to your node-red PC IP e.g. 192.168.0.2","info":"","x":457,"y":566,"wires":[]},{"id":"a05859d36ec523b6","type":"inject","z":"176d195fcf8c8d6d","name":"test2.mp3 (open & edit ip and url)","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"ip\":\"192.168.1.19\",\"url\":\"http://192.168.1.32:1880/audio/test2.mp3\",\"contentType\":\"audio/mp3\",\"volume\":70}","payloadType":"json","x":430,"y":520,"wires":[["7eaa537bd18a5b65"]]},{"id":"bcde1b6c9f0e8883","type":"debug","z":"176d195fcf8c8d6d","name":"req.params.filename","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"msg.req.params.filename","targetType":"msg","statusVal":"msg.req.params.filename","statusType":"auto","x":460,"y":320,"wires":[]},{"id":"dd8ab131477e6684","type":"debug","z":"176d195fcf8c8d6d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":950,"y":240,"wires":[]},{"id":"7b839e9487429e18","type":"debug","z":"176d195fcf8c8d6d","name":"bad request","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":690,"y":320,"wires":[]},{"id":"c4c7d9ec3e3a6eeb","type":"comment","z":"176d195fcf8c8d6d","name":"This demo expects the files   test.mp3     &    test2.mp3  \\n ... to be found in the base path (basepath set in function)","info":"","x":660,"y":140,"wires":[]}]

Does the cast node still work? There is a message in its README that states the following.

Because I no longer use this node myself, there is unfortunately only limited support.

And, since you are running it on HA, I'd suggest that you use its media_source integration for casting media. I posted an example above in #3. If you have any questions regarding that, you can post on the HA Forum, they even have a Node-RED category there.

It works for me (non docker / non container)


@mrrobot I tested the flow you posted back & it definitely works for me.
image

I suggest there is some other issue with your cast device or network (docker networking, host firewall?).

  • Can you PING the cast device from node-red? (use node-red-node-ping to test this as it will ping from within the container)

  • When you click the :mag: button in the nodes editor, does it list your cast device?
    image

    • If yes, is the PORT set correctly?
    • If yes, are you entering the correct IP in the INJECT

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.