Demo of deep hyperlinking into HTML5 video

In an effort to give a demo of some of the W3C Media Fragment WG specification capabilities, I implemented a HTML5 page with a video element that reacts to fragment offset changes to the URL bar and the <video> element.

Demo Features

The demo can be found on the Annodex Web server. It has the following features:

If you simply load that Web page, you will see the video jump to an offset because it is referred to as “elephants_dream/elephant.ogv#t=20”.

If you change or add a temporal fragment in the URL bar, the video jumps to this time offset and overrules the video’s fragment addressing. (This only works in Firefox 3.6, see below – in older Firefoxes you actually have to reload the page for this to happen.) This functionality is similar to a time linking functionality that YouTube also provides.

When you hit the “play” button on the video and let it play a bit before hitting “pause” again – the second at which you hit “pause” is displayed in the page’s URL bar . In Firefox, this even leads to an addition to the browser’s history, so you can jump back to the previous pause position.

Three input boxes allow for experimentation with different functionality.

  • The first one contains a link to the current Web page with the media fragment for the current video playback position. This text is displayed for cut-and-paste purposes, e.g. to send it in an email to friends.
  • The second one is an entry box which accepts float values as time offsets. Once entered, the video will jump to the given time offset. The URL of the video and the page URL will be updated.
  • The third one is an entry box which accepts a video URL that replaces the <video> element’s @src attribute value. It is meant for experimentation with different temporal media fragment URLs as they get loaded into the <video> element.

Javascript Hacks

You can look at the source code of the page – all the javascript in use is actually at the bottom of the page. Here are some of the juicy bits of what I’ve done:

Since Web browsers do not support the parsing and reaction to media fragment URIs, I implemented this in javascript. Once the video is loaded, i.e. the “loadedmetadata” event is called on the video, I parse the video’s @currentSrc attribute and jump to a time offset if given. I use the @currentSrc, because it will be the URL that the video element is using after having parsed the @src attribute and all the containing <source> elements (if they exist). This function is also called when the video’s @src attribute is changed through javascript.

This is the only bit from the demo that the browsers should do natively. The remaining functionality hooks up the temporal addressing for the video with the browser’s URL bar.

To display a URL in the URL bar that people can cut and paste to send to their friends, I hooked up the video’s “pause” event with an update to the URL bar. If you are jumping around through javascript calls to video.currentTime, you will also have to make these changes to the URL bar.

Finally, I am capturing the window’s “hashchange” event, which is new in HTML5 and only implemented in Firefox 3.6. This means that if you change the temporal offset on the page’s URL, the browser will parse it and jump the video to the offset time.

Optimisation

Doing these kinds of jumps around on video can be very slow when the seeking is happening on the remote server. Firefox actually implements seeking over the network, which in the case of Ogg can require multiple jumps back and forth on the remote video file with byte range requests to locate the correct offset location.

To reduce as much as possible the effort that Firefox has to make with seeking, I referred to Mozilla’s very useful help page to speed up video. It is recommended to deliver the X-Content-Duration HTTP header from your Web server. For Ogg media, this can be provided through the oggz-chop CGI. Since I didn’t want to install it on my Apache server, I hard coded X-Content-Duration in a .htaccess file in the directory that serves the media file. The .htaccess file looks as follows:

<Files "elephant.ogv">
Header set X-Content-Duration "653.791"
</Files>

This should now help Firefox to avoid the extra seek necessary to determine the video’s duration and display the transport bar faster.

I also added the @autobuffer attribute to the <video> element, which should make the complete video file available to the browser and thus speed up seeking enormously since it will not need to do any network requests and can just do it on the local file.

ToDos

This is only a first and very simple demo of media fragments and video. I have not made an effort to capture any errors or to parse a URL that is more complicated than simply containing “#t=”. Feel free to report any bugs to me in the comments or send me patches.

Also, I have not made an effort to use time ranges, which is part of the W3C Media Fragment spec. This should be simple to add, since it just requires to stop the video playback at the given end time.

Also, I have only implemented parsing of the most simple default time spec in seconds and fragments. None of the more complicated npt, smpte, or clock specifications have been implemented yet.

The possibilities for deeper access to video and for improved video accessibility with these URLs are vast. Just imagine hooking up the caption elements of e.g. an srt file with temporal hyperlinks and you can provide deep interaction between the video content and the captions. You could even drive this to the extreme and jump between single words if you mark up each with its time relationship. Happy experimenting!

