A declarative approach for HTML Timing using SMIL Timesheets
Here is a SMIL Timing adaptation of this HTML5/Audio demo (proposed by Samuel Goldszmidt, IRCAM) — but the HTML information is synchronized with the audio track, which is precisely the goal of our project.
controls: | |
The four buttons above allow to quickly jump to the different musical sections. No specific JavaScript code is used for these navigation buttons: again, this is pure SMIL Timing.
Many thanks to Florence Baschet’s and the Quatuor Danel for allowing us to reproduce this extract.
The markup is very similar to the one we’ve used for the previous example:
<div id="media" smil:timeContainer="excl" smil:mediaSync="audio" smil:first = "firstSection.click" smil:prev = "prevSection.click" smil:next = "nextSection.click" smil:last = "lastSection.click"> <div id="section1" smil:begin="0:00"> <img alt="treble clef" style="float: left;" src="images/music-trebleClef.png" /> While the three other instruments hold a cluster of high notes, the cellist’s silent gestures interact with them, provoking a windy sonority that becomes noisier as the cellist’s gestures become more energetic. </div> <div id="section2" smil:begin="0:36"> […] </div> <div id="section3" smil:begin="0:43"> […] </div> <div id="section4" smil:begin="1:09"> […] </div> <div id="section5" smil:begin="2:04"> […] </div> <div id="section6" smil:begin="3:10"> […] </div> </div> <div id="mediaController"> <div id="mediaTimeline"> […] </div> <audio id="audioPlayer" controls autoplay preload="auto"> <source src="media/StreicherKreis_BASCHET_extract.ogg" type="audio/ogg" /> <source src="media/StreicherKreis_BASCHET_extract.mp3" type="audio/mpeg" /> Your browser does not support the HTML5 <audio> tag, please upgrade to a modern browser to see this demo. </audio> </div>
The main difference is that we’re using the (non-standard)
mediaSync
attribute to select the <audio>
element as the syncMaster.
These four attributes are used to describe a basic user interaction. Each value refer to an HTML element event:
[elementID].[event]
In the example above, these attributes are defined as follows:
<div id="media" smil:timeContainer="excl" smil:end="4:09" smil:first = "firstSection.click" smil:prev = "prevSection.click" smil:next = "nextSection.click" smil:last = "lastSection.click">
and they point to this navigation menu:
<p class="menu"> <button id="firstSection" title="first section"> « </button> <button id="prevSection" title="previous section"> < prev </button> <button id="nextSection" title="next section"> next > </button> <button id="lastSection" title="last section"> » </button> </p>
These first/prev/next/last attributes are defined in the Timesheets working draft, but
they aren’t (yet?) in the SMIL Timing
recommendation. They are supposed to be specific to
<excl>
time containers, but our implementation allows
to use them in <seq>
containers as well.
Note that similar time events can be used in begin
and
end
attributes, too.
Besides the native audio player, we've designed a visual timeline in order to access to any section directly. No specific JavaScript is involved here, it's just a set of links:
<div id="mediaTimeline"> <a href="#section1" style="width: 87px; background-color: #2cb3ec;"> <span>0:00 => 0:36</span> </a> <a href="#section2" style="width: 16px; background-color: #958b5f;"> <span>0:36 => 0:43</span> </a> <a href="#section3" style="width: 62px; background-color: #efa8a8;"> <span>0:43 => 1:09</span> </a> <a href="#section4" style="width:133px; background-color: #ed8484;"> <span>1:09 => 2:04</span> </a> <a href="#section5" style="width:159px; background-color: #ed5a5a;"> <span>2:04 => 3:10</span> </a> <a href="#section6" style="width:141px; background-color: #ec2c2c;"> <span>3:10 => 4:09</span> </a> </div>
Our timesheet scheduler checks for hash changes and activates the target's parent time container on the corresponding time position. This ensures your anchor is properly displayed -- both spatially and temporally.
We still had to write some specific JavaScript code to sync the play/pause buttons and the time cursor between our visual timeline and the native audio player. The code is very simple but it's specific to the HTML5 media API -- see timeline.js (~50 lines of code).
We’re using transitions on CSS transformations to animate the media annotation blocks:
div#media { /* define a 1s transition on all properties */ transition : all 1s; -o-transition : all 1s; -moz-transition : all 1s; -webkit-transition : all 1s; } div#media div[smil=idle] { /* position and shape before the transition */ opacity: 0; transform : scale(0.3) translate(+200%); -o-transform : scale(0.3) translate(+200%); -moz-transform : scale(0.3) translate(+200%); -webkit-transform : scale(0.3) translate(+200%); } div#media div[smil=done] { /* position and shape after the transition */ opacity: 0; transform : scale(0.3) translate(-200%); -o-transform : scale(0.3) translate(-200%); -moz-transform : scale(0.3) translate(-200%); -webkit-transform : scale(0.3) translate(-200%); } div#media div[smil=active] { /* position and shape when active */ opacity: 1; /* «transform: none;» is implicit */ }
Firefox users: these CSS transitions require Firefox 4.
Internet Explorer users: your browser doesn't support CSS transitions at all.