4

I'm working on chrome extension to make Netflix video player opens the hidden changing quality panel.

Netflix Changes the video quality automatically depending on the speed of your Internet.

But there is a known way to open the hidden panel and change the quality manually.

This is the method to open the hidden panel in HTML5 Player Only CTRL + SHIFT + ALT + S

Is there a way when the user clicks on Title,
it simulates the keyboard keys CTRL + SHIFT + ALT + S ?

$('body').on('click', 'div.player-status .player-status-main-title', function () {
    alert('Clicked!');
    //Simulate?
});
Vikrant
  • 4,920
  • 17
  • 48
  • 72
Jim
  • 1,430
  • 5
  • 18
  • 41
  • If it's an HTML5 function, that means it's running with javascript. Why not skip the keypress step entirely and just identify and trigger the function to open the panel? – DiMono Nov 10 '14 at 17:55
  • @DiMono I tried but I'm not that good at javascript, I failed to identify the function, If you need netflix account to try yourself I will provide you with account – Jim Nov 10 '14 at 18:02

2 Answers2

11

Try this (can't test, since I can't access Netflix tested, confirmed working as of 11.11.14).

function simulateCtrlShiftAltS() {
  // Prepare function for injection into page
  function injected() {
    // Adjust as needed; some events are only processed at certain elements
    var element = document.body;

    function keyEvent(el, ev) {
      var eventObj = document.createEvent("Events");
      eventObj.initEvent(ev, true, true);

      // Edit this to fit
      eventObj.keyCode = 83;
      eventObj.which = 83;
      eventObj.ctrlKey = true;
      eventObj.shiftKey = true;
      eventObj.altKey = true;

      el.dispatchEvent(eventObj);
    }

    // Trigger all 3 just in case
    keyEvent(element, "keydown");
    keyEvent(element, "keypress");
    keyEvent(element, "keyup");
  }

  // Inject the script
  var script = document.createElement('script');
  script.textContent = "(" + injected.toString() + ")();";
  (document.head||document.documentElement).appendChild(script);
  script.parentNode.removeChild(script);
}

This code is adapted from comments to the answer you linked: https://stackoverflow.com/a/10520017/2518069

To be precise, from this example: http://jsbin.com/awenaq/4

Regarding "adjust as needed":

Some pages process events on an element and some wait until it bubbles to something like body or document. You can spy on this by going to Dev Tools, Sources, and enabling Event Listener Breakpoints > Keyboard. From there, you'll be able to see which event triggers the change you need, and which element catches it - it will be in this when the breakpoint triggers.

Also, note that all of this may not work if the player is actually a plugin. I tested this on YouTube HTML5 player: it works for everything but fullscreen (which I believe to be a security restriction?), and is processed at element #movie_player.

Community
  • 1
  • 1
Xan
  • 74,770
  • 16
  • 179
  • 206
  • Thank you, It seems your code trigger the keys (I checked the console and I'm sure it's working) but Netflix not respond like when I press myself the keys on keyboard! .... If you need netflix account to try yourself I will provide you with account just need a private way to send you my account – Jim Nov 11 '14 at 11:41
  • I did and this what I get http://jsfiddle.net/Jim_Toth/yn9804q5/ see the line 18531, I tried to trigger the function itself but I get console error Uncaught ReferenceError: m is not defined – Jim Nov 11 '14 at 13:23
  • You shouldn't try to trigger the function; you just need to know which element catches the event. This will be `this` in Scope Variables at the moment the breakpoint is tripped. – Xan Nov 11 '14 at 13:25
  • this: body#page-WiPlayer.ua-chrome.ua-chrome-38.le-blink.os-win.os-win-81.ua-not-ie.sc-wn.sc-strm.struts.global-header – Jim Nov 11 '14 at 13:39
  • That is for manually triggered events that actually show the interface? – Xan Nov 11 '14 at 13:41
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/64715/discussion-between-xan-and-jim). – Xan Nov 11 '14 at 14:10
1

Since it's not shure that the Netflix player code sets the event-listeners with jQuery, I would recommend a solution with native js-events. It's also possible that Netflix needs an event-timing that's more natural than simply firing four key-events in 1ms (see this SO - question).

The function below creates four native keydown-KeyboardEvents with the right properties for the keys in the order you gave. They are fired with a delay of 50ms in between to simulate a more natural behaviour. I have added an immediately following keypress-event with 'S', because some devices trigger on that.

