Read the statement by Michael Teeuw here.
Controlling Embedded Youtube Video on MM
-
@Jopyth, I realized i was using an older version of your remote control. However, after updating the remote control module, i inserted your recommended line back into this code:
// edit menu buttons "show-all-button": function() { var parent = document.getElementById("visible-modules-results"); var buttons = parent.children; for (var i = 0; i < buttons.length; i++) { if (buttons[i].id!="module_5_youtube"){ if (Remote.hasClass(buttons[i], "external-locked")) { continue; } buttons[i].className = buttons[i].className.replace("toggled-off", "toggled-on"); Remote.showModule(buttons[i].id); var notification = "SCREEN_WAKEUP"; Remote.getWithStatus("action=NOTIFICATION&n"+"otification=" + notification ); } else{ if (Remote.hasClass(buttons[i], "external-locked")) { continue; } buttons[i].className = buttons[i].className.replace("toggled-on", "toggled-off"); Remote.hideModule(buttons[i].id); }
I was testing this code with paviro’s PIR module ( https://github.com/paviro/MMM-PIR-Sensor) on this line which is found from his MMM-PIR-Sensor.js .
notificationReceived: function(notification, payload) { if (notification === "SCREEN_WAKEUP"){ this.sendNotification(notification, payload) } },
I modified the PIR code in such a way that when it receives the SCREEN_WAKEUP notification , it will perform certain actions for me rather than turning on the monitor.
-
Hi all, im not too sure if i have made any mistake regarding the structure of MMM.
I placed my
notificationReceived
at the front end of embedded youtube, which i called it youtube.js( it doesnt have any node_helper) :Here’s the code of my youtube.js , the codes are heavily based on a the default module called “compliments” :
module.register("youtube",{ // Module config defaults. defaults: { updateInterval: 30000, fadeSpeed: 4000 }, // Define required scripts. getScripts: function() { return ["moment.js"]; // exec("sudo python /home/pi/NicoRFID/RFID_playlist.py"); }, getStyles: function() { return [ 'script.css', // will try to load it from the vendor folder, otherwise it will load is from the module folder. ] }, // Define start sequence. start: function() { Log.info("Starting module: " + this.name); // Schedule update timer. var self = this; setInterval(function() { self.updateDom(self.config.fadeSpeed); }, this.config.updateInterval); }, /* randomIndex(compliments) * Generate a random index for a list of compliments. * * argument compliments Array - Array with compliments. * * return Number - Random index. */ /* complimentArray() * Retrieve an array of compliments for the time of the day. * * return compliments Array - Array with compliments for the time of the day. */ /* complimentArray() * Retrieve a random compliment. * * return compliment string - A compliment. */ notificationReceived: function(notification, payload) { if (notification === "PAUSE_VIDEO"){ pausethevideo() } else if (notification === "PLAY_VIDEO"){ playthevideo() } }, // Override dom generator. getDom: function() { //var complimentText = this.randomCompliment(); //var complimentText = "Hi NUS GOD Puay Hiang "; //var compliment = document.createTextNode(complimentText); var wrapper = document.createElement("div"); wrapper.className = "thin xlarge bright"; function playthevideo(){ var myPlayer = document.getElementById('my-video'); myPlayer.playVideo(); }; function stopthevideo(){ var myPlayer = document.getElementById('my-video'); myPlayer.stopVideo(); }; function pausethevideo(){ var myPlayer = document.getElementById('my-video'); myPlayer.pauseVideo(); }; wrapper.innerHTML='<div> <div> allowfullscreen></div></div>'; //wrapper.appendChild(compliment); return wrapper; } });
So with the
notificationReceived
line, i intend to control my video using the remote control with these codes :/ edit menu buttons "show-all-button": function() { var parent = document.getElementById("visible-modules-results"); var buttons = parent.children; for (var i = 0; i < buttons.length; i++) { if (buttons[i].id!="module_5_youtube"){ if (Remote.hasClass(buttons[i], "external-locked")) { continue; } buttons[i].className = buttons[i].className.replace("toggled-off", "toggled-on"); Remote.showModule(buttons[i].id); var notification = "PAUSE_VIDEO"; Remote.getWithStatus("action=NOTIFICATION&n"+"otification=" + notification ); } else{ if (Remote.hasClass(buttons[i], "external-locked")) { continue; } buttons[i].className = buttons[i].className.replace("toggled-on", "toggled-off"); Remote.hideModule(buttons[i].id); }
Am i doing something wrong here?
-
@Jopyth ,
I managed to have some developments with your remote control module’s
sendNotifcation
command. I hooked up the MM using a browser and observed( using dev console, Note to beginners: press F12 on a browser to access this cool feature ) that a notification was send from MM Remote. This means that you were right all along, just that i didnt know how to observe thesendNotification
command via dev console.Currently, i have another issue. My youtube.js module receives the “PLAY_VIDEO” or “PAUSE_VIDEO” notification but is not able to perform what was desired.
Here’s my snippet of my code from my youtube.js :
notificationReceived: function(notification, payload) { if (notification === "PAUSE_VIDEO"){ pausethevideo() } if (notification === "PLAY_VIDEO"){ playthevideo() } }, getDom: function() { var wrapper = document.createElement("div"); wrapper.className = "thin xlarge bright"; function playthevideo(){ var myPlayer = document.getElementById('my-video'); myPlayer.playVideo(); }; function stopthevideo(){ var myPlayer = document.getElementById('my-video'); myPlayer.stopVideo(); }; function pausethevideo(){ var myPlayer = document.getElementById('my-video'); myPlayer.pauseVideo(); }; wrapper.innerHTML='<div> <div> allowfullscreen></div></div>'; //youtube video link found here. return wrapper; } });
However, i got an error from dev console :
Uncaught TypeError: Cannot read property 'pauseVideo' of null at Class.notificationReceived (youtube.js:69)
Im suspecting that my pauseVideo/playVideo function wasn’t recognised as it is
getDom
.Will appreciate any help or advice !
-
@zichao92 the access to those functions is limited to the getDom function.
you should put the definitions outside like
playthevideo: function() { //do the stuff }
and call the function like
this.playthevideo()
-
@strawberry-3.141 said in Controlling Embedded Youtube Video on MM:
playthevideo: function() {
//do the stuff
}Hi there,
I tried your recommendation but i got this error
Uncaught TypeError: Cannot read property 'playVideo' of null
.
Which is coming from this code:playthevideo: function() { var myPlayer = document.getElementById('my-video'); myPlayer.playVideo(); },
I suspect that the problem is that the above function is not being recognise as my embedded youtube codes still lies in the getDom function, which has the
allowscriptaccess="awalys"
that allows the user to control the video. I tried to extract out from the getDom function but i think my syntax is wrong. Here’s the full code of the youtube function that’s in the getDom function.wrapper.innerHTML='<div> <div> //(youtube link here ) controls=0&showinfo=0&rel=0&autoplay=1" allowscriptaccess="always" name="my-video" frameborder="0" enablejsapi=1&version=3&playerapiid=ytplayer" type="application/x-shockwave-flash"> allowfullscreen></div></div>';
-
@zichao92 because there is no html element that has the id your looking for so
var myPlayer = document.getElementById('my-video');
is null -
Hi @strawberry-3.141 ,
Thanks for the clarification!
I have addedid = "my-vdieo"
into my code, however, it produced another error :Uncaught TypeError: myPlayer.playVideo is not a function at Class.playthevideo (youtube.js:69)
It’s not able to detect the function. After doing some readings about embedded YouTube videos, i came across this site :
https://developers.google.com/youtube/js_api_reference#onYouTubePlayerReadyIt was mentioned that i require a callback function named onYouTubePlayerReady. The API will call this function when the player is fully loaded and the API is ready to receive calls.
From there, I should be able to control my video. However, since this function can only be called in getDom function, im not too sure how it should work from here.
-
@zichao92 do you have your code on github?
-
Hi @strawberry-3.141 ,
I just uploaded to github ( not too sure if i have done it correctly , first time using github) but here you go.
https://github.com/zichao92/youtube/tree/Remote-
Edit 1: I’m still using an older version of Remote Control module by Jopyth, it’s more stable on my MagicMirror( less laggy etc). Im not too sure why though
-
@zichao92 I cleaned up your module
Module.register("youtube",{ start: function() { Log.info("Starting module: " + this.name); }, getStyles: function() { return ['script.css']; }, sendCommand: function(cmd){ var myPlayer = document.getElementById('my-video'); if(myPlayer){ myPlayer.contentWindow.postMessage(JSON.stringify({ "event": "command", "func": cmd }), "*"); } }, notificationReceived: function(notification, payload) { if (notification === "PAUSE_VIDEO"){ this.sendCommand("pauseVideo"); } if (notification === "PLAY_VIDEO"){ this.sendCommand("playVideo"); } }, getDom: function() { var wrapper = document.createElement("div"); var background = document.createElement("div"); background.classList.add("video-background"); var foreground = document.createElement("div"); foreground.classList.add("video-foreground"); var iframe = document.createElement("iframe"); iframe.setAttribute("id", "my-video"); iframe.setAttribute("src", "https://www.youtube.com/embed/5kIe6UZHSXw?enablejsapi=1&autoplay=1"); iframe.setAttribute("frameborder", "0"); iframe.setAttribute("type", "text/html"); foreground.appendChild(iframe); background.appendChild(foreground); wrapper.appendChild(background); return wrapper; } });