blog.humaneguitarist.org

discoveries in digital audio, music notation, and information encoding

jAUs: trying to add a startTime attribute to the audio tag

leave a comment

I work up this morning feeling unwell, but I still went in to work for a few minutes to enable Remote Desktop as it had stopped working (was a Windows Firewall thing) …

Anyway, on the walk back home I started thinking about something I've wanted to play with for a while.

And that's seeing what it would take to add support for a "startTime" attribute for the HTML5 <audio> tag using a browser's built-in player. I think it's a real oversight that there isn't native support for passing the start and stop times in the <audio> and <video> tags themselves. Um, there isn't right?

Adding support for a "stopTime" attribute would, I think, require more than I'm willing to think about right now (I should be napping) because obviously that entails checking the current time against the point at which one would want the media to stop.

But adding a simple (and, yes, non-standard) "startTime" attribute inside the <audio> tag seems pretty easy – if you aren't using IE. Ugh.

As you can see in the code below there's an alert() that returns a null, but without it IE (version 9) won't set the audio players to the values in the "startTime" attributes. The other "major" browsers do fine without it. And, really, it can't be there because it's annoying as hell.

But I think this still points to the problem of each browser having its own player. Take Safari for instance. It doesn't natively show the current or total time of the track. Chrome doesn't show the total time.

Still think Flash is a bad thing?

:P

<!DOCTYPE html>
<html>
  <head>
    <title>jAUs</title>
    <script type="text/javascript">
      function jAUs(){
        var audioTag = document.getElementsByClassName('jAUs');
        for (i=0;i<=audioTag.length;i++){
          var audioTag_startTime = audioTag[i].getAttribute('startTime');
          alert('');
          audioTag[i].currentTime = audioTag_startTime;
        }
      }
    </script>
  </head>
<body onload="jAUs()">

  <audio class="jAUs" controls startTime="10">
    <source src="sonnet130_shakespeare_njm.mp3" type="audio/mp3" />
    <source src="sonnet130_shakespeare_njm.ogg" type="audio/ogg" />
    Your browser does not support the audio element.
  </audio>

  <br />

  <audio class="jAUs" controls startTime="25">
    <source src="sonnet130_shakespeare_njm.mp3" type="audio/mp3" />
    <source src="sonnet130_shakespeare_njm.ogg" type="audio/ogg" />
    Your browser does not support the audio element.
  </audio>

</body>
</html>

ps: If this ever turns into a little project of mine, it needs a decently cool name to keep my interest. "JS" for JavaScript and "AU" for audio mashed up equals "jAUs". I hope that isn't already taken within the JavaScript/HTML5 domain.

Update, January 09, 2012: Now that an hour has past and I finished watching "Thor & Loki: Blood Brothers", I figured out how to elegantly do the "stopTime" thing – well, at least I think it's better than what I was thinking earlier today!

So unlike in the code above, the JavaScript below only hits on one <audio> element (the one with an "id" value of "jAUs") and not all the ones with a "class" value of "jAUs". But the point is that this new code adds the "ontimeupdate" attribute to the <audio> tag and makes it run a function called stopper() that will stop the audio once the current time is greater than the designated stopping time.

Now, there's still work to do. For example, the code should test for the existence of the "stopTime" attribute before forcing the stopper() function to run, but that's no big deal. I also need to test doing this as above – i.e. hitting all <audio> tags with a "class" value of "jAUs" – and see how that works. And there's that pesky IE thing, too.

Anyway, this is working in the other "major" browsers 'far as I can tell.

<!DOCTYPE html>
<html>
  <head>
    <title>jAUs</title>
    <script type="text/javascript">
      function jAUs(){
        var audioTag = document.getElementById('jAUs');
        var audioTag_startTime = audioTag.getAttribute('startTime'); //returns "10"
        //alert(''); //no IE love this time, sorry!
        audioTag.currentTime = audioTag_startTime;
        var audioTag_stopTime = audioTag.getAttribute('stopTime');  //returns "20"
        var stopThis = "stopper(this.currentTime," + audioTag_stopTime + ");"; //returns "stopper(this.currentTime,20);"
        audioTag.setAttribute('ontimeupdate',stopThis); //sends current time and stopTime value to stopper()
      }
      function stopper(currentTime, stopTime){
        var audioTag = document.getElementById('jAUs');
        if (currentTime > stopTime){
          audioTag.pause(); //stops playback if the current time is greater than the stopTime value
        }
      }
    </script>
  </head>
  <body onload="jAUs()">

  <audio id="jAUs" controls startTime="10" stopTime="20">
    <source src="sonnet130_shakespeare_njm.mp3" type="audio/mp3" />
    <source src="sonnet130_shakespeare_njm.ogg" type="audio/ogg" />
    Your browser does not support the audio element.
  </audio>

</body>
</html>

Update, January 09, 2012: I still don't like it, but it seems that the alert() line can go at the top of the jAUs() function and still allow all this to work on IE 9. At least that prevents an alert message for each <audio> tag within the page.

