Middleware is one of the cool new features that is coming to Video.js in version 6.0
With middleware, you are now able to interact with and change how the player and the tech talk to each other. The tech is Video.js’s abstraction from the player, separating the player API from the playback technology. With techs, we can plug things like a Flash fallback or a Youtube embed into Video.js without changing the external API or the look-and-feel of the player.
Video.js middleware are like Express middleware but routes are based on video MIME types.
A lot of Video.js users may be familiar with middleware from projects like Express. Video.js middleware isn’t that different from those. In both cases you register your middleware against a particular route to call down the chain when the route is triggered. In Express, routes are based on the url paths. In Video.js, these routes are based on the video MIME type. And, like Express, there are “star” (
*) middleware that match all routes.
There are two important pieces to be aware of with middleware:
- dynamic source handling
- intercepting the player and tech interactions.
With the dynamic source handling, you could load video with a custom type and source and resolve it asynchronously. A good example for this is a video catalog system. The page can be rendered with a specific catalog ID and a special MIME type, like so:
Then, you could register a middleware for that route – the type
Then, when Video.js initializes, it’ll go through and call the middleware that are set for
Server Side Ad Insertion (SSAI) is a great fit for middleware. It showcases the ability to intercept the play and tech interactions. For example, you have a 30 seconds ad followed by a five minute video in your HLS manifest. You want the timeline to display the ad time and the content time appropriate when each is playing. Right now, the duration displayed will be the combined duration of five minutes and 30 seconds (
5:30). The solution is to add a middleware that knows when the ad is being played and tells the player that the duration is 30 seconds and when the content is playing that the duration is five minutes.
A simple but interesting middleware to look at is the playbackrate-adjuster. This middleware will change the times of the controls depending on the current rate. For example, if you’re playing back a 20 minute video and change the rate to 2x, the controls will adjust to display 10 minutes. Let’s take a look at the code.
So, here, we attach a star-middleware because we want to have it applied to any video, regardless of the MIME type. In
setSource, we also call
next directly with
null and the
srcObj because we want to use this middleware with any and all sources. We also set up our
duration method to take in the duration from the previous middleware and divide it by the playback rate we get from the player.
If you look at the code you can see some other methods next to duration. They’re there to make sure other methods that rely on timing get updated. The two methods to notice are
currentTime gets called when we want to know what the current time is.
setCurrentTime is called when we’re seeking. Because the user is seeking in the shifted time, we want to apply our change operation in reverse. Instead of dividing it, we want to multiply it.
If you were to apply what we’ve done so far, you’ll notice that the nothing changes, the control bar is still showing a duration of 20 minutes. This is because as far as Video.js knows, nothing has changed. So, we need to tell Video.js that the duration has changed. We can do that by storing the tech that Video.js gives us after source selection is complete.
And then, when the
ratechange event triggers, we tell Video.js that the duration has changed and Video.js will update the controls accordingly: