Clément Hallet's blog

Some times ago, I was trying to re-synchronize subtitles and video whithin VLC player, the typical : "150 ms after ... erf, 50 ms before, that's it ! no ... it's still desynchronized ...".

After giving up, and by curiosity, I opened the file, and found that the SubRip format is, in fact, quite simple. Just for trying, I read and displayed them in a browser. This is the way SubRipReader was born, using Mootools 1.2.

Edit : SubRipReader has been deleted since then, its functionnalities are now integrated into the Mooplay project. More to come about it.

Unfortunately, it won't resolve my initial problem. But it's still able to load the subtitles through an Ajax request, to parse them, and to display them step by step, into a DOM element.

It supports :

  • play / pause states
  • overlapping subtitle levels : when several lines of texts should be displayed at the same time, each one took a different css class :
    1. 2
    2. 00:00:15,000 --> 00:00:25,000
    3. A text
    4.  
    5. 3
    6. 00:00:20,850 --> 00:00:30,000
    7. An other text

    For instance, the previous subtitles lines will be injected in DOM and could be displayed like that, depending of your custom styles :

    1. <div class="overlapping0"><p>A text</p></div>
    2. <div class="overlapping1"><p>An other text</p></div>

    subtitles screenshot

For playing subtitles, use Srt.Parser and Srt.Reader :

  1. var myReader = null;
  2.  
  3. var myParser = new Srt.Parser({
  4.     url: 'test.srt', // the subtitle file url
  5.     onComplete: function(data) {
  6.         myReader = new Srt.Reader(data, {
  7.             container: 'mysubtitlecontainer', // where to display subtitles
  8.             time_container: 'mytimecontainer' // where to optionnaly display the internal timer state
  9.         });
  10.     }
  11. });

Then, you should be able to call the start and pause actions :

  1. myReader.start();
  2. myReader.pause();

I've just seen about the Universal Subtitle Format, it's going to be the time to implement its own parser !

Pour cette nouvelle session d'atelier, le thème était l'organisation technique des projets.
Parmi les thèmes abordés : le versionnage des sources avec Git, la numérotation des versions d'une application, les jalons correspondant dans Trac, les branches à utiliser, les environnements déployés et leur utilité.

Deux présentations ont donc été faites :

Prochaine étape : migrer l'ensemble de nos projets sous Git ;)

According to the Microsoft documentation, there are two dirty ways to catch such objects DOM events :

Here are two exemples using the "PlayStateChange" event :

  1. <!-- integrate the WMP object -->
  2. <object id="Player" type="application/x-ms-wmp" width="300" height="200">
  3.     <param name="URL" value="c:\MediaFiles\Seattle.wmv"/>
  4. </object>
  5.  
  6. <!-- the first one -->
  7. <script for="Player" event="PlayStateChange(newState)">
  8.     console.log("newState: " + newState);
  9. </script>
  10.  
  11. <!-- the second one -->
  12. <script>
  13. function OnDSPlayStateChangeEvt(newState) {
  14.     console.log("newState: " + newState);
  15. }
  16. </script>

The two script tag properties "for" and "event" don't appear in the HTML standards, nevertheless that way works fine with Internet Explorer 6, 7 and Firefox 2, but doesn't with Firefox 3 .
The second one works on all those browsers, but a problem appears when several player instances are running. How to know which one has fired the event ?

An alternate way is using DOM level 2 events. However, the WMP plugin for Firefox doesn't fire its events in the DOM. Instead of it, the plugin probably look for matching script tags and eval the content it found.

Then, on Internet Explorer, and contrary to all other events in this browser, the ones from WMP objects are not prefixed by "on" (like "onMouseOut", "onClick" ...).
Since the javascript libraries like mootools or prototype follow that Microsoft "standard", their event listeners on DOM elements are useless.

So, the good syntax to make it work with IE is :

  1. document.getElementById('Player').attachEvent("PlayStateChange",function(newState) {
  2.     console.log("newState: " + newState);
  3. }