I am developing a Google Chrome extension that needs to take over all the controls of a YouTube video (play, pause, next, previous, change the volume, start video at X seconds, etc). I tried the following approaches:
First approach: with content_scripts
My manifest.json
contains the following:
"content_scripts": [
{
"matches": ["https://www.youtube.com/*"],
"js": ["scripts/jquery.js", "scripts/in_page.js"]
}
],
I'm loading the scripts for every YouTube link, and not only /watch*
because now YouTube navigation is fully using AJAX, therefore the page is not entirely refreshed, and if I was on a search page and then clicked on a video, the extension wouldn't have loaded my content_scripts
.
How I took over the controls
I successfully managed to trigger simple click events on the YouTube player, such as Play, Pause, Previous video, Next video.
For instance, this works to pause the video:
$("#player-api .html5-video-controls .ytp-button-pause").trigger("click");
But it seems that I can't trigger events such as clicking on the progress bar to play from a specific moment of the video or restart the video.
I tried this piece of code without success (using jQuery's $.Event
):
var click = $.Event("click");
click.clientX = 0; // Beginning of the video
click.clientY = 0; // I also tried several other coordinates
$("#player-api .html5-video-controls .html5-progress-bar").trigger(click);
(And I also tried clicking on every child of the .html5-progress-bar
, but nothing worked.)
Second approach: with an injected script
As I seemed to have encountered a dead-end with my first approach, I then tried something else: injecting a script directly inside the page.
My manifest.json
contains the following:
"content_scripts": [
{
"matches": ["https://www.youtube.com/*"],
"js": ["scripts/jquery.js", "scripts/isolated.js"]
}
],
"web_accessible_resources": [
"scripts/injected.js"
],
Contents of isolated.js
var s = document.createElement("script");
s.src = chrome.extension.getURL("scripts/injected.js");
s.onload = function() {
this.parentNode.removeChild(this);
};
(document.head || document.documentElement).appendChild(s);
Contents of injected.js
Well, this is where I encountered my second dead-end. I may have overlooked some things, but I searched in every object inside the page, I found yt
, ytplayer
, player
, and others. But none of them seem to have proper functions to trigger changes on the player such as play/pause/next, etc.
I then downloaded the html5player.js
from YouTube (available here) and beautified it to take a peek at what was under the hood. I found some interesting function names such as playVideoAt
, playVideo
, pauseVideo
around the lines 20235-20315 (once beautified).
That would be exactly the functions I would want to call/invoke, but I don't know where they are, and how to call them.
I also know that YouTube has a JavaScript API to control the player, but it's only for embedded players (iframes), so it's not useful in my case.