Simple way to play sound Dashboard 2.0

I need to play some sounds on the client device (not TTS, .wav or .mp3 local files) for warnings, errors e.t.c

It was so simple with classic node-red dasboard, like this:
image

How to do the same with Dashboard 2.0?

Tried to use Play audio node, the problem is - it works only if node-red editor opened at client device. It's unacceptable for my project.

image

Tried to use ui-audio node. TTS voice works, but i don't need it. Sounds doesn't play at all.

image

sound.json (6.8 KB)

[
    {
        "id": "637b119b233a292e",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "a33f72be9115168a",
        "type": "inject",
        "z": "637b119b233a292e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 200,
        "y": 780,
        "wires": [
            [
                "aeb782b71628f369"
            ]
        ]
    },
    {
        "id": "d6ed7513998ca59e",
        "type": "play audio",
        "z": "637b119b233a292e",
        "name": "",
        "voice": "0",
        "x": 590,
        "y": 680,
        "wires": []
    },
    {
        "id": "15698c7d54c21dad",
        "type": "file in",
        "z": "637b119b233a292e",
        "name": "SOUND",
        "filename": "/home/rks/.node-red/sounds/beep-07.mp3",
        "filenameType": "str",
        "format": "",
        "chunk": false,
        "sendError": false,
        "encoding": "none",
        "allProps": false,
        "x": 380,
        "y": 680,
        "wires": [
            [
                "d6ed7513998ca59e"
            ]
        ]
    },
    {
        "id": "71b2efb1375ac82e",
        "type": "inject",
        "z": "637b119b233a292e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 200,
        "y": 680,
        "wires": [
            [
                "15698c7d54c21dad"
            ]
        ]
    },
    {
        "id": "f79bce3737c81bbb",
        "type": "ui_audio",
        "z": "637b119b233a292e",
        "name": "",
        "group": "4b7b9a0cd8e7b0ce",
        "voice": "",
        "always": "",
        "x": 580,
        "y": 580,
        "wires": []
    },
    {
        "id": "e3fa643931af0a47",
        "type": "file in",
        "z": "637b119b233a292e",
        "name": "SOUND",
        "filename": "/home/rks/.node-red/sounds/beep-07.mp3",
        "filenameType": "str",
        "format": "",
        "chunk": false,
        "sendError": false,
        "encoding": "none",
        "allProps": false,
        "x": 380,
        "y": 580,
        "wires": [
            [
                "f79bce3737c81bbb"
            ]
        ]
    },
    {
        "id": "e863a8fefe8eb3d0",
        "type": "inject",
        "z": "637b119b233a292e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 200,
        "y": 580,
        "wires": [
            [
                "e3fa643931af0a47"
            ]
        ]
    },
    {
        "id": "aeb782b71628f369",
        "type": "ui-audio",
        "z": "637b119b233a292e",
        "group": "de8fea73a6588944",
        "ui": "",
        "name": "",
        "order": 0,
        "width": 0,
        "height": 0,
        "mode": "src",
        "voice": "",
        "src": "/home/rks/.node-red/sounds/beep-08.mp3",
        "autoplay": "off",
        "loop": "off",
        "muted": "off",
        "className": "",
        "x": 380,
        "y": 780,
        "wires": [
            []
        ]
    },
    {
        "id": "4b7b9a0cd8e7b0ce",
        "type": "ui_group",
        "name": "SOUND",
        "tab": "6bc6eebe885603b9",
        "order": 1,
        "disp": true,
        "width": 6,
        "collapse": false,
        "className": ""
    },
    {
        "id": "de8fea73a6588944",
        "type": "ui-group",
        "name": "Group 1",
        "page": "aa996ee29b3a5486",
        "width": 6,
        "height": 1,
        "order": 1,
        "showTitle": true,
        "className": "",
        "visible": true,
        "disabled": false,
        "groupType": "default"
    },
    {
        "id": "6bc6eebe885603b9",
        "type": "ui_tab",
        "name": "SOUND",
        "icon": "dashboard",
        "order": 2,
        "disabled": false,
        "hidden": false
    },
    {
        "id": "aa996ee29b3a5486",
        "type": "ui-page",
        "name": "Page 22",
        "ui": "b3ec8449d91f6fb4",
        "path": "/page22",
        "icon": "home",
        "layout": "grid",
        "theme": "cd18f1e802ba5381",
        "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": 5,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "b3ec8449d91f6fb4",
        "type": "ui-base",
        "name": "My Dashboard",
        "path": "/dashboard",
        "appIcon": "",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-control"
        ],
        "showPathInSidebar": false,
        "headerContent": "none",
        "navigationStyle": "default",
        "titleBarStyle": "hidden",
        "showReconnectNotification": false,
        "notificationDisplayTime": 1,
        "showDisconnectNotification": false,
        "allowInstall": false
    },
    {
        "id": "cd18f1e802ba5381",
        "type": "ui-theme",
        "name": "Default Theme",
        "colors": {
            "surface": "#ffffff",
            "primary": "#0094CE",
            "bgPage": "#eeeeee",
            "groupBg": "#ffffff",
            "groupOutline": "#cccccc"
        },
        "sizes": {
            "density": "default",
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "4px",
            "widgetGap": "12px"
        }
    },
    {
        "id": "0878aef0fd6b55bf",
        "type": "global-config",
        "env": [],
        "modules": {
            "node-red-contrib-play-audio": "2.5.0",
            "node-red-dashboard": "3.6.6",
            "@flowfuse/node-red-dashboard": "1.30.2"
        }
    }
]

