Once upon a time, Adobe Flash was dominated for web video playing, and myself used to be a fan of the Flash family, having fun with actionscript for a while. But now it has to worry about its future since more and more complains against its being closed, proprietary, power-consumed and not touch friendly.
Flash was created during the PC era – for PCs and mice… New open standards created in the mobile era, such as HTML5, will win on mobile devices (and PCs too).
– Steve Jobs
For now Apple seems to have won this battle and the thoughts on flash letter appeared to be the death sentence in advance. But the emergence of HTML5 might be the fuse of Flash’s fall down.
HTML5 Video Element
Most modern browsers support the HTML5 <video>
element/tag. The embedding is simple:
<video width="640" height="360" controls>
<source src="movie.mp4" type="video/mp4">
<source src="movie.ogg" type="video/ogg">
<source src="movie.webm" type="video/webm">
Your browser does not support the video tag.
</video>
(The video and related material are from the Paypal demo.)
The multiple sources/formats above are for different and if indeed different movies are provided, the first recognized one will be played. I will talk about video format later, let’s see what it really looks like first:
Not bad, huh. It has most of what you want from a web video player: the playback control and the volumn bar are all ready, and you can even make it full-screen. These actions can also be control using JavaScript, which can actually achieve far more customizations of the player’s behaviours. For example, you can control when it should play()/pause() by another button element. For more details, see the mozilla guide.
Video.js
I did not realize what is missing for the native player till I saw Video.js: it should at least shows something, say, a poster/preview picture, before the video being played; and it would be better if it can play subtitles. And that’s not the only things Video.js offers.
It is open-source and easy to use, with a well-decorated website and even an online designer to help you stylish your player. I did not stylish my own player yet because its default appearance looks satisfactory already:
Embedding this player just needs a couple lines of html and I won’t show it here since you will find out right on its website. What I show here is the shortcode I write to embed it in Hugo (the site generator I used for this blog) rendered Markdown:
<script src="//vjs.zencdn.net/4.11/video.js"></script>
<!-- The video -->
<video class="video-js vjs-default-skin" controls preload="auto"
width="640" height="360" {{ with .Get "poster" }} poster="{{ . }}" {{ end }} data-setup='{}'>
{{ with .Get "src" }}
<source src="{{ . }}.mp4" type="video/mp4" />
<source src="{{ . }}.webm" type="video/webm" />
{{ end}}
{{ with .Get "vtt" }}
<track kind="captions" label="English" src="{{ . }}" srclang="en" default />
{{ end }}
<p class="vjs-no-js">
Please enable JavaScript or consider upgrading to a modern browser.
</p>
</video>
And the “caller” in Markdown:
{{ % videojs src="url/to/file.no-extension" poster="url/to/an/image" vtt="the-subtitle.vtt" % }}
NOTE that there should be no space between {{
and %
, I separate them above to prevent Hugo manipulate it instead of showing it as codes. I miss that in the shortcodes docs and suffered from it for a while.
Alternatives
Another player I found was the Accessible HTML5 Video Player, aka px-video.js, which was actually the first customized HTML5 player occurred to me through its online demo. It’s also Github open-source, and provides similar functionalities.
After all, I decided to use Video.js for this site mainly for the sake of Hugo compatibility. The comparison between these two here is from the viewpoint of embedding it in Markdown (then static html) by Hugo shortcode. Both of them need to include a js script and a css stylesheet. However, Video.js only requires changing the class of the video tag while px-video.js requires additional initialization script, which make it more prone to unexpected errors during Hugo rendering. I indeed happened during my developing/blogging. (And the online designer and complete docs are extra bonuses for Video.js.)
TODOs
I had an impulse to implement my own customized player once. But then I thought why should I bother rebuilding the car from the wheels while I had one running. So I narrow down what should be done further, if necessary:
- The subtitle (.vtt format) now suffers the same origin policy problem, so I have to save it locally before going deep into CORS support.
- In the shortcodes, the height and width should also be able to specify.
- Try out the online designer to make the player matching the theme of this site.
Canvas
Another benefic of using HTML5 video is you can manipulate the video data in real time and incorporate any visual effect you want with the help of <canvas>
element.
You can accomplish that by 3 simple steps:
I. put a video element and a canvas element into the html, and get them in javascript;
<video id="vid" src="video.mp4"/>
<canvas id="cvs" width="320" height="240"/>
...
var vid = document.getElementById('vid');
var cvs = document.getElementById('cvs');
II. get a handle of the 2D context of the canvas and draw video content on it:
var ctx = cvs.getContext('2d');
// this can be triggered by a timer or a button click
ctx.drawImage(vid, 0, 0, width, height);
III. get the image data out of the context, do whatever:
var frame = ctx.getImageData(0, 0, w, h);
// access the RGBA element of pixel i
var r = frame[i * 4 + 0];
var g = frame[i * 4 + 1];
var b = frame[i * 4 + 2];
var a = frame[i * 4 + 3];
...
// put it back to another canvas context with changed frame
ctx2.putImageData(frame2, 0, 0);
Of course, a lot more can be done on the canvas, this tutorial a good starting point, or the screenshot demo. However, I plan to explore so much more that I think it should be in another post. So I will spare an example here and turn my focus back to videos.
HEVC
The emergence of HEVC (a.k.a H.265) is another excitement of the future of videos. It’s said to be half the size of the now dominating H.264 format while keeping the same visual quality. (If you only know the container, e.g., mkv or mp4, and never heard of real video format, you may skip this part.)
That’s really a savior for 4K and even 8K videos. However, it’s still too early for HEVC to take over H.264’s world since the encoding/decoding cost of HEVC are much higher (for encoding it’s time and computation resources consumed, and for decoding it’s the power and speed).
I would not dive into explaining the detailed pros/cons and the future of it (it will become dominating for a while and being taken over by another more advanced format, for sure). Rather, I’d like to show an example of how to play it on a not-yet-naively-supported browser.
The open-source project libde265 provides a javascript decoder for it. Below are just a copy of its original demo with video content substituted (I re-encoded the video clip to make the whole post concistent). The decoded frames also utilize the canvas element:
The blank space below are the canvas for the HEVC video.
Note that the original clip is a 02:29.14 long 720p (1280x720) H.264 video with file size as large as 28.8MB. I resized and encoded the HEVC clip to 01:00.00 long 360p (640x360), and the file is only 2.4MB. A H.264 video with the same duration and resolution will require up to 10MB. What a save! That’s why I can upload it to my site without any concern.
But the downside is obvious too: it is not well supported. The HTML5 player can not play it yet. The js decoder in the above example lacks further control (at least sync to play in normal speed) and can not play sound (both you might already notice). So there’s a long way to go.
Look Ahead
Anyway, the staffs I show above are the two most promising technology I recall when talking about videos. If you are not a developer nor in related industries, you may consider it a sip into some new juices. Hope you will think of these when you watch a 4K/8K movie through a browser in the future.