Inside the Timeouts an IIFE (immediately invoked function expression) is used to pass the events as arguments into the Timeout-callback.

function simulateCtrlShiftAltS() {
    var keys = [
            {view: document.defaultView, bubbles: true, location: 1, keyLocation: 1, keyIdentifier: 'U+0017', key: 'Control', keyCode: 17, which: 17, altKey: false, ctrlKey: true, shiftKey: false},
            {view: document.defaultView, bubbles: true, location: 1, keyLocation: 1, keyIdentifier: 'U+0016', key: 'Shift', keyCode: 16, which: 16, altKey: false, ctrlKey: true, shiftKey: true},
            {view: document.defaultView, bubbles: true, location: 1, keyLocation: 1, keyIdentifier: 'U+0018', key: 'Alt', keyCode: 18, which: 18, altKey: true, ctrlKey: true, shiftKey: true},
            {view: document.defaultView, bubbles: true, location: 0, keyLocation: 0, keyIdentifier: 'U+0053', key: 'S', keyCode: 83, which: 83, altKey: true, ctrlKey: true, shiftKey: true}
        ], body = document.body;
    for (var i = 0; i < 5; i++) {
        var events = [new KeyboardEvent(i == 4 ? 'keyup' : 'keydown', keys[i] || keys[3])];
        if (i == 3) events.push(new KeyboardEvent('keypress', keys[i]));
        if (events[0].keyCode == 0) events.forEach(function(ev) {
            ['keyCode', 'which'].forEach(function(p) {
                delete ev[p]; Object.defineProperty(ev, p, {value: (keys[i] || keys[3])[p], enumerable: true});
            });
        });
        window.setTimeout(function(evts) {
            return function() {evts.forEach(function(ev) {body.dispatchEvent(ev);});};
        }(events), i * 50);
    }
}

You can simply pass the function to the click-handler:

$('body').on('click', 'div.player-status .player-status-main-title', simulateCtrlShiftAltS);

EDIT: It has been found that webkit browsers don't set the keyCode- and which-property correctly. I don't recommend usage of .initKeyboardEvent() because it's deprecated and browsers handles it very different. So I added a method to redefine these properties in the event-object. It's inspired by termi's answer on this SO-question. I have also switched from T to S.

Now this FIDDLE works for FF, Chrome and Opera but not IE and Safari (no Implementation of KeyboardEvent API). I'll try to find and implement a simple solution for them.

EDIT 2: Since it's still not working we add a keyup-event on 'S'. See the changed code. If that's not enough we will stepwise release also ALT, SHIFT, and CTRL before we give up.

Community
  • 1
  • 1
Martin Ernst
  • 3,199
  • 1
  • 12
  • 12
  • 1
    One may need to inject this [into the page content](http://stackoverflow.com/questions/9515704/building-a-chrome-extension-inject-code-in-a-page-using-a-content-script). – Xan Nov 10 '14 at 14:28
  • I tested on Netflix and It's not working... I think there is a problem with passing the T See http://jsfiddle.net/Jim_Toth/0wuj6s2j/1/ and here when I remove the T key checker works grate http://jsfiddle.net/Jim_Toth/0wuj6s2j/ – Jim Nov 10 '14 at 15:52
  • @Jim `T`-keyCode is `84` not 16 (your alert-if). [It's working in FF](http://jsfiddle.net/0wuj6s2j/6/). But Webkits sets `keyCode` always to `0` when initializing the KeyboardEvent. Don't know why, I'll look for a solution. – Martin Ernst Nov 10 '14 at 16:12
  • BTW the key not (T) It's (S), sorry about that... and also please remove the extra } from $('body').on('click', 'div.player-status .player-status-main-title',..... – Jim Nov 11 '14 at 10:16
  • @MartinErnst I tested the new edit but unfortunately I'm facing same problem I'm facing with Xan's Code, Netflix not respond for the trigger like when I press myself the keys on keyboard :( – Jim Nov 11 '14 at 13:10
  • @MartinErnst The principal problem is described in my first comment. This needs to be wrapped in a ` – Xan Nov 11 '14 at 14:36
  • @Xan That's why I marked your first comment. Thanks for testing and the points. I just read your `chat`. Fine solution and the most important: OP is happy! – Martin Ernst Nov 11 '14 at 14:49