Mp3 playlist through HTTP out

Hi all,

I'm struggling with this for a while. I'm trying to play all mp3 urls, one-by-one, through the HTTP out node. It works only when the function node is:

msg.payload = msg.payload[0].url;
return msg;

But when I'm trying to play the entire array, it fails. I'm sure I'm missing something here...
Any ideas to make it work? 10x

Here's my flow:

[{"id":"c737fb49.1834d8","type":"http in","z":"c3131846.ef3fe8","name":"","url":"/playlist","method":"get","upload":false,"swaggerDoc":"","x":75,"y":165.25,"wires":[["d2e4ca04.dde7d8"]]},{"id":"7130c772.6ee758","type":"function","z":"c3131846.ef3fe8","name":"Array","func":"//msg.topic=\"word1\"\n//msg.payload = msg.payload[0].url;\n//return msg;\n\nvar msgList = [];\nvar letterList = msg.payload;\nfor (var i =0 ; i < 5; i++){\n    msgList.push({payload:letterList[i].url});\n}\n\nmsg.payload = msgList;\nreturn msg;","outputs":1,"noerr":0,"x":214.375,"y":247.75,"wires":[["9e7a33ad.4330b"]]},{"id":"fee8e102.5fb1a","type":"change","z":"c3131846.ef3fe8","name":"","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":464.75006103515625,"y":274.58331298828125,"wires":[["5142f40f.23405c","e20b14db.c4dfd8"]]},{"id":"e20b14db.c4dfd8","type":"http request","z":"c3131846.ef3fe8","name":"","method":"GET","ret":"bin","paytoqs":false,"url":"","tls":"","proxy":"","authType":"","x":587.472412109375,"y":323.77764892578125,"wires":[["9419c512.606338"]]},{"id":"9419c512.606338","type":"change","z":"c3131846.ef3fe8","name":"Set Headers","rules":[{"t":"set","p":"headers","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"headers.content-type","pt":"msg","to":"audio/mp3","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":694.3056030273438,"y":271.97210693359375,"wires":[["6d5f2037.2e368","c9fea8b8.e61df8"]]},{"id":"6d5f2037.2e368","type":"http response","z":"c3131846.ef3fe8","name":"","statusCode":"","headers":{},"x":822.9722290039062,"y":314.388916015625,"wires":[]},{"id":"9e7a33ad.4330b","type":"delay","z":"c3131846.ef3fe8","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"2","nbRateUnits":"","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":288.75001525878906,"y":286.5,"wires":[["fee8e102.5fb1a"]]},{"id":"c9fea8b8.e61df8","type":"debug","z":"c3131846.ef3fe8","name":"","active":false,"console":"false","complete":"false","x":826.5,"y":218.75,"wires":[]},{"id":"5142f40f.23405c","type":"debug","z":"c3131846.ef3fe8","name":"","active":true,"console":"false","complete":"false","x":601,"y":221,"wires":[]},{"id":"d2e4ca04.dde7d8","type":"function","z":"c3131846.ef3fe8","name":"mp3","func":"msg.payload = \n[{\"url\":\"https://freesound.org/data/previews/179/179101_3332582-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/428/428908_8584880-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/340/340481_313780-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/476/476542_9786444-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/482/482385_3442171-lq.mp3\"}]\nreturn msg;","outputs":1,"noerr":0,"x":155,"y":205,"wires":[["7130c772.6ee758"]]},{"id":"b2fd8f41.38a24","type":"inject","z":"c3131846.ef3fe8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":60.5,"y":319,"wires":[["d2e4ca04.dde7d8"]]}]

Try adding a function node before your http request node to check you are sending it what you think you are

Function or debug?

yep meant debug

1 Like

Thanks, I did - and it's all going well until the HTTP requests node for a binary buffer. This is my point of failure, I guess. At that point the debugger shouts "Error: Invalid URI".

Your function node:

var msgList = [];
var letterList = msg.payload;
for (var i =0 ; i < 5; i++){
    msgList.push({payload:letterList[i].url});
}

msg.payload = msgList;
return msg;

This only returns 1 message with an array.

Instead I would use something like:

var l = msg.payload;
for (var i =0 ; i < l.length; i++){
   node.send({url:l[i].url});
}

Remove the msg.url change node and connect the delay node to the first http request node.

Thanks, I did it. Almost there. the debugger shows the buffers, but the HTTP out is not returning anything - only ""No response object""

Here's the updated flow:

[{"id":"c737fb49.1834d8","type":"http in","z":"c3131846.ef3fe8","name":"","url":"/playlist","method":"get","upload":false,"swaggerDoc":"","x":75,"y":165.25,"wires":[["d2e4ca04.dde7d8"]]},{"id":"7130c772.6ee758","type":"function","z":"c3131846.ef3fe8","name":"Array","func":"//msg.topic=\"word1\"\n//msg.payload = msg.payload[0].url;\n//return msg;\n\nvar l = msg.payload;\nfor (var i =0 ; i < l.length; i++){\n   node.send({url:l[i].url});\n}","outputs":1,"noerr":0,"x":232.375,"y":256.75,"wires":[["e20b14db.c4dfd8"]]},{"id":"e20b14db.c4dfd8","type":"http request","z":"c3131846.ef3fe8","name":"","method":"GET","ret":"bin","paytoqs":false,"url":"","tls":"","proxy":"","authType":"","x":406.472412109375,"y":295.77764892578125,"wires":[["9419c512.606338"]]},{"id":"9419c512.606338","type":"change","z":"c3131846.ef3fe8","name":"Set Headers","rules":[{"t":"set","p":"headers","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"headers.content-type","pt":"msg","to":"audio/mp3","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":579.3056030273438,"y":247.97210693359375,"wires":[["c9fea8b8.e61df8","9e7a33ad.4330b"]]},{"id":"6d5f2037.2e368","type":"http response","z":"c3131846.ef3fe8","name":"","statusCode":"","headers":{},"x":859.9722290039062,"y":319.388916015625,"wires":[]},{"id":"9e7a33ad.4330b","type":"delay","z":"c3131846.ef3fe8","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"2","nbRateUnits":"","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":701.75,"y":305.5,"wires":[["6d5f2037.2e368"]]},{"id":"c9fea8b8.e61df8","type":"debug","z":"c3131846.ef3fe8","name":"","active":true,"console":"false","complete":"false","x":826.5,"y":218.75,"wires":[]},{"id":"d2e4ca04.dde7d8","type":"function","z":"c3131846.ef3fe8","name":"mp3","func":"msg.payload = \n[{\"url\":\"https://freesound.org/data/previews/179/179101_3332582-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/428/428908_8584880-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/340/340481_313780-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/476/476542_9786444-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/482/482385_3442171-lq.mp3\"}]\nreturn msg;","outputs":1,"noerr":0,"x":155,"y":205,"wires":[["7130c772.6ee758"]]},{"id":"b2fd8f41.38a24","type":"inject","z":"c3131846.ef3fe8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":99.5,"y":318,"wires":[["d2e4ca04.dde7d8"]]}]

Further ideas? 10x

To be honest I am no hero with bufferstuff. Is this webpage supposed to play audio one by one ?
I am not sure if you can do that.

Yes the http out node is playing audio for a single url, i.e. msg.payload[0].url;
But when it comes to multiple URLs it's different.
Here's a working example, for a single element, I believe it's doable

[{"id":"c737fb49.1834d8","type":"http in","z":"c3131846.ef3fe8","name":"","url":"/playlist","method":"get","upload":false,"swaggerDoc":"","x":80,"y":90.25,"wires":[["d2e4ca04.dde7d8"]]},{"id":"7130c772.6ee758","type":"function","z":"c3131846.ef3fe8","name":"Array","func":"msg.topic=\"word1\"\nmsg.payload = msg.payload[0].url;\nreturn msg;\n\n//var l = msg.payload;\n//for (var i =0 ; i < l.length; i++){\n//   node.send({url:l[i].url});\n//}","outputs":1,"noerr":0,"x":241.375,"y":210.75,"wires":[["fee8e102.5fb1a"]]},{"id":"fee8e102.5fb1a","type":"change","z":"c3131846.ef3fe8","name":"","rules":[{"t":"set","p":"url","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":284.75006103515625,"y":272.58331298828125,"wires":[["e20b14db.c4dfd8"]]},{"id":"e20b14db.c4dfd8","type":"http request","z":"c3131846.ef3fe8","name":"","method":"GET","ret":"bin","paytoqs":false,"url":"","tls":"","proxy":"","authType":"","x":338.472412109375,"y":328.77764892578125,"wires":[["9e7a33ad.4330b"]]},{"id":"9419c512.606338","type":"change","z":"c3131846.ef3fe8","name":"Set Headers","rules":[{"t":"set","p":"headers","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"headers.content-type","pt":"msg","to":"audio/mp3","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":519.3056030273438,"y":278.97210693359375,"wires":[["c9fea8b8.e61df8","6d5f2037.2e368"]]},{"id":"6d5f2037.2e368","type":"http response","z":"c3131846.ef3fe8","name":"","statusCode":"","headers":{},"x":760.9722290039062,"y":262.388916015625,"wires":[]},{"id":"9e7a33ad.4330b","type":"delay","z":"c3131846.ef3fe8","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"2","nbRateUnits":"","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":497.75,"y":355.5,"wires":[["9419c512.606338"]]},{"id":"c9fea8b8.e61df8","type":"debug","z":"c3131846.ef3fe8","name":"","active":true,"console":"false","complete":"false","x":640.5,"y":191.75,"wires":[]},{"id":"d2e4ca04.dde7d8","type":"function","z":"c3131846.ef3fe8","name":"mp3","func":"msg.payload = \n[{\"url\":\"https://freesound.org/data/previews/179/179101_3332582-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/428/428908_8584880-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/340/340481_313780-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/476/476542_9786444-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/482/482385_3442171-lq.mp3\"}]\nreturn msg;","outputs":1,"noerr":0,"x":164,"y":159,"wires":[["7130c772.6ee758"]]},{"id":"b2fd8f41.38a24","type":"inject","z":"c3131846.ef3fe8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":108.5,"y":272,"wires":[["d2e4ca04.dde7d8"]]}]

Ok, not giving up yet.
Since the http response node is able to play a single mp3 file,
rather than array of mp3 files one-by-one, with the current function node:

msg.payload = msg.payload[0].url;
return msg;

I tried to merge/join/concat the audio files into one single file with ffmpeg-concat
by adding a function node before the current function node - with no luck.

The ffmpeg-concat does not seem to work in the demo as well.
Does anyone has experience with ffmpeg-concat or other audio joining/merging methods for node-red? Here's the current flow:

Thanks

If you can detect the end of the previous track playing then you could use a triggered queue to play them... ege https://flows.nodered.org/flow/cea8afa28b7a93ebdc0f (which was doing a TTS instead of playback but...)

Thanks dceejay,

Tried this trigger-queue concept, and also tried the logic of a counter, https://flows.nodered.org/flow/081ca5e25b7345bf046d
to increase automatically msg.payload[0].url; value by one to msg.payload[1].url; at the same http endpoint,
I'm still getting "502 bad gateway error" when using the http response node.

502 Bad Gateway: Registered endpoint failed to handle the request.

But when I'm using the array version of this flow, with the play audio node at the end, I'm able to hear audio, not through http though.

The big question then, is how can we make the same thing through http out?
Any new direction is highly appreciated.

Current flow:

[{"id":"7d6e6a59.d22084","type":"http in","z":"8ced2aec.35a9f8","name":"","url":"/playlists","method":"get","upload":true,"swaggerDoc":"","x":136,"y":132,"wires":[["d186f610.234598"]]},{"id":"d186f610.234598","type":"function","z":"8ced2aec.35a9f8","name":"mp3","func":"msg.payload = \n[{\"url\":\"https://freesound.org/data/previews/179/179101_3332582-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/428/428908_8584880-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/340/340481_313780-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/476/476542_9786444-lq.mp3\"},\n{\"url\":\"https://freesound.org/data/previews/482/482385_3442171-lq.mp3\"}]\nreturn msg;","outputs":1,"noerr":0,"x":291,"y":172.75,"wires":[["8a42304d.cbb28"]]},{"id":"8a42304d.cbb28","type":"function","z":"8ced2aec.35a9f8","name":"Array","func":"//msg.topic=\"word1\"\n//msg.payload = msg.payload[0].url;\n//return msg;\n\nvar l = msg.payload;\nfor (var i =0 ; i < l.length; i++){\nnode.send({url:l[i].url}); }\n\n\n","outputs":1,"noerr":0,"x":404.375,"y":206.5,"wires":[["74352ee5.7ef29"]]},{"id":"dd54d10d.43204","type":"inject","z":"8ced2aec.35a9f8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":150,"y":188.75,"wires":[["d186f610.234598"]]},{"id":"74352ee5.7ef29","type":"http request","z":"8ced2aec.35a9f8","name":"","method":"GET","ret":"bin","paytoqs":false,"url":"","tls":"","proxy":"","authType":"","x":373.472412109375,"y":263.52764892578125,"wires":[["d447536.2e2a2b"]]},{"id":"8957e3ab.7aa25","type":"change","z":"8ced2aec.35a9f8","name":"Set Headers","rules":[{"t":"set","p":"headers","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"headers.content-type","pt":"msg","to":"audio/mp3","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":386,"y":436,"wires":[["6d9c8d8.1d29b74","c1d13891.7465f8"]]},{"id":"6d9c8d8.1d29b74","type":"http response","z":"8ced2aec.35a9f8","name":"","statusCode":"","headers":{},"x":575.5,"y":417,"wires":[]},{"id":"c1d13891.7465f8","type":"play audio","z":"8ced2aec.35a9f8","name":"","voice":"","x":589,"y":370,"wires":[]},{"id":"d447536.2e2a2b","type":"delay","z":"8ced2aec.35a9f8","name":"","pauseType":"rate","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"2","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":383.5,"y":318,"wires":[["8957e3ab.7aa25"]]}]

thanks