The blog post describes the problems I face when working with UI frameworks and Media elements in the web platform (specially video 🎥 and audio 🎵). I really am excited about this as it is the first solution that is totally owned by me without referring to any other sources of solution. I'm going to give a brief overview of problems I had at work and how I ended up create this solution. Thus, read on guys 📖
It's harder than you thought, easier than you think
First of all, let's define couple of terms before moving to the rest of the article:
As of writing, I was working at Axon enterprise. The big mission is "Write code, save life". Specifically, Axon provides solution to helps police officers make bullet obsolete which consists of hardware and software. Among Axon's software ecosystem, there is a very customized and sophisticated media player to help user working with media evidences in the web. By the time I wrote this post, I had approximately one year experience with it (as long as I had joined Axon). Our team was the owner of this package and I was the only engineer working on it as maintainer.
In short, our current media package was a tightly coupled binding between React, MSE and Media elements. Since none of us was super experienced working with these pieces of technology before. We made couple of critical mistakes:
We are done for the problems statement part. The media package has served our customer well to some extend. As the company scales up quickly, we definitely need a better solution to make sure developer experience and productivity work beautifully in harmony. That is why I decided to work on something completely new to solve my problem with this media package, make Axon's developers and customers happy (less cursing words come out of their mouths 🤪). I created the blueprint to make lives better.
The image attachment above can be broken down into "understandable" parts as followings:
With the architecture above, I was able to solve all problems I faced except one - IE11 loading issue. It will take years before IE11 goes completely vanished. Before that, we have to support it as much as we can. The problems with IE was that it's not responsive to certain events that are vital to indicate whether media elements has data to play or not (canplay, canplaythrough, waiting events are among them). Our previous engineers had to do a ton of workaround to mimic the behavior compared with other modern players. I spent couple of days trying to resolve this issue as clean as I could. I ended up first with the solution of detaching loading logic away from media elements and shift that to MSE instance. This works consistently but failed on normal media sources. Even though, we have not supported normal media sources yet but I wanted to "aim far". The optimal solution was to have the snippet below to check on any events that required loading logic (progress, waiting, seeking events)
It's very much readable, isn't it? 😁 Try it yourself on IE11 to see it works 😇
Error handling has always been something mistreated by most applications AFAIK. It's pretty tedious compared to fancy working features, but we need a way to let consuming code known what's going on internally and communicate effectively so that the UI can be updated as per demands. In the case of this media package, there are two big categories where error can fall into. They are network error and MSE error (due to internal error of relative MSE libraries). For the latter, we can't do anything more about it but to let client code know that some error came with MSE instance. With respect to network error, there are several scenarios thing such as unstable network, wifi change, network timeout, failed API call. Most of the time, these should be solved by retrying on the current loading segment until reaching thresholds (this should be configurable) 😎
Last but never be the lease is testability, how do we test any components that connected to our media store? This is pretty straightforward as all we need to do is render them all into the DOM, interact with it and assert that they works the way we expected. The simplest and meaning full test to make sure mute feature work should look like the attachment right below 👇. How hard can it be? 😃 (Since we are not able to load a video stream into our media player, that would require e2e test. That should not be a problem but involves a bit of setup. Since the media player and testing tools are sharing the same interface if they test via media tags or interact directly via media control components. It just works! 🤝)
I built a mini Youtube clone video application in Vue in less than a day. This exemplify the effectiveness of the architecture 🎉
To error is human, it's the fact - without trial and error we will never be able to progress in life. I was completely new to media in the web, never written any lines of code related to media service. I had done nothing more than using video and audio tags directly from the web. At Axon, I was really grateful that the problems I faced mostly not available in stackoverflow (I couldn't copy and paste like most developers in the world would do - no offense 😆). Trying to keep an open-minded, experiment and see things work under various scenarios did cost many weekends of mine 😬
To see the list of things that I have come up with without any helps from stackoverflow while being at Axon. Please visit this link for the full list in case you are curious 😊
At the moment of this writing, I was not at the position at Axon to make direction for the media package project to go anywhere. It totally came out of my frustration with the current media package, I wanted to make lives better (customers, friends and developers), build something that I would personally like and use for the rest of my-life (as long as I'm still coding 😄). Life is all about challenging and pushing ourselves 😎
❤️❤️❤️ Be well, Be happy ❤️❤️❤️