- Media Chrome is a suite of web components for building media player UIs. The HTML looks like this (no JS required):
- Media Chrome is now 1.0 and we're excited to officially dub it production ready. We were using it in production before and other people were too, but now we'll feel more guilty if we break you.
Congrats to all the contributors on this huge milestone!
It's typical to say "it's been a long road", but it feels more accurate to say it's been a fun road, pushing the edges of browser APIs and working with an incredible team who's as geeky about video player tech as I am.
I pushed the first commit on September 13, 2019 at the end of a pre-kids summer staying up late prototyping the idea. I'd finally got off of my butt and built what I'd been speaking about for half a decade—at the SF Video Tech meetup and Demuxed—which are the benefits of Web Components in building video players.
While the architecture has changed in some ways, the underlying philosophies of the project are the same as on day one.
- Despite some issues, Web Components are the future of the web, and this is already true for widgets (like a video player) that benefit from being cross-framework compatible
- Video and audio are fundamental to the web and there should be a set of idiomatic HTML elements for building media experiences
- A video player UI should not be tightly coupled to the playback engine/tech
Now after another almost half decade, Media Chrome is officially ready for prime time.
I built the first version of Video.js in 2010 with a similar goal of solving video UIs in an HTML-first way, in a world where HTML <video> was barely supported yet and Flash was dominant. Video.js control components attempted to mimic HTML where they could and the player API matches the video element API as best as 2010 JS would allow. But ES6 and Web Components have unlocked our ability to build actual HTML elements, and made it possible to build player components that better achieve the original HTML-first design goal of Video.js.
That said, Video.js, through the help of hundreds of contributors, has evolved well beyond the original goals into a mature (version 8), battle-hardened video player with an extensive ecosystem, and is still the right choice for many use cases. Long term, Media Chrome and Video.js aren't mutually exclusive projects. Media Chrome started as an experimental new approach to video player architecture, and we may choose to build later versions of Video.js using the Media Chrome components under the hood. Afterall, Media Chrome is not a player in itself, it's components for building media player UIs.
The main focus for the 1.0 release has been production-readiness. We've talked to a number of developers at larger companies looking to use Media Chrome who have been concerned about the zero-dot versioning, and while we were already confident in the stability of the project, we used this milestone to cross some Is and dot some Ts [sic].
Before our AI overlords take over it's our primary goal to keep Media Chrome stable and free of bugs in our limited human fashion. That means adding tests, and lots of 'em.
Media Chrome already had some unit tests but we really bulked up tests around the Media Controller API's and the themes API to easily catch any regressions in those more knotty areas.
We'll be adding more tests throughout development but for now we're pretty pleased having added a test coverage percentage nearing 80% and implemented the tooling to keep track of Media Chrome's code health.
Check em out! The team put a ton of work into improving the guides and the general aesthetics, including a fancy new logo that the Mux brand team threw together for us.
We also pulled the media elements themselves into the spotlight. While Media Chrome is just the UI layer, there's a lot of video and audio players that expose the <video> API to support the Media Chrome model, and we wanted to make those more discoverable. We've also defined the bare minimum API that a media element should support for Media Chrome to be compatible, which we hope makes it possible to build more media experiences that aren't exactly video players. If you're looking to build your own media element, check out custom-media-element.
If you're using any of the versions from the last year, there aren't any major workflow or structural changes to the API. What we have changed has been for the sake of consistency, with an eye towards a future larger ecosystem of components.
The design details you find yourself spending hours debating can be surprising, amirite? That was the case for element attribute names, which are allowed to contain dashes for better readability (<my-button media-airplay-unavailable>) but usually don't (<my-button mediaairplayunavailable>), with some added complexity of what React's web component support will be friendly to. Ultimately we fell back to the web platform design principles and removed the dashes from our attribute names. It's not everyone's favorite decision and some of the attributes get pretty fugly, but it's the most right call we could make based on the principles of the project itself.
We've used CSS vars throughout the project for a couple of reasons. The first is to allow developers to more easily style different components consistently. The second is to make it easier to style elements deep in shadow doms, which is blocked otherwise because of the nature of shadow doms. The problem was, we just hadn't always named vars consistently, or made sure the same variables exist everywhere you'd expect them too. For 1.0 we did a pass on cleaning up this landscape. If you were using CSS vars before 1.0 you may need to tweak a var name somewhere.
A debate that predates Media Chrome is whether or not Captions and Subtitles should be combined in the same list. I'm not gonna teach you the difference here, but just know that the <video> tag treats them as separate lists while every modern video player combines them in one menu for viewers. In 1.0 we've combined them into one list to make the common UI treatment easier to achieve. Special thanks to Gary Katsevman (@gkatsev) for pushing that one through in time.
While the Media Chrome API is only loosely tied to the media theme element, we wanted the Themes API to also be in a relatively stable place for this 1.0 release, so that as people build themes they don't have to worry that the theming ecosystem will change underneath them. With the 1.0 release we're excited to charge forward building many new themes and showing off how creative you can be with media player UIs using just HTML.
Yes, yes we are. We've heard the feedback that the name can be confused with Chrome Media, and people don't immediately get that chrome is a term for the UI, not Google's web browser specifically (which is using the term chrome in the same way, and no this didn’t make us feel old why do you ask?). With the size of change it would require, and no definitively better options on the table, we're moving forward as is! If you hate that, post about it somewhere, and be sure to link the words "media chrome" back to the project. 😉
As mentioned previously, we're excited to build more. If you know HTML and CSS, you can easily build a Media Chrome theme. We'd love for you to try and share what you create.
Media Chrome is just the UI layer of a video player and relies on media elements/players exposing the same API as the <video> tag. But the <video> tag API doesn't have everything we need to build modern player interfaces, including things like a video quality menu and ads. For this reason there's a separate community-driven project called media-ui-extensions, that is standardizing extensions to the <video> API to support these other UI features. We're working through a few of these now which will then unlock more features in Media Chrome.
We're in the process of some internal re-architecture of the media-controller that will allow for more natural workflows in React-based development. Compared to some other frameworks React has been slower than I had hoped in supporting Web Components seamlessly, and even in the latest version there are some gotchas to work around. So while we can still benefit from the portability of web components, it's clear that some React-specific components will take the edge off when using Media Chrome in React.