Update, January 10, 2012: Ah. Now, we might be getting somewhere. I don't know if it's just a band-aid fix, but if I add an "onloadeddata" bit for IE9 this actually seems to be working just fine. The problem was that IE didn't consider the <audio> element's properties to be accessible, thus giving me an "Invalid State Error" with a code number of 11 which is this, more or less: "An attempt was made to use an object that is not, or is no longer, usable." So, IE9 is taking a little longer than the other browsers in realizing what's what.

<!DOCTYPE html>
<html>
  <head>
    <title>jAUs</title>
    <script type="text/javascript">
      function jAUs(){
        audioTag = document.getElementById('jAUs'); //this is a global variable
        var audioTag_startTime = audioTag.getAttribute('startTime'); //returns "10"
        //alert(audioTag.readyState); //IE returns "0", other browsers "4"
        //alert(audioTag.readyState); //IE and others return "4"
   
        //needs to be for IE9 only ... I guess it waits until the audioTag is ready to go.
        if (navigator.appName == 'Microsoft Internet Explorer')
        {
          audioTag.onloadeddata = function() {
            audioTag.currentTime = audioTag_startTime;
          }
        }
        else {
          audioTag.currentTime = audioTag_startTime;
        }

        var audioTag_stopTime = audioTag.getAttribute('stopTime');  //returns "13"
        var stopThis = "stopper(this.currentTime," + audioTag_stopTime + ");"; 
        //returns "stopper(this.currentTime, 13);"

        audioTag.setAttribute('ontimeupdate',stopThis);
      }

      function stopper(currentTime, stopTime){
        if (currentTime > stopTime){
          audioTag.pause();
        }
      }
    </script>
  </head>
  <body onload="jAUs()">

  <audio id="jAUs" controls startTime="10" stopTime="13">
    <source src="sonnet130_shakespeare_njm.mp3" type="audio/mp3" />
    <source src="sonnet130_shakespeare_njm.ogg" type="audio/ogg" />
    Your browser does not support the audio element.
  </audio>

</body>
</html>

Update, January 10, 2012: Hopefully (for you and me) this is the last update for a while. Hey, I'm still sick, jerk!

Anyway, this is a test for hitting on all <audio> tags with a class value of "jAUs".

<!DOCTYPE html>
<html>
  <head>
    <title>jAUs</title>
    <script type="text/javascript">
      function jAUs(){
     
        audioTagArray = document.getElementsByClassName('jAUs');
       
        for (i=0;i<=audioTagArray.length-1;i++){
          var thisAudioTag = audioTagArray[i];
          jAUs_2(audioTagArray,thisAudioTag);
        }
      }
     
      function jAUs_2(audioTagArray,thisAudioTag){
      //if this is placed directly into jAUs() - i.e. not a separate function,
      //then this whole thing doesn't seem to work.
     
        if (navigator.appName == 'Microsoft Internet Explorer'){
          thisAudioTag.onloadeddata = function(){
            var thisAudioTag_startTime = thisAudioTag.getAttribute('startTime');
            thisAudioTag.currentTime = thisAudioTag_startTime;
          }
        }
       
        else {
          var thisAudioTag_startTime = thisAudioTag.getAttribute('startTime');
          thisAudioTag.currentTime = thisAudioTag_startTime;
        }
     
        var thisAudioTag_stopTime = thisAudioTag.getAttribute('stopTime');
        var stopString = "jAUs_3(this.currentTime," + thisAudioTag_stopTime + "," + i + ");"; 
        //returns "jAUs_3(this.currentTime, 13, i);" where "i" is an int.

        thisAudioTag.setAttribute('ontimeupdate',stopString);
      }

      function jAUs_3(this_currentTime,thisAudioTag_stopTime,i){
     
        if (this_currentTime > thisAudioTag_stopTime){
          audioTagArray[i].pause();
        }
      }
    </script>
  </head>
  <body onload="jAUs()">

  <audio class="jAUs" controls startTime="10" stopTime="13">
    <source src="sonnet130_shakespeare_njm.mp3" type="audio/mp3" />
    <source src="sonnet130_shakespeare_njm.ogg" type="audio/ogg" />
    Your browser does not support the audio element.
  </audio>

  <br />

  <audio class="jAUs" controls startTime="25" stopTime="26">
    <source src="sonnet130_shakespeare_njm.mp3" type="audio/mp3" />
    <source src="sonnet130_shakespeare_njm.ogg" type="audio/ogg" />
    Your browser does not support the audio element.
  </audio>

</body>
</html>

By the way, using the HTML5 "data-" prefix a la "data-startTime" would make the attribute(s) valid, though still not part of a standard per the <audio> tag specifically. But I guess the "data-" prefix is an acknowledgment of reality.

--------------

Related Content:

Written by nitin

January 9th, 2012 at 12:29 pm

Posted in digital audio

Tagged with , ,

Leave a Reply

*

Switch to our mobile site