 So, I've been doing a lot of what I like to think of as boilerplate code because I've been working on the site and I've been building custom controls for the video player. And so firstly, it's awesome that you can totally get, like, there's loads of events that fire off a media element, whether it's Seeking, it's Seeked, whether it's Ended, whether it's Playing and all these things are really, really handy when you're making custom controls because you want to kind of handle that. I just wanted to, because I've spent some time doing it, I just wanted to kind of show you very briefly around some of the code. I mean, you can find it all on GitHub. Just check the link in the description below if you want to actually, like, spend ages looking over the source code. But I will explain, broadly speaking, how I've decided to divide and conquer the code for this. Let's have a look at what's on my screen. So, the first thing to note is that there are two things. There's actually, there's two classes that are interesting. There we go. That's how I should say it. There's the video player and the video controls. The video player is what is going to decide whether the video is playing or whether it's actually pause. It actually controls the Shaka player and it controls the video element itself. That's the, it's kind of the wrapper around. Why is it a wrapper around a wrapper around a video? Because it's a wrapper around Shaka around a video. This feels like it's going to quickly descend into some kind of tongue twister. It's a wrapper around Shaka around video. Yes, I got it. Yes. Anyway, that's not what you came for. Let's talk about the code bits. So, in the constructor for one of these video players, you can see I pull a lot of stuff from the video element because I actually put a video element in the page using Dust.js template. So, I say, look, there's a video element. And I pop in, in the HTML, all the data that I think I'm going to need. And the reason I do that is because I think that server-side rendering makes a lot of sense here. Even though this is all JavaScript-based, I don't want to make a request off for the JSON and then bring it back in, but I can encode this all inside the DOM if I absolutely need to and it's working just fine. So, I pick up all the things that I need from the DOM, like the title of the video, the link to the manifest, as in, where do I get the manifest for this particular video, post frames, all that kind of stuff. And I keep a bunch of things around that I need to just, you know, for housekeeping. This, here, with all these binds, you'll recognize if you have watched a supercharged. I'll explain it now just very, very briefly. These things like on key down, on click, they are class methods, but that's sugar over a prototype method in ES5 terminology. And so, if I call, if I had an event listener that's like, there's like a click event handle, let's say, on a button, and I say this.onclick, by default, the onclick will be bound to the button, for example. So, if I say this.something or other, it will refer to the button. Typically, what I actually want it to refer to is my instance of my class. The other thing, the other reason I do it like this and take a copy of it off the prototype and onto the instance is just simply so that I can do add event listeners and remove event listeners and I can still refer to it by name. So, this.onclick always refers by name to the instance copy. So, I do it for two reasons. It looks slightly odd and it is slightly odd and it's just one of those things. I would like it if we had a different way to do this, but we don't at the moment. So, anyway, so I set them all up at the start. Okay, here's actually, yeah, the event listeners are things like key down, click play, pause, back for 30, forward 30. So, these are custom specific to my app. These aren't your standard issue events. These come from the video controls, so I'll have to show you that in a moment. But there are some specific ones that I do which go in the other direction. So, when we play, we pause, the video has ended or the duration changes, I actually notify the controls. So, there is some coupling going on here. I either call into the video controls and give the video controls a bit of updated state about the video so that controls can be updated and reflect what's going on and the video controls will dispatch events back out. So, the video player, the video controls are inside something, so I can basically do event handling and so I call in, but I do events out. I think actually when you do VDOM stuff, they often say that you want to do props down and events up and it's not a dissimilar thing here. I'm sort of calling in an events bubble back up and it seems to work just great. So, these are the custom events, essentially, that I get from the controls. Then there's a few bits and pieces about whether we've gone full screen. I was surprised to discover things like full screen still require webkit prefixing on the way through. Interesting. Thought most of the webkit stuff had disappeared. In fact, I thought all the vendor prefixed stuff had mostly disappeared, but there are a few that are hanging around. There are a couple of other bits and pieces like whether we support the newer orientation locks, which I have a quick test for, which is like if orientation in a string is in window.screen. These are convenience things here, whether we support these various things. I will show you the media session API at some other point, not in this one, because it's worth seeing all by itself. It's very exciting. So, we've got all this going on. As I say, most of this is boilerplate-like. For example, if you go on back 30, all we do is we grab the video and we just say current time, take off 30 seconds, and then update the video controls. So, as I say, loads of boilerplate. On the video controls side, however, it's, again, actually not dissimilar in terms of a lot of boilerplate about sort of click handlers and so on. In fact, there's actually one global click handler, which I, so I delegate control of the click handling out to the video controls. Let me show you that. Where's the on click when you need it? La, la, la. Come on, Paul. I look on the button itself. Oh, I look on whatever was actually clicked. And if it's got a type in its data set, so if it's got data-type as an attribute, I fire a custom event with that name, which is why in the video player, we get things like, la, la, la. We get, like, back 30 and forward 30, because if we were to look in the player, I hope you all sing when you're doing your look around your codes, because I definitely do. Makes me a joy to work alongside. Hmm, hmm, hmm, hmm. Anyway, that's not what you came here for. There we see, there we are. So, like, data type equals toggle volume or data type equals toggle Chromecast. I've yet to build that bit mostly. So that data type is what's used to, as the event name, we just fire that from the video controls, pick it up in the video player and then do the appropriate thing. Oh, hopefully it all makes sense. So there you go. That is a quick look around the video controls, the video player. That's kind of where I've been roughly spending nearly all of my time. I expected a lot of boilerplate. I got a lot of boilerplate, but on the upside, I mean, let me show you now. Let me show you what we've got. This is the video player as it is, and how would you look at that? It's me and Serma. And a few other people besides. We've got the pause, play controls. We can skip forward 30. There's the buffering. Go back 30 as well. We can also drag along like that, which will also work. There's Rob Dodson. Looking very Rob Dodson. Yeah. Full screen. We can go full screen. Boom. Look at that. That's great. So that all works. All these things you can do. And more besides, I've got some code that will switch on things like the Chromecast button if there's a Chromecast on the network, all that. You can find all that in the source code, and I will spend a bit more time talking about that kind of stuff in a future entry. But for now, I will wish you a very good day, and thank you very much for watching. Hey, folks, thanks for watching. Don't forget that there is more content that you can find kind of over here-ish. And if you want to subscribe, there's probably a button. Oh, maybe there. Maybe somewhere around there. Click that if you've not done that. Brilliant.