Thursday, 15 November 2012

15 HTML5 video player - sync a second audio track

This week I am thinking about a second audio track for my video that provides audio descriptions for people with visual impairment.

To describe the problem that a second track would solve let's think about an actual classroom setting with a teacher demonstrating a task to a number of students. The teacher might say something like "Ok it is very important that you take this here and wrap it 5 times around this coil - but not the other coil. Before you turn it on make sure you press this button over here before flicking the power switch." Obviously the student can hear the teacher but might be stuck in the back of the classroom behind taller students and miss the visual information. If that is the case it is completely unclear what the teacher is talking about.

Many videos available online are excellent but every now and then slip into using non-descriptive words like 'this' and 'that'. If the user can't see what 'this' and 'that' are an otherwise excellent video can be rendered useless to them.

Early in 2011 Sylvia Pfeiffer at WHATWG and W3C were working on "... new HTML markup and a JavaScript interface for dealing with audio or video content that has more than just one audio and video track." Read the whole article: HTML5 multi-track audio or video.

This HTML markup should solve the problem of video with alternate tracks though it's not yet supported in current browsers. So what about now?

It turns out it isn't that hard to have a second audio track and to keep it relatively in sync with the video that is playing.

I have done it this way (basically):

  1. Place some video on a HTML5 web page (using the video tag of course... not flash :-) )
  2. Give the video tag an ID of videoTrack
  3. Now add the audio track to the web page also (for my test I stripped the audio from the video so I could confirm if the audio was in fact in sync with the video)
  4. Give the audio tag an ID of audioTrack
  5. Create a function in JavaScript that looks like the one below:
function syncTracks(){
   var audio = document.getElementById("audioTrack"); 
   var video = document.getElementById("videoTrack");
   audio.currentTime = video.currentTime
}

Pretty much as easy as that, set the current time of the audio track to the current time of the video.  Essentially all that needs to happen now is to call the syncTracks() function whenever the video is played, paused or stopped.

NOTE: The video controls should also control the audio playback.

There is a big BUT!

The currentTime property of the video only seems to start updating when the video is running for a short time. I found that the audio track and the video gets out of sync by about a second or so depending on how the user interacts with play and pause buttons.

To circumvent this I created a timer which is called when play is pressed. It waits for about a tenth of a second and THEN calls the syncTracks() function. This works much better. The sound is only ever a small fraction of a second out using this method.

Here is the timer I used:

setTimeout(function(){syncTracks()},100)

While this is not perfect it is better than the alternative of waiting for browser support for multiple tracks.






3 comments:

  1. I also hit a bit of a dead end with the Sylvia Pfeiffer article (although it was a great article). Great work around you have, simple and effective. Fair play!

    ReplyDelete
  2. Hey is there an example of what you just described up there anywhere on the web? I'd just love to have a look at it and see how it works.
    Thanks so much
    Markus

    ReplyDelete
  3. Thanks for sharing of informations about 15 Html5 video player- sync a second audio track...

    ReplyDelete