This template plays a tone in the browser.

Pass it a message with payload something like

{
  freq: 1000, // Hz
  gain: -10,    // In dB. 0 is max volume
  period: 1000, // msec
  fadeInTime = 100  // msec
}

It shows itself with some fixed text on the dashboard, you could remove that or make it dynamic if you wish.

[{"id":"6d52935d19f64c1a","type":"ui-template","z":"b451a10428b5266b","group":"4f87bd59a15b847e","page":"","ui":"","name":"Tone Player using listener","order":13,"width":6,"height":2,"format":"<template>\n  <div>\n    <p>Browser Tone Player</p>\n  </div>\n</template>\n\n<script>\nexport default {\n  mounted () {\n    this.$socket.on('msg-input:' + this.id, (msg) => {\n      //console.log(`msg received: ${JSON.stringify(this.msg)}`)\n      let newMsg = this.msg\n      if (!newMsg || !newMsg.payload) return\n\n      const { freq, gain, period=1700, fadeInTime = 100 } = newMsg.payload\n      if (!freq || (!period && period !== 0)) return\n\n      const audioCtx = new (window.AudioContext || window.webkitAudioContext)()\n      const osc = audioCtx.createOscillator()\n      const gainNode = audioCtx.createGain()\n\n      const linearGain = Math.pow(10, gain / 20)\n\n      osc.type = 'sine'\n      osc.frequency.setValueAtTime(freq, audioCtx.currentTime)\n\n      gainNode.gain.setValueAtTime(0, audioCtx.currentTime)\n      gainNode.gain.linearRampToValueAtTime(linearGain, audioCtx.currentTime + fadeInTime/1000)\n\n      osc.connect(gainNode)\n      gainNode.connect(audioCtx.destination)\n\n      osc.start()\n\n      setTimeout(() => {\n        try { osc.stop() } catch (e) {}\n        audioCtx.close()\n\n        // Send message back to Node-RED\n        this.send({ payload: { status: 'complete', freq, period }, _linkSource: newMsg._linkSource })\n      }, period)\n    })\n  }\n}\n</script>","storeOutMessages":true,"passthru":false,"templateScope":"local","className":"","x":470,"y":1840,"wires":[[]]},{"id":"4f87bd59a15b847e","type":"ui-group","name":"test","page":"c6ff182a4185f2f2","width":"6","height":"1","order":2,"showTitle":true,"className":"","visible":"true","disabled":"false","groupType":"default"},{"id":"c6ff182a4185f2f2","type":"ui-page","name":"Test page","ui":"ID-BASE-1","path":"/testpage","icon":"home","layout":"grid","theme":"c4cba76c368d7996","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":10,"className":"","visible":"true","disabled":"false"},{"id":"ID-BASE-1","type":"ui-base","name":"Dashboard","path":"/dashboard","appIcon":"","includeClientData":true,"acceptsClientConfig":["ui-control","ui-notification"],"showPathInSidebar":false,"headerContent":"page","titleBarStyle":"default","showReconnectNotification":false,"notificationDisplayTime":"1","showDisconnectNotification":true,"allowInstall":true},{"id":"c4cba76c368d7996","type":"ui-theme","name":"Test theme","colors":{"surface":"#ffffff","primary":"#0094ce","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"},"sizes":{"density":"default","pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}},{"id":"c39c092fe36464e0","type":"global-config","env":[],"modules":{"@flowfuse/node-red-dashboard":"1.30.2"}}]

Thank you for an answer, I will try it . But I need to play audio file.

Is it because the source needs to be a URL, not a file destination

The source is the url where the audio file can be fetched from (Audio Player only).

You said you didn't want .wav or mp3 files

Not TTS.

I need to play .wav or .mp3 files. Sorry for not obvious annotation.

So, how to play local audio file on client device? Client device doesn'h have an internet access. It was easy with Dashboard 1.

define a static web root on your server (via httpStatic in settings.js), place you audio file there and load them in a template node like you load images.