Cast Youtube to Roku
Casts a YouTube video to a Roku device. The YouTube URL is specified in the entry inject node and the IP address of the Roku is specified in the follow-on change node. Inject node can be modified to run on a scheduled task (for a YouTube alarm clock). You could also craft input nodes that deliver a URL to the change node.
Hope this helps someone; first time posting a flow! Enjoy!
EDIT: Added a flow to pull the top trending videos from YouTube via rss query and play the top trending video in the list.
[{"id":"5fed5dca.adb674","type":"tab","label":"Cast Youtube To Roku","disabled":false,"info":""},{"id":"7b9f3d57.477c24","type":"inject","z":"5fed5dca.adb674","name":"Play Specific Youtube Video","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"https://www.youtube.com/watch?v=Lrj2Hq7xqQ8","payloadType":"str","x":160,"y":620,"wires":[["7dc76446.58a2bc"]]},{"id":"eadf4a1e.e682b8","type":"debug","z":"5fed5dca.adb674","d":true,"name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":450,"y":440,"wires":[]},{"id":"523bf68d.b454d8","type":"function","z":"5fed5dca.adb674","name":"Convert To Roku Request","func":"function youtube_parser(url){\n var regExp = /^.*((youtu.be\\/)|(v\\/)|(\\/u\\/\\w\\/)|(embed\\/)|(watch\\?))\\??v?=?([^#&?]*).*/;\n var match = url.match(regExp);\n return (match&&match[7].length==11)? match[7] : false;\n}\nvar ips = msg.roku_ip;\nif(!Array.isArray(ips)){\n ips = [ips];\n}\nvar endpoint = msg.roku_endpoint;\nvar id = youtube_parser(msg.payload);\nvar port = msg.roku_port;\n\nips.forEach(function(ip) {\n var request = \"http://\" + ip + \":\" + port + endpoint + id;\n node.send({\"url\": request})\n});","outputs":1,"noerr":0,"initialize":"","finalize":"","x":510,"y":360,"wires":[["22d5408d.5b563"]]},{"id":"22d5408d.5b563","type":"http request","z":"5fed5dca.adb674","name":"Send To Roku(s)","method":"POST","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":490,"y":400,"wires":[["eadf4a1e.e682b8"]]},{"id":"d1529c96.dd481","type":"comment","z":"5fed5dca.adb674","name":"README: Single Video","info":"Supported single-video formats:\nhttp://www.youtube.com/watch?v=0zM3nApSvMg&feature=feedrec_grec_index\nhttp://www.youtube.com/user/IngridMichaelsonVEVO#p/a/u/1/QdK8U-VIH_o\nhttp://www.youtube.com/v/0zM3nApSvMg?fs=1&hl=en_US&rel=0\nhttp://www.youtube.com/watch?v=0zM3nApSvMg#t=0m10s\nhttp://www.youtube.com/embed/0zM3nApSvMg?rel=0\nhttp://www.youtube.com/watch?v=0zM3nApSvMg\nhttp://youtu.be/0zM3nApSvMg\n\nFunctionality pulled from:\nhttps://stackoverflow.com/questions/3452546/how-do-i-get-the-youtube-video-id-from-a-url/8260383#8260383\n\nCredit for the regex magic goes to Lasnv and the StackExchange community.","x":140,"y":580,"wires":[]},{"id":"7dc76446.58a2bc","type":"change","z":"5fed5dca.adb674","name":"Roku Info","rules":[{"t":"set","p":"roku_ip","pt":"msg","to":"[\"192.168.11.104\",\"192.168.11.193\"]","tot":"json"},{"t":"set","p":"roku_endpoint","pt":"msg","to":"/launch/837?contentID=","tot":"str"},{"t":"set","p":"roku_port","pt":"msg","to":"8060","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":320,"wires":[["523bf68d.b454d8"]]},{"id":"f5af682a.eb7ed8","type":"comment","z":"5fed5dca.adb674","name":"Change roku_ip in this node.","info":"Change roku_ip in this node. This is a json entry so you can specify multiple ip's:\n\n[\"192.168.11.104\",\"192.168.11.193\"]\n\nor a single ip:\n\n[\"192.168.11.104\"] or just \"192.168.11.104\"","x":500,"y":280,"wires":[]},{"id":"c586e9b3.83cb38","type":"http request","z":"5fed5dca.adb674","name":"Get Top Trending RSS","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://www.youtube.com/feeds/videos.xml?playlist_id=PLrEnWoR732-BHrPp_Pm8_VleD68f9s14-","tls":"","persist":false,"proxy":"","authType":"","x":180,"y":80,"wires":[["5779e148.f6761"]]},{"id":"c0be378a.cc7ff8","type":"debug","z":"5fed5dca.adb674","d":true,"name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":130,"y":200,"wires":[]},{"id":"3b5ed79c.756468","type":"inject","z":"5fed5dca.adb674","name":"Play Top Trending Youtube Video","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":170,"y":40,"wires":[["c586e9b3.83cb38"]]},{"id":"5779e148.f6761","type":"function","z":"5fed5dca.adb674","name":"Get All URLs","func":"function detectURLs(message) {\n var expression = /https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)?/gi;\n var urlRegex = /(((https?:\\/\\/)|(www\\.))[^\\s]+)/g;\n return message.match(expression)\n}\n\nnode.send({\"payload\": detectURLs(msg.payload)});","outputs":1,"noerr":0,"initialize":"","finalize":"","x":150,"y":120,"wires":[["78fbee5.dbd2b1"]]},{"id":"78fbee5.dbd2b1","type":"function","z":"5fed5dca.adb674","name":"Get Top Trending Youtube","func":"var urls = msg.payload\nvar watch_urls = []\nurls.forEach(function(url) {\n if(url.includes(\"watch?v=\")){\n watch_urls.push(url);\n }\n});\nnode.send({\"payload\": watch_urls[0]})","outputs":1,"noerr":0,"initialize":"","finalize":"","x":190,"y":160,"wires":[["c0be378a.cc7ff8","7dc76446.58a2bc"]]},{"id":"71f12d76.e37b94","type":"debug","z":"5fed5dca.adb674","d":true,"name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":110,"y":520,"wires":[]},{"id":"90230d23.ff4b5","type":"inject","z":"5fed5dca.adb674","name":"Play First in Playlist","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"https://www.youtube.com/watch?v=GavgwfcE33k&list=PL4fGSI1pDJn6O1LS0XSdF3RyO0Rq_LDeI","payloadType":"str","x":130,"y":320,"wires":[["f6c28c30.a6ed3"]]},{"id":"cbc41654.60c978","type":"function","z":"5fed5dca.adb674","name":"Get All URLs","func":"function detectURLs(message) {\n var expression = /https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)?/gi;\n return message.match(expression)\n}\n\nnode.send({\"payload\": detectURLs(msg.payload)});","outputs":1,"noerr":0,"initialize":"","finalize":"","x":130,"y":440,"wires":[["41472835.fef5d8"]]},{"id":"41472835.fef5d8","type":"function","z":"5fed5dca.adb674","name":"Get Top New Youtube","func":"var urls = msg.payload\nvar watch_urls = []\nurls.forEach(function(url) {\n if(url.includes(\"watch?v=\")){\n watch_urls.push(url);\n }\n});\nnode.send({\"payload\": watch_urls[0]})","outputs":1,"noerr":0,"initialize":"","finalize":"","x":160,"y":480,"wires":[["71f12d76.e37b94","7dc76446.58a2bc"]]},{"id":"f6c28c30.a6ed3","type":"function","z":"5fed5dca.adb674","name":"","func":"var prefix=\"https://www.youtube.com/feeds/videos.xml?playlist_id=\"\nreturn {\"url\": prefix + msg.payload.split(\"=\").slice(-1)[0] }","outputs":1,"noerr":0,"initialize":"","finalize":"","x":120,"y":360,"wires":[["fa60e930.c4bbe8"]]},{"id":"fa60e930.c4bbe8","type":"http request","z":"5fed5dca.adb674","name":"Get Top Trending RSS","method":"GET","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":160,"y":400,"wires":[["cbc41654.60c978"]]},{"id":"a1251286.65f01","type":"comment","z":"5fed5dca.adb674","name":"README: Playlist Flow","info":"This flow plays the first video that appears in a playlist. This is useful for getting quick access to top music, top news stories, top live streams, etc.\n\nFormat is strict and must adhere to the below:\nhttps://www.youtube.com/watch?v=GavgwfcE33k&list=PL4fGSI1pDJn6O1LS0XSdF3RyO0Rq_LDeI\n\nThe line is split at the = to get the id at the end; so whatever the URL the playlist ID just needs to be at the end.","x":140,"y":280,"wires":[]}]