Evangelism/Firefox3.5/35Days/Articles/VideoPaul

From MozillaWiki
Jump to: navigation, search

Title: The video tag, more than just a new tag

Starting with Firefox 3.5, you can embed a video in a web page like an image. It means video is now a part of the document. And like all other elements, you can use it with CSS and Javascript. Let's see what it means.

A quick overview about how use the video tag

the basis

First, you need a video to play. Firefox supports the OGG/Theora codec (see here to know all media formats supported by the audio and video elements).

Add the video to your document:

<video id="myVideo" src="myFile.ogv"/>

You might need to add some "fallback" code (if the browser doesn't support the video tag). Just include some HTML (a warning, or some Flash) inside the video tag.

 <video id="myVideo" src="myFile.ogv"><strong>Your browser is not awesome enough</strong></video>

see here for more information about the fallback mechanism.

HTML attributes

You can find all the available attributes here: https://developer.mozilla.org/En/HTML/Element/Video

Some important attributes:

  • autoplay: The video will be played just after the page loads.
  • autobuffer: By default (without this attribute), the video file is not downloaded unless you click on the play button. Adding this attribute starts downloading the video just after the page loads.
  • controls: by default (without this attribute), the video doesn't include any controls (play/pause button, volume, etc.). Use this attribute if you want the default controls.
  • height/width: The size of the video

Example:

 <video id="myVideo" src="myFile.ogv" autobuffer="true" controls="true"/>

You don't have to add the "true" value (autobuffer=""), but it looks better. If you're not in a XML document, you can write:

 <video id="myVideo" src="myFile.ogv" autobuffer controls/>


JavaScript API

Like any other HTML element, you have access to a JavaScript API:

 var myVideo = document.getElementById("myVideo");

Here is a short list of some useful methods and properties: (For the complete DOM API, see this document.)

  • play() / pause(): Play and pause your video.
  • currentTime: The current playback time, in seconds. You can change this to seek.
  • duration: The duration of the video
  • muted: Is the sound muted?
  • ended: Is the video ended?
  • paused: Is the video paused?
  • volume: To know and to change the volume

Example:

 <button onclick="myVideo.play()">Play</button>
 <button onclick="myVideo.volume = 0.5">set the current volume</button>
 <button onclick="alert(myVideo.volume)">show me the current volume</button>

Events

You know how to control a video (play/pause, seek, change the volume, etc.). You have almost everything you need to create your own controls. But you need some feedback from the video, and for that, let's see the different events you can listen to:

  • canplay: The video is ready to play
  • canplaythrough: The video is ready to play without interruption (if the download rate doesn't change)
  • load: The video is ready to play without interruption (the video has been downloaded entirely)
  • ended: The video just ended
  • play: The video just started playing
  • pause: The video has been paused
  • seeking: The video is seeking (it can take some seconds)
  • seeked: The seeking process just finished
  • timeupdate: While the video is playing, the currentTime is updated. Every time the currentTime is updated, timeupdate is fired.

The full list of the event.

For example, you can follow the percentage of the video played:

 <script type="text/javascript">
   function init() {
       var video = document.getElementById("myVideo");
       var textbox = document.getElementById("sometext");
       video.addEventListener("timeupdate", function() {
           textbox.value = Math.round(100 * (video.currentTime / video.duration)) + "%";
       }
   }
 </script>
 <video id="myVideo" src="myFile.ogv" autoplay="true" onplay="init()"/>
 <input id="sometext"/>

For example, here you can see a nice player: http://www.tapper-ware.net/devel/js/JS.TinyVidPlayer/index.xhtml

going beyond with the new openweb standards and the video tag

CSS & SVG

A video element is an HTML element. That means you can use CSS to style it.

A simple example: using the CSS Image Border rule (a new CSS 3 feature in Firefox). You can view how it works in MDC: [1].

And obviously, you can use it with the video tag:

 <video id="myVideo" src="myFile.ogv" style="-moz-border-image: url(tv-border.jpg) 25 31 37 31 stretch stretch; border-width: 20px;"/>

One of my demos uses this trick: [2].

Since Firefox 3.5 provides some new sexy CSS features, you can do some really fantastic things. Take a look at this demo: http://hacks.mozilla.org/2009/06/tristan-washing-machine/ It uses several CSS rules:

  • filter, clip-path: [3].
  • SVG & foreignobject: [4].
  • css transform: [5].

Because the video element is like any other HTML element, you can add some HTML content over the video itself, like I do in this demo: [6]. As you can see, there is a <div> element on the top of the video (position: absolute;).


Time for a break

Well, we've just seen how far we can go with the video element, both how to control it and how to style it. That's great, and it's powerful. I strongly encourage you to read about the new web features available in Firefox 3.5: [7], and to think about what you can do with such features and the video element.

But you can do more. You can compute the pixels of the video. You can, for example, try to find some shapes in the video, follow the shapes, and draw something hung to these shapes. It's what I do here: [8]. Let's see how it actually works.

Canvas & Video

Another HTML 5 element is the canvas tag. With this element, you can draw bitmap data (see the reference, and I strongly suggest this canvas overview). But something you might not know is that you can copy the content of an <img/> element, a <canvas/> element and a <video/> element.

That's a really important point for the video element. It gives you a way to play with the values of the pixels of the video frames.

You can do a "screenshot" of the current frame of the video in a canvas.

 <script type="text/javascript">
   function screenshot() {
       var video = document.getElementById("myVideo");
       var canvas = document.getElementById("myCanvas");
       var ctx = canvas.getContext("2d");
 
       ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
   }
 </script>
 
 <video id="myVideo" src="myFile.ogv" autoplay="true" with="600" height="400"/>
 <canvas id="myCanvas" with="600" height="400"/>
 <button onclick="screenshot()">Copy current video frame to canvas</button>

You can first apply a transformation to your canvas (see the documentation), then the drawImage will be affected. You can also copy a thumbnail of the video (see [9]).

If you draw every frame in a canvas, your canvas will look like a video element. And you can draw what you want in this canvas, after drawing the frame. It's what I do in this demo.

Once you have a video frame in your canvas, you can compute the values of the pixels, see: [10].

Some things you should know if you want to compute the pixels values of a frame:

  • you can't use this mechanism with a video from another domain.
  • you can't use this mechanism with a video from a file:/// uri (which would be useful during the development of your web application). But you can change this behavior for testing: In about:config, change the value of "security.fileuri.strict_origin_policy" to "false".
  • There are two ways to display the result of your application on the top of the video:
    • use your canvas as a video (if you draw the frame every time), and then draw directly into the canvas
    • use a transparent canvas on the top of the video
  • the canvas element can be "display: none"
  • the video element can be "display: none"

About JavaScript:

For the image processing, you will need to do a lot of computation; here are some tricks:

  • copy your frame in a small canvas. If the canvas is three times smaller than the video, it means nine times fewer pixels to compute
  • avoid recursion. In a recursion, the script engine doesn't use the JIT optimization (https://wiki.mozilla.org/JavaScript:TraceMonkey)
  • if you want to do a distance between colors, use the L.A.B colorspace: [11]
  • if you want to find the center of an object, compute its centroid: [12]. See the "computeFrame" function [view-source:http://people.mozilla.com/~prouget/demos/DynamicContentInjection/main.js here].
  • if the algorithm is really heavy, you can use a Worker thread, but take into account that you will need to send the content of the canvas to the thread. It's a big array, and objects are automatically JSONified before being sent. It can take a while.

Conclusion

As you can see, you can do powerful things with the video element, the canvas element, CSS3, SVG and the new JavaScript engine. You have everything in your hands to create a completely new way to use the Video on the web.

It's up to you now; upgrade the web ;)