Evening Hack: Adding Playback Controls to F1 TV

July 3rd, 20202 min read

One of the things YouTube has done well has made certain shortcuts for videos ubiquitous. The flipside is that when an HTML5 video doesn't have those shortcuts, it's annoying.

That's the case with F1 TV. So, with my new found browser extension building skills, I decided to tackle that one issue (of the very many) that plague the F1 TV website.

There really isn't much to blog about in this one, but here's some things that were interesting to learn on my browser extension journey.

Before going any further, you can pick up the code for my extension on GitHub.

Learning About Extensions

You can run several types of scripts ranging from popups in the toolbar, background scripts, content scripts, and developer tools scripts. Each one of these has its own unique restrictions and ways to interact with the website. I'm not going to go into each in detail here, but it was interesting to learn about.

Javascript Isolates

In my case, I used a content script to inject code into the website. However, this code runs in its own isolated Javascript sandbox.

If you're waiting for interactions to happen in the client Javascript, you'll be waiting forever. One of these examples is that I tried injecting, loading and waiting for the Google Cast API to initialize.

To get around this, you can inject Javascript (or CSS) elements directly into the DOM. If you're providing an external file like I did, you have to declare this in your extension's manifest.json ahead of time and specify which browser addresses on which to perform the injection.

YouTube Controls

Though I had pretty simple needs for playback, pause / play and minimal seeking, it turned out that YouTube power users have enjoyed a number of playback controls that I had no idea existed. Here's what they look like:

  • [space]: pause / play the video
  • m: mute / unmute the video
  • + / -: increment / decrement the volume by 5%
  • [left arrow] / [right arrow]: backward / forward by 5 seconds
  • j / l: backward / forward by 10 seconds
  • f: fullscreen
  • [1]...[9]: skip to 10%...90% of the video
  • [home]: seek to the start of video
  • [end]: seek to the end of the video

Implementation

The code is thankfully simple enough:

  1. On F1 TV urls, it injects the script into the page.
  2. A MutationObserver is used to wait for the HTML5 <video> tag to be added to the page by embedplayer.js
  3. It adds a keyboard listener to the browser window for the controls listed above and manipulates the video container.
  4. That's it!

Google Cast

I am trying to add Google Cast abilities to it too. This seems like a bit of a harder challenge since the HLS (HTTP Live Streaming) stream needs to be authenticated.

It turns out you have to build a Cast Receiver and Cast Sender for Google's Cast API...which is a bit more trouble than I originally anticipated.

Sounds like a good idea for a future hack!