UPDATE: I forgot to mention that it is really annoying that the video has to be re-loaded when the @src attribute is changed, even if only the hash changes. As support for media fragments is implemented in <video> and <audio> elements, it would be advantageous if the “load()” function checked whether only the hash changed and does not re-load the full resource in these cases.

Thanks go to Chris Double and Chris Pearce from Mozilla for their feedback and suggestions for improvement on an early version of this.

13 thoughts on “Demo of deep hyperlinking into HTML5 video

  1. Good work Silvia! The resource reloading on load() seems odd if it’s still in cache. Will have to check if Opera has similar bugs… In any case, basic media fragments support seems pretty straightforward, I hope we will see native implementations (in Opera or elsewhere) soon enough.

  2. Very cool stuff. I tried loading a different .ogv file (with offset) and it worked like a charm. I’m excited to see how we might harness this in the future for purposes of inclusion and accessibility.

    Please make sure that unnecessary re-load has a bug filed 🙂

  3. Thanks for this post, it’s really exciting seeing all the pieces coming together around OGG / open source video!

    > For Ogg media, this can be provided through the oggz-chop CGI.

    According to this:
    https://bugs.launchpad.net/ubuntu/+source/liboggz/+bug/415947
    It’s maybe still just on the wishlist (unless I missed something?)

    In my testing setup on a local apache2 server (ubuntu) and using liboggz-0.9.9, when I enable oggz-chop (using the method provided by the included script), not only is there not x-content-duration, but all my ogv files lose even the Content-Length header and embedded videos appear with the scrubbar constantly all the way to the right (only as the video loads, the duration expands, and the “current position” thus stays always at max)… But it’s quite possible I have mis-configured something?

    I am considering writing a small CGI wrapper for oggz-chop to address the issue.

    1. Did you work with the latest checkout of oggz-chop? Some bugs have been fixed recently. Also: You should talk with Conrad Parker (kfish on irc) about patches for oggz-chop – I think he is about to put some major effort into extending it.

  4. I’m not sure the reloading on load() is a bug. I think it may be on purpose because it follows the algorithm specified within HTML5 accurately and there it states that the current resource is unloaded and the resource selection algo is fired on the “new” resource. I think this algorithm may need a comment for changes to the URL that only refer to the hash part of the video.

  5. This is a great move forward no more relying on 3rd party apps and extensions to play video or audio, i have been reading up on HTML 5 at the HTML 5 Tutorials website, i am now playing around with one of the free templates and was wondering how to embed audio, so thanks a lot, great information, lets hope more people lean towards HTML 5 and SOON!!!

  6. Great demonstration, but I’m confused as to the meaning of the URL ending
    mediafrag.html#t=15 vs the URL ending elephant.ogv#t=15.

    In the second instance, which seems to conform to the Media Fragment Working Group proposal, I can understand the the offset t=15 applies to the video which is the resource elephant.ogv. But in the first case, the resource is a html file. There is nothing in the #t=15 fragment that ties it to the video. The html file could conceivably contain multiple video tags and then what does the fragment refer to?

    Should the proposal describe additional name, value pairs such as tag=tagname, class=classname, id=idname so that the target(s) of the fragment can be located within the page?

    1. @John.Zornig The Media Fragment Working Group is only specifying URI query and fragment formats for media resources, such as elephant.ogv. The introduction of a fragment on the URI of the html page is a freedom that I took in my demo to show that a connection can be introduced between the URI of the page and of the media resource – always assuming that there is a single media resource on the page. This is akin to what YouTube do, e.g. http://blogoscoped.com/archive/2008-10-26-n19.html . They also hand the time offset through to the only video on the watch page.

      However, you are indeed right that a Web page author has the opportunity to define even more name-value pairs on pages to better specify the target element of the fragment. This can be done easily by the web page author and parsed using JavaScript on the page. However, it’s not part of the standardisation effort, so I wasn’t particularly keen to explore this further.

  7. Does anyone know how to configure IIS to deliver the X-Content-Duration HTTP header? I’m working on a SharePoint site and using custom HTML5 video players. In FF 3.6, which apparently uses the OGG versions of the videos, the duration property comes back as ‘NaN’, so my video progress bar doesn’t update. I have at least one IIS server that doesn’t have this problem, so I know it can be done on IIS, I just don’t know where/how.

Comments are closed.