Hello,
I am having success using Piper to generate TTS for voice notifications. I'm able to use a POST message to send text to an instance of Piper running in a Docker container, which returns the spoken text as a binary buffer.
I've tested it with node-red-contrib-play-audio
, and the results are about as glorious as I could ever have hoped.
However, the next most obvious step is to wrap that buffer properly in a nice object and publish it to MQTT, and thus any device with a speaker that is subscribed to that topic will play it. I will be using this for spoken notifications in specific locations.
The node-red-contrib-play-audio
node is great, but I'd also like to be able to play voice notifications on any device viewing the Dashboard, therefore ui-audio
.
Where I need help is to format a ui_update.src
message so a the ui-audio
node is happy to accept that message as input. It wants the location of the audio as a URL ... but I have it right here in this buffer. Here. Have it. Please.
I need to somehow con ui-audio
into believing that a local buffer is an URL, or ... uhhhh ... help.
Please, assuming a msg.payload of a raw buffer, please help me write a function or set up a change node such that ui-audio
will play it. There has to be a field or a parameter I'm not seeing.
Simply feeding ui-audio
the buffer in ui_update.src
has not worked. This is a formatting thing. Halp. I stuck.
This is what I have so far:
[{"id":"6a137c41d3addec5","type":"ui-template","z":"3567e03e18126502","group":"d3197b4c4dd7b057","page":"","ui":"","name":"","order":2,"width":0,"height":0,"head":"","format":"<template>\n <!-- if you remove the `controls` attribute, you MUST click soomething on the page before initiating play -->\n <audio ref=\"audio\" controls autoplay src=\"\"> </audio>\n</template>\n\n<script>\n export default {\n watch: {\n msg: function () {\n if (this.msg?.topic === 'play') {\n if (this.$refs.audio.src !== this.msg.payload ) {\n this.$refs.audio.src = this.msg.payload\n }\n this.$refs.audio.play()\n } else if (this.msg?.topic === 'stop') {\n this.$refs.audio.src = ''\n } else if (this.msg?.topic === 'pause') {\n this.$refs.audio.pause()\n }\n }\n }\n }\n</script>\n\n<style>\n.hidden {\n display: none !important;\n}\n</style>","storeOutMessages":true,"passthru":true,"resendOnRefresh":true,"templateScope":"local","className":"hidden","x":320,"y":340,"wires":[[]]},{"id":"caf334102ab7952d","type":"inject","z":"3567e03e18126502","name":"cantina","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"play","payload":"https://media.geeksforgeeks.org/wp-content/uploads/20240218213800/CantinaBand60.wav","payloadType":"str","x":170,"y":380,"wires":[["6a137c41d3addec5"]]},{"id":"8e135a0e9bfdccb7","type":"inject","z":"3567e03e18126502","name":"march","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"play","payload":"https://www2.cs.uic.edu/~i101/SoundFiles/ImperialMarch60.wav","payloadType":"str","x":170,"y":340,"wires":[["6a137c41d3addec5"]]},{"id":"3c290f1ea6cf8b36","type":"inject","z":"3567e03e18126502","name":"pause","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"pause","x":170,"y":300,"wires":[["6a137c41d3addec5"]]},{"id":"436efb1217534529","type":"inject","z":"3567e03e18126502","name":"stop","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"stop","x":170,"y":260,"wires":[["6a137c41d3addec5"]]},{"id":"d3197b4c4dd7b057","type":"ui-group","name":"P2 G1","page":"6685af11067a04cd","width":11,"height":"1","order":1,"showTitle":true,"className":"","visible":"true","disabled":"false","groupType":"default"},{"id":"6685af11067a04cd","type":"ui-page","name":"grid page","ui":"22ea43815413e748","path":"/page2","icon":"home","layout":"grid","theme":"70e58855f40712e7","breakpoints":[{"name":"Default","px":"0","cols":"3"},{"name":"Tablet","px":"576","cols":"6"},{"name":"Small Desktop","px":"768","cols":"9"},{"name":"Desktop","px":"1024","cols":"12"}],"order":2,"className":"","visible":"true","disabled":"false"},{"id":"22ea43815413e748","type":"ui-base","name":"base","path":"/dashboard","appIcon":"","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control"],"showPathInSidebar":false,"showPageTitle":true,"navigationStyle":"icon","titleBarStyle":"default"},{"id":"70e58855f40712e7","type":"ui-theme","name":"pink Theme","colors":{"surface":"#ffffff","primary":"#d355a5","bgPage":"#e1bcbc","groupBg":"#fbe9e9","groupOutline":"#dc8f8f"},"sizes":{"density":"compact","pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}}]