Viki HTML5 Player — UI
When started this project. The goal what was adding ads to the player, so in first few months it’s using default video.js UI. Only few icons has been changed and adding ads cue and square button for “cinema mode” that expands player to make it bigger in page.
It never look like player for viki.com website and designer already have an idea for the new UI that match to new viki.com website. Problem is, I cannot reuse current control and replace the icons and have to build my own control bar.
Same controls, different icons and position
First thing that different is number of controls, instead of one line, now I have progress bar on top and three groups of controls in the bottom instead of just two groups. I also have “Ads” toggle button and subtitle information and setting that’s look very different with sub-menu.
All icons are also different, instead of boxes, now it has arrow to tell the behaviour of player when click on it.
I started with icons first. video.js is using font icon, so I just follow them and this probably not that hard, and asking designer to give me font with all icons that need for the player. Problem is, to generate fonts, only shape is not enough and all fonts become unusable. I still think it’s ok to use font by finding the way to make all shapes size the same and look into how video.js generate all those icons and end up with this script.
Two properties that I need are “fontHeight” and “normalize”, in case for “normalize” I end up resize all icons manually instead of using webfont-generator to make the height equals because some icons will become bigger especially the arrow that’s normally need to add some space to make it smaller.
So, the icons size problem solve and what designer need to do after this is just send me SVG image which’s defined an icon shape and run this script to generate font files.
However, the second problem come in sometime later (It actually after I finished other feature which was like 3 months after shipping the UI to production), all icons are showing different in different browsers! After tried figure out with css and font script again for a while, this problem seems took too long to solve. So, in the end, I fade out this script and fonts and converts all player controls to images and use SVG image designer send to me directly. It’s actually make it easier to use too because for image, I have more control on height and width, make it exactly what designer want.
After icons are solved, I started looking to position components. In video.js, most player controls (except “big-play-button” which is defined in player but this one can use css to replace look and feel) are defined in control-bar.js and it’s flat children, all controls are in same line. To make it group and separate, I need to create component split all these controls to be child of those new component.
All components in video.js are inherit from “Component” class and all children that pass to options are registered to Component. Most simple component is looked like this.
It’s very simple class that wrap around DOM element to make DOM manipulation and event handler easy. It’s very similar to react but Component doesn’t re-render element when state change, all those thing have to handle manually.
When component get create, it starts by calling “createEl”. This method is return the component DOM that showing on the player. After that, it will look through children in options and create all elements that’s defined in this list.
From control-bar.js, by overriding children options make it looks like this.
make the control separate into two lines. “playerControls” is custom component which is similar to ControlBar but has three separate boxes inside split into left, middle and right and have children accordingly to design make the control bar looks like now.
This is the most simple steps in making html5 player so far, the next part that’s a bit harder is “Ads UI” which’s currently base on videojs-ima. The library is maintaining by Google and very active but if ads UI is needs to modify too, build it by yourself with ima3.js from google might be a lot simpler. Will continue this part in next post.