Web Radio Tuner

Hello All.

My Marantz-Cinema-70 uses InTune to stream web radio stations but unfortunately one of the stations we listen to is no longer streaming via this service. Raspberry PI (RPI) has Node-RED running and there is a flow controlling some Marantz functions directly from dashboard. I had in mind to use RPI as music server with some basic functionalities. Node-RED forum post URL in msg.payload to play audio, UI Template deals with a Web Audio flow. After some digging, flow was adapted to stream requested radio stations and results are the same as InTune or MyTuner. There is no publicity nor soliciting to upgrade to premium version!

When station is changed directly from RPI Node-RED server or via RealVNC connection it works like a charm. However, when using Safari from either iPhone or iPad to connect to RPI Node-RED Server, nothing happens in RPI. I realized that sound streams in client devices. Here is copy of used flow.

Does someone have some tips to force template widget to issue call only in server device and not in clients.

Node-RED V 4.0.2
Node JS V 20.15.1

Thanks in advance
Quike

[
    {
        "id": "781005ba.a02be4",
        "type": "inject",
        "z": "2f52681b.fb4b08",
        "name": "",
        "props": [
            {
                "p": "options",
                "v": "[{\"Stop\":\"\"},{\"N-Joy\":\"https://cdn.bweb.bg/radio/njoy\"},{\"CBC\":\"https://playerservices.streamtheworld.com/api/livestream-redirect/CBLAFM_CBC\"},{\"RNE 1\":\"https://dispatcher.rndfnk.com/crtve/rne1/main/mp3/high\"},{\"Los Cuarenta\":\"https://playerservices.streamtheworld.com/api/livestream-redirect/LOS40\"},{\"RMC\":\"https://audio.bfmtv.com/rmcradio_128\"},{\"Europe 1\":\"http://stream.europe1.fr/europe1\"},{\"Studio Brussel\":\"http://icecast.vrtcdn.be/stubru-high\"},{\"MNM Hits\":\"http://icecast.vrtcdn.be/mnm_hits-high\"},{\"Radio 1\":\"http://icecast.vrtcdn.be/radio1-high\"}]",
                "vt": "json"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "x": 130,
        "y": 1300,
        "wires": [
            [
                "7e15de16.d3b868"
            ]
        ]
    },
    {
        "id": "7e15de16.d3b868",
        "type": "ui_dropdown",
        "z": "2f52681b.fb4b08",
        "name": "",
        "label": "Radio",
        "tooltip": "Choose your station",
        "place": "Web Radio",
        "group": "165e1e1a.e752fa",
        "order": 4,
        "width": "0",
        "height": "0",
        "passthru": true,
        "multiple": false,
        "options": [],
        "payload": "",
        "topic": "radio",
        "topicType": "str",
        "className": "",
        "x": 270,
        "y": 1300,
        "wires": [
            [
                "31724f4f.8bc6a8"
            ]
        ]
    },
    {
        "id": "31724f4f.8bc6a8",
        "type": "change",
        "z": "2f52681b.fb4b08",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "template",
                "pt": "msg",
                "to": "'<!DOCTYPE html>\t<html>\t<body>\t\t<audio autoplay>\t  <source src=\"' & payload & '.mp3\" type=\"audio/mpeg\">\t  <source src=\"' & payload & '.ogg\" type=\"audio/ogg\">\t</audio>\t\t</body>\t</html>'",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 450,
        "y": 1300,
        "wires": [
            [
                "c96c65d6.bfc148"
            ]
        ]
    },
    {
        "id": "c96c65d6.bfc148",
        "type": "ui_template",
        "z": "2f52681b.fb4b08",
        "group": "165e1e1a.e752fa",
        "name": "test",
        "order": 5,
        "width": 0,
        "height": 0,
        "format": "",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "resendOnRefresh": false,
        "templateScope": "local",
        "className": "",
        "x": 620,
        "y": 1300,
        "wires": [
            [
                "ac1c43a9d393f091"
            ]
        ]
    },
    {
        "id": "ac1c43a9d393f091",
        "type": "debug",
        "z": "2f52681b.fb4b08",
        "name": "debug 19",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 800,
        "y": 1300,
        "wires": []
    },
    {
        "id": "165e1e1a.e752fa",
        "type": "ui_group",
        "name": "Tuner",
        "tab": "f9b58883.fa613",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "f9b58883.fa613",
        "type": "ui_tab",
        "name": "WebRadio",
        "icon": "dashboard",
        "order": 4,
        "disabled": false,
        "hidden": false
    }
]

JSONata does not use template strings.
So you would need to add \n and use & and have quotes on each line to format a string to several lines.
e.g.

'blah blah\n' &
'blah' & $$.payload & 'blah\n' &
'blah'

But it would be simpler in a template node.
e.g.

[{"id":"781005ba.a02be4","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"options","v":"[{\"Stop\":\"\"},{\"N-Joy\":\"https://cdn.bweb.bg/radio/njoy\"},{\"CBC\":\"https://playerservices.streamtheworld.com/api/livestream-redirect/CBLAFM_CBC\"},{\"RNE 1\":\"https://dispatcher.rndfnk.com/crtve/rne1/main/mp3/high\"},{\"Los Cuarenta\":\"https://playerservices.streamtheworld.com/api/livestream-redirect/LOS40\"},{\"RMC\":\"https://audio.bfmtv.com/rmcradio_128\"},{\"Europe 1\":\"http://stream.europe1.fr/europe1\"},{\"Studio Brussel\":\"http://icecast.vrtcdn.be/stubru-high\"},{\"MNM Hits\":\"http://icecast.vrtcdn.be/mnm_hits-high\"},{\"Radio 1\":\"http://icecast.vrtcdn.be/radio1-high\"}]","vt":"json"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","x":130,"y":820,"wires":[["7e15de16.d3b868"]]},{"id":"7e15de16.d3b868","type":"ui_dropdown","z":"d1395164b4eec73e","name":"","label":"Radio","tooltip":"Choose your station","place":"Web Radio","group":"165e1e1a.e752fa","order":4,"width":"0","height":"0","passthru":true,"multiple":false,"options":[],"payload":"","topic":"radio","topicType":"str","className":"","x":270,"y":820,"wires":[["96712f31b01fd6c3"]]},{"id":"96712f31b01fd6c3","type":"template","z":"d1395164b4eec73e","name":"","field":"template","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!DOCTYPE html>\n<html>\n<body>\n\n<audio autoplay>\n  <source src=\"{{{payload}}}.mp3\" type=\"audio/mpeg\">\n  <source src=\"{{{payload}}}.ogg\" type=\"audio/ogg\">\n</audio>\n\n</body>\n</html>","output":"str","x":420,"y":780,"wires":[["c96c65d6.bfc148"]]},{"id":"c96c65d6.bfc148","type":"ui_template","z":"d1395164b4eec73e","group":"165e1e1a.e752fa","name":"test","order":5,"width":0,"height":0,"format":"","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","className":"","x":620,"y":820,"wires":[["ac1c43a9d393f091"]]},{"id":"ac1c43a9d393f091","type":"debug","z":"d1395164b4eec73e","name":"debug 19","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":800,"y":820,"wires":[]},{"id":"165e1e1a.e752fa","type":"ui_group","name":"Tuner","tab":"f9b58883.fa613","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"f9b58883.fa613","type":"ui_tab","name":"WebRadio","icon":"dashboard","order":4,"disabled":false,"hidden":false}]

Hello E1cid,

Thanks for your prompt response.
I disabled old flow and used the one you posted with template node.

Everything works fine when opening dashboard from same Raspberry PI (RPI) as Node-RED server.

If I access dashboard with Safari or Chrome from another device such as an iPad and change the radio station, RPI keeps playing old station while iPad plays the new station. Dashboard dropdown ui and debug node show new station.

Thanks in advance for your help.

The dropdown node emits a property called msg.socketid, due to this the ui-template is only updated on the same browser. Try deleting the msg.socketid, then all browsers running the ui-template would recieve the new msg.template.
e.g.

[{"id":"781005ba.a02be4","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"options","v":"[{\"Stop\":\"\"},{\"N-Joy\":\"https://cdn.bweb.bg/radio/njoy\"},{\"CBC\":\"https://playerservices.streamtheworld.com/api/livestream-redirect/CBLAFM_CBC\"},{\"RNE 1\":\"https://dispatcher.rndfnk.com/crtve/rne1/main/mp3/high\"},{\"Los Cuarenta\":\"https://playerservices.streamtheworld.com/api/livestream-redirect/LOS40\"},{\"RMC\":\"https://audio.bfmtv.com/rmcradio_128\"},{\"Europe 1\":\"http://stream.europe1.fr/europe1\"},{\"Studio Brussel\":\"http://icecast.vrtcdn.be/stubru-high\"},{\"MNM Hits\":\"http://icecast.vrtcdn.be/mnm_hits-high\"},{\"Radio 1\":\"http://icecast.vrtcdn.be/radio1-high\"}]","vt":"json"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","x":130,"y":820,"wires":[["7e15de16.d3b868"]]},{"id":"7e15de16.d3b868","type":"ui_dropdown","z":"d1395164b4eec73e","name":"","label":"Radio","tooltip":"Choose your station","place":"Web Radio","group":"165e1e1a.e752fa","order":4,"width":"0","height":"0","passthru":true,"multiple":false,"options":[],"payload":"","topic":"radio","topicType":"str","className":"","x":270,"y":820,"wires":[["fb3f2496becb786a","3fe47091ce6bbe37"]]},{"id":"fb3f2496becb786a","type":"debug","z":"d1395164b4eec73e","name":"debug 2563","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":350,"y":860,"wires":[]},{"id":"3fe47091ce6bbe37","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"delete","p":"socketid","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":260,"y":780,"wires":[["96712f31b01fd6c3"]]},{"id":"96712f31b01fd6c3","type":"template","z":"d1395164b4eec73e","name":"","field":"template","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!DOCTYPE html>\n<html>\n<body>\n\n<audio autoplay>\n  <source src=\"{{{payload}}}.mp3\" type=\"audio/mpeg\">\n  <source src=\"{{{payload}}}.ogg\" type=\"audio/ogg\">\n</audio>\n\n</body>\n</html>","output":"str","x":420,"y":780,"wires":[["c96c65d6.bfc148"]]},{"id":"c96c65d6.bfc148","type":"ui_template","z":"d1395164b4eec73e","group":"165e1e1a.e752fa","name":"test","order":5,"width":0,"height":0,"format":"","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","className":"","x":620,"y":820,"wires":[["ac1c43a9d393f091"]]},{"id":"ac1c43a9d393f091","type":"debug","z":"d1395164b4eec73e","name":"debug 19","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":800,"y":820,"wires":[]},{"id":"165e1e1a.e752fa","type":"ui_group","name":"Tuner","tab":"f9b58883.fa613","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"f9b58883.fa613","type":"ui_tab","name":"WebRadio","icon":"dashboard","order":4,"disabled":false,"hidden":false}]

Not all dashboard nodes respond to socketid, i.e switch nodes as they are either on or off and can not be different on different browsers, not sure how the dropdown uses the socketid. You will need to experiment.

[edit]
You may find it easier to create your own dropdown using the ui-template node, as it can be used with socketid.
Or you could use the ip of each device to show/hide different dropdowns for each device/browser, each in there own group, using ui_control node.

Hello E1cid,

Deleting msg.socketid did the job!
Sound is now in both devices. This is enough for my needs.

Some stations seem to require to stop streaming before listening to them.
This is probably the site or just the fact that it's late at night and I need more fiddling.
Thanks a lot for your help.

Best regards,

Quike :grinning:

1 Like