Commit b645cdb5 authored by Michael Murtaugh's avatar Michael Murtaugh
Browse files

added demos and code

parent 6f7801d9
Unify!
1. POC: jquery.playable for uniform playable elements (html5media/youtube/vimeo)
2. Write timeline using playable
# (Static) titles synced to a vid (cascading)
So, a video tag will be BOTH playable and a timeline
(Add timeline fn to playable?!)
# Direct <audio>, <video> tag support
# starttime (via hash?)
$("#element").playable("play", )
* Deal with element dynamism (removal from screen)
* Deal with fast scrubbability
* Migrate old html5media, youtube, vimeo widgets to some kind of uniform aa "playable" interface
** standard events/interface
** support for start and end (via fragment or other means ?!)
* Thinking fun range of widgets for different kinds of media (multi-image/ multi-format, book views? // archive.org)
* "Timeline" element for syncing multiple playables + static elements
+> ON THE FLY changes in playback quality / version
* Efficient loading / unloading (to support long format playlists)
=====================
jquery.timeline.js
* Allow simple external controls (scrubber, play button)
example
one or more audio at 30 seconds
annotations hung either directly to the audio (1)
or (2) relative to the master timeline
This diff is collapsed.
......@@ -3,129 +3,197 @@
<html>
<head>
<meta charset="utf-8" />
<title>jQuery timeline</title>
<title>Active Archives: Temporal HTML Javascript</title>
<!-- jquery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<!-- Highlight.js -->
<script src="http://yandex.st/highlightjs/5.16/highlight.min.js"></script>
<link rel="stylesheet" href="http://yandex.st/highlightjs/5.16/styles/zenburn.min.css">
<!-- syntaxhighlighter -->
<script src="../lib/syntaxhighlighter/scripts/shCore.js" ></script>
<script src="../lib/syntaxhighlighter/scripts/shBrushJScript.js" ></script>
<script src="../lib/syntaxhighlighter/scripts/shBrushXml.js" ></script>
<link href="../lib/syntaxhighlighter/styles/shCore.css" rel="stylesheet" />
<link href="../lib/syntaxhighlighter/styles/shThemeDefault.css" rel="stylesheet" />
<script>
hljs.tabReplace = ' ';
hljs.initHighlightingOnLoad();
</script>
$(document).ready(function () {
SyntaxHighlighter.all();
});
</script>
</head>
<body>
<p>
A Timeline corresponds to a virtual media element, that may contain other media elements.
Timeline is a partial implementation of the <a href="http://www.w3.org/TR/html5/video.html#synchronising-multiple-media-elements">HTML5 "controller"</a>, and mixes in some ideas from SMIL & <a href="http://www.w3.org/TR/media-frags">Media Fragments</a>.
</p>
<p>NB: Timeline follows an approach of using of temporal HTML, that is mixing in timing to existing HTML+CSS+Javascript, as opposed to introducting a new and external format for text / subtitles (like WebSRT, WebVVT ? cf?).
</p>
<h1>Active Archives: Temporal HTML Javascript</h2>
<p>
This page describes some Javascript libraries used in Active Archives
that enables time-based HTML. This project is inspired by a mixture of best
practices and ideas from HTML5, such as the proposed (but not yet implemented)
<a href="http://dev.w3.org/html5/spec/media-elements.html#attr-media-mediagroup">
mediagroup attribute</a>, as well as ideas from <a href="http://www.w3.org/AudioVideo/">
SMIL</a> & <a href="http://www.w3.org/TR/media-frags">Media Fragments</a>.
The approach here attempts to propose a minimal means of adding timing to existing HTML,
in contrast to approaches that introduce additional and external formats (WebSRT,
WebVVT) or consider special synchronized text to be a special case (ie HTML5 <a
href="http://dev.w3.org/html5/spec/media-elements.html#timed-text-tracks">Timed
Text Tracks</a>).
See also <a href="http://blog.gingertech.net/2011/05/01/html5-multi-track-audio-or-video/">
Sylvia Pfeiffer's blog entry</a> on multi track audio and video for background and related techniques.
</p>
<p>From Annotation to Playlist. Key idea: An annotation is potentially both passive, triggered by it's related media, or active: able to form the basis of a playlist.</p>
<h2>Related code</h2>
<ul>
<li>
<a href="playable.html">jquery.playable.js</a> : Abstraction wrapper to give a uniform interface around various media. Extendable. Includes html5 video, audio tags, YouTube, Virtual media (aka Void Player).
</li>
<li>
<a href="#timeline">jquery.timeline.js</a> : Allows time-based events related to a timed element (by default, "passive" in that it simply follows and is triggered by the element's timeupdate event)
</li>
</ul>
<h2>More Examples</h2>
<ul>
<li>
<a href="annotation.html">Video drives Annotation(s)</a>
</li>
<li>
<a href="annotation_driving.html">Annotation drives Video (& Annotations)</a>
</li>
<li>
<a href="playlist.html">Multi-source Annotation</a>
</li>
<li>
<a href="virtual.html">Virtual Timeline</a>
</li>
<li>
<a href="cascading.html">Cascading Timeline with Embedded Media</a>
</li>
</ul>
<h3>Generic Setup Code</h3>
<p>
The following code creates/ensures timeline elements and associates them with any referring HTML elements.
</p>
<script type="syntaxhighlighter" class="brush: js">
var timelines = {};
$("[mediagroup]").each(function() {
var timeline = timelines[$(this).attr("mediagroup")];
if (timeline === undefined) {
timeline = new Timeline();
timelines[$(this).attr("mediagroup")] = timeline;
}
timeline.add(this);
});
</script>
<h2>Examples</h2>
The timeline, on adding, searches within the added DOM element for timed (sub)elements, ie things with attributes data-begin and data-end.
<ul>
<li>Simple subtitles: video + timed titles, inpage</li>
<li>"Void player": timed text</li>
<li> >1 video on a single timeline, sequential</li>
<li> >1 video on a single timeline, overlapping (synchronization)</li>
<li>Elements with a data-begin (and optionally data-end)</li>
</ul>
<a href="http://blog.gingertech.net/2011/05/01/html5-multi-track-audio-or-video/">Sylvia Pfeiffer's blog entry</a>
<pre>
The algorithm:
1. Add all audio, video tags to the controller specified by their mediagroup (or create a controller based on their source)
$("video[mediagroup]|audio[mediagroup]").each(function() {
var mediagroup = $(this).attr("mediagroup") || $(this).attr("src");
var controller = controllerForMediaGroup(mediagroup);
var begin = $(this).attr("data-begin");
var end = $(this).attr("data-end");
controller.add(this, begin, end);
});
<h3>Hello world (trivial example)</h3>
<p>
Example of a single video connected to controller. By default, without other attributes, adding the mediagroup attribute has no apparent effect.
</p>
2. Find all things with timing, and add to the controller corresponding to the closest mediagroup attribute (on the element itself, or in an ancestor).
<script type="syntaxhighlighter" class="brush: html">
<video src="sadie-plant.ogg" controls mediagroup="sadie-plant"></video>
</script>
in code:
<h3>Using custom Javascript controls</h3>
$("[data-begin]").each(function () {
var mediagroup = $(this).closest("[mediagroup]").attr("mediagroup");
var controller = controllerForMediaGroup(mediagroup);
var begin = $(this).attr("data-begin");
var end = $(this).attr("data-end");
controller.add(this, begin, end);
<script type="syntaxhighlighter" class="brush: html">
<video src="sadie-plant.ogg" controls mediagroup="master"></video>
<div class="aacontrols" mediagroup="master" ></div>
</script>
... and Javascript to "activate" the scrubber:
<script type="syntaxhighlighter" class="brush: js">
$(document).ready(function () {
$(".aacontrols").aacontrols();
});
</pre>
</script>
<h2>Hello world (one video wrapped in a controller)</h2>
<h3>Video with an offset</h3>
<p>
Example of a single video connected to controller. Proxies methods like play / pause. Echoes the media events (like play, timeupdate)
In this case, a data-begin attribute introduces a 5 second delay, then the video plays (from start to end). (cf is begin == startOffsetTime? attribute of HTML5 Media Elements)
</p>
<pre class="html"><code>
<video controls src="sadie-plant.ogg" mediagroup="sadie-plant.ogg">video</video>
</code></pre>
<script type="syntaxhighlighter" class="brush: html">
<video src="sadie-plant.ogg" controls mediagroup="sadie-plant" data-begin="5"></video>
</script>
<h2>Hello world 2 (one video wrapped in a controller, with an offset)</h2>
<p>
5 second delay, then the video plays (from start to end). (cf is begin == startOffsetTime? attribute of HTML5 Media Elements)
</p>
<pre class="html"><code>
<video begin="5" controls src="sadie-plant.ogg" mediagroup="sadie-plant.ogg">video</video>
</code></pre>
<p>Need a Visible controller</p>
<h3>Synchronized Videos</h3>
<script type="syntaxhighlighter" class="brush: html">
<video src="sadie-plant.ogg" controls mediagroup="master"></video>
<video src="michael-moss.ogg" controls mediagroup="master"></video>
</script>
<h2>2 Synced Videos</h2>
<pre class="html"><code>
<video controls src="sadie-plant.ogg" mediagroup="master">video 1</video>
<video controls src="michael-moss.ogg" mediagroup="master">video 2</video>
</code></pre>
<h2>2 Synced Videos, with an offset</h2>
<pre class="html"><code>
<h3>2 Synced Videos, with an offset</h3>
<script type="syntaxhighlighter" class="brush: html">
<video controls src="sadie-plant.ogg" mediagroup="master">video 1</video>
<video begin="10s" controls src="michael-moss.ogg" mediagroup="master">video 2</video>
</code></pre>
</script>
<h2><a name="simplesubtitles">Simple subtitles</a></h2>
<h3><a name="simplesubtitles">Simple subtitles</a></h3>
<p>
Example of a single video connected to timed subtitles.
</p>
<pre class="html"><code>
<video controls src="sadie-plant.ogg" mediagroup="sadie-plant.ogg">video</video>
<div id="subtitles" mediagroup="sadie-plant.ogg">
<div class="title" data-begin="00:02:21,766" data-end="00:03:19,393">
I have to begin with many thanks to Femke and Laurence, because it really has been a great pleasure for me to have been here this weekend. It’s nearly five years since I came to an event like this, believe it or not, and I really cannot say enough how much I have enjoyed it, and how stimulating I have found it. So yes, a big thank you to both for getting me here. And as you say, it’s ten years since I wrote Zeros + Ones, and you are marking ten years of this festival too, so it’s an interesting moment to think about a lot of the issues that have come up over the weekend. This is a more or less spontaneous report, very much an ‘open performance’, to use Simon Yuill’s words, and not to be taken as any kind of definitive account of what has happened this weekend. But still I hope it can bring a few of the many and varied strands of this event together, not to form a true conclusion, but perhaps to provide some kind of digestif after a wonderful meal.
<script type="syntaxhighlighter" class="brush: html">
<video controls src="sadie-plant.ogg" mediagroup="sadie-plant">video</video>
<div mediagroup="sadie-plant">
<div data-begin="00:02:21,766" data-end="00:03:19,393">
I have to begin with many thanks to Femke and Laurence, because it really
has been a great pleasure for me to have been here this weekend. Its nearly
five years since I came to an event like this, believe it or not, and I really
cannot say enough how much I have enjoyed it, and how stimulating I have found
it. So yes, a big thank you to both for getting me here. And as you say, its
ten years since I wrote Zeros + Ones, and you are marking ten years of this
festival too, so its an interesting moment to think about a lot of the issues
that have come up over the weekend. This is a more or less spontaneous report,
very much an open performance, to use Simon Yuills words, and not to be
taken as any kind of definitive account of what has happened this weekend. But
still I hope it can bring a few of the many and varied strands of this event
together, not to form a true conclusion, but perhaps to provide some kind of
digestif after a wonderful meal.
</div>
<div class="title" data-begin="00:03:19,393" data-end="00:03:48,937">
I thought I should begin as Femke very wisely began, with the theme of cooking. Femke gave us a recipe at the beginning of the weekend, really a kind of recipe for the whole event, with cooking as an example of the fact that there are many models, many activities, many things that we do in our everyday lives, which might inform and expand our ideas about technology and how we work with them.
<div data-begin="00:03:19,393" data-end="00:03:48,937">
I thought I should begin as Femke very wisely began, with the theme of cooking.
Femke gave us a recipe at the beginning of the weekend, really a kind of recipe
for the whole event, with cooking as an example of the fact that there are many
models, many activities, many things that we do in our everyday lives, which
might inform and expand our ideas about technology and how we work with them.
</div>
</div>
</code></pre>
</script>
<h2><a name="simplesubtitles">Timed Text</a></h2>
<h3><a name="simplesubtitles">Timed Text</a></h3>
Example of timed text only.
<pre class="html"><code>
<div id="timedtext" mediagroup="timedtext">
<div class="title" data-begin="00:02:21,766" data-end="00:03:19,393">
<script type="syntaxhighlighter" class="brush: html">
<div mediagroup="timedtext">
<div data-begin="00:02:21,766" data-end="00:03:19,393">
I have to begin with many thanks to Femke and Laurence, because it really has been a great pleasure for me to have been here this weekend. Its nearly five years since I came to an event like this, believe it or not, and I really cannot say enough how much I have enjoyed it, and how stimulating I have found it. So yes, a big thank you to both for getting me here. And as you say, its ten years since I wrote Zeros + Ones, and you are marking ten years of this festival too, so its an interesting moment to think about a lot of the issues that have come up over the weekend. This is a more or less spontaneous report, very much an open performance, to use Simon Yuills words, and not to be taken as any kind of definitive account of what has happened this weekend. But still I hope it can bring a few of the many and varied strands of this event together, not to form a true conclusion, but perhaps to provide some kind of digestif after a wonderful meal.
</div>
<div class="title" data-begin="00:03:19,393" data-end="00:03:48,937">
<div data-begin="00:03:19,393" data-end="00:03:48,937">
I thought I should begin as Femke very wisely began, with the theme of cooking. Femke gave us a recipe at the beginning of the weekend, really a kind of recipe for the whole event, with cooking as an example of the fact that there are many models, many activities, many things that we do in our everyday lives, which might inform and expand our ideas about technology and how we work with them.
</div>
</div>
</code></pre>
</script>
<h2><a name="simplesubtitles">Overlapping videos</a></h2>
<pre class="html"><code>
<h3><a name="simplesubtitles">Overlapping videos</a></h3>
<script type="syntaxhighlighter" class="brush: html">
<par mediagroup="playlist">
<div data-begin="00:01:00" data-end="00:06">
Sadie Plant speaking at VJ10 in Brussels.
......@@ -136,10 +204,10 @@ Example of timed text only.
<video controls src="michael-moss.ogg" >video</video>
</div>
</par>
</code></pre>
</script>
<h2><a name="simplesubtitles">Sequential videos</a></h2>
<pre class="html"><code>
<h3><a name="simplesubtitles">Sequential videos</a></h3>
<script type="syntaxhighlighter" class="brush: html">
<seq mediagroup="playlist">
<div >
Sadie Plant speaking at VJ10 in Brussels.
......@@ -150,11 +218,11 @@ Example of timed text only.
<video controls src="michael-moss.ogg" >video</video>
</div>
</seq>
</code></pre>
</script>
<h2><a name="simplesubtitles">Mixed source/type playlist</a></h2>
<h3><a name="simplesubtitles">Mixed source/type playlist</a></h3>
In a seq, begin times delay the start of each clip by a 3 seconds (3 seconds after the end of the previous element). See <a href="http://www.w3.org/TR/2008/REC-SMIL3-20081201/smil-timing.html#edef-seq">this example</a>.
<pre class="html"><code>
<script type="syntaxhighlighter" class="brush: html">
<seq mediagroup="playlist">
<div dur="10s">
Here are some interesting clips.
......@@ -165,12 +233,10 @@ In a seq, begin times delay the start of each clip by a 3 seconds (3 seconds aft
That's all folks.
</div>
</seq>
</code></pre>
<h2>Antonia Baeher On Scores</h2>
<pre class="html"><code>
</script>
<h3>Antonia Baeher On Scores</h3>
<script type="syntaxhighlighter" class="brush: xml">
<seq>
<par>
<video>
......@@ -196,8 +262,11 @@ In a seq, begin times delay the start of each clip by a 3 seconds (3 seconds aft
<img begin="00:02:54" end="00:03:15" src="unapresmidi.png">
</div>
</par>
</script>
<p>"Active Archives" style</p>
<!-- active archives style -->
<script type="syntaxhighlighter" class="brush: xml">
<audio src="interview.ogg" controls mediagroup="interview.ogg"></audio>
<div about="interview.ogg" mediagroup="interview.ogg">
<h2>Chronology</h2>
......@@ -230,7 +299,7 @@ In a seq, begin times delay the start of each clip by a 3 seconds (3 seconds aft
<img begin="00:00:34" end="00:02:54" src="holdinghands.png">
<img begin="00:02:54" end="00:03:15" src="unapresmidi.png">
</div>
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Active Archives: jquery.playable.js</title>
<!-- jquery -->
<script src="../lib/jquery/jquery-1.7.1.min.js"></script>
<script src="../lib/jquery/jquery-ui-1.8.17.custom.min.js"></script>
<link rel="stylesheet" href="../lib/jquery/css/ui-lightness/jquery-ui-1.8.17.custom.css" />
<!-- swfobject (used by jquery.playable.youtube.js) -->
<script src="../lib/swfobject/swfobject.js"></script>
<!-- syntaxhighlighter -->
<script src="../lib/syntaxhighlighter/scripts/shCore.js" ></script>
<script src="../lib/syntaxhighlighter/scripts/shBrushJScript.js" ></script>
<script src="../lib/syntaxhighlighter/scripts/shBrushXml.js" ></script>
<link href="../lib/syntaxhighlighter/styles/shCore.css" rel="stylesheet" />
<link href="../lib/syntaxhighlighter/styles/shThemeDefault.css" rel="stylesheet" />
<script src="../source/jquery.datetimecode.js"></script>
<script src="../source/jquery.playable.js"></script>
<script src="../source/jquery.playable.voidplayer.js"></script>
<script src="../source/jquery.playable.youtube.js"></script>
<style type="text/css" media="screen">
</style>
<script>
$(document).ready(function () {
SyntaxHighlighter.all();
// $(".playable").playable();
// $(".playable").playable("play");
$(".playset").each(function () {
var context = this;
// Activate the play button
$(".play", context).click(function () {
$(".playable", context).playable("toggle");
});
// Respond to events to update interface (optional)
$(".playable", context).bind('play', function () {
$(".play", context).text("pause");
}).bind('pause', function () {
$(".play", context).text("play");
}).bind("durationchange", function () {
var d = $(this).playable("duration");
$(".duration", context).text($.timecode_unparse(d, false))
}).bind("timeupdate", function () {
var ct = $(this).playable("currentTime");
$(".currenttime", context).text($.timecode_unparse(ct, false))
});
});
});
</script>
</head>
<body>
<h1><a href="index.html">demos</a> / jquery.playable.js</h1>
<h2>Javascript</h2>
<script type="syntaxhighlighter" class="brush: js">
$(".playset").each(function () {
var context = this;
// Activate the play button
$(".play", context).click(function () {
$(".playable", context).playable("toggle");
});
// Respond to events to update interface (optional)
$(".playable", context).bind('play', function () {
$(".play", context).text("pause");
}).bind('pause', function () {
$(".play", context).text("play");
}).bind("durationchange", function () {
var d = $(this).playable("duration");
$(".duration", context).text($.timecode_unparse(d, false))
}).bind("timeupdate", function () {
var ct = $(this).playable("currentTime");
$(".currenttime", context).text($.timecode_unparse(ct, false))
});
});
</script>
<h2>Audio/Video</h2>
<section>
<h3>HTML5 Video</h3>
<div class="playset">
<div>Video: Michael Moss (<span class="currenttime"></span>/<span class="duration"></span>)</div>
<div class="playable" data-type="video/ogg" data-src="http://video.constantvzw.org/vj12/Michael_Moss.ogv"></div>
<button class="play">play</button>
</div>
<script type="syntaxhighlighter" class="brush: html">
<div class="playset">
<div>Video: Michael Moss (<span class="currenttime"></span>/<span class="duration"></span>)</div>
<div class="playable" data-type="video/ogg" data-src="http://video.constantvzw.org/vj12/Michael_Moss.ogv"></div>
<button class="play">play</button>
</div>
</script>
</section>
<section>
<h3>HTML5 Audio</h3>
<div class="playset">
<div>Audio: Jonathan Burrows on Scores (<span class="currenttime"></span>/<span class="duration"></span>)</div>
<div class="playable" data-type="audio/ogg" data-src="Jonathan Burrows on scores.ogg"></div>
<button class="play">play</button>
</div>
<script type="syntaxhighlighter" class="brush: html">
<div class="playset">
<div>Audio: Jonathan Burrows on Scores (<span class="currenttime"></span>/<span class="duration"></span></div>
<div class="playable" data-type="audio/ogg" data-src="Jonathan Burrows on scores.ogg"></div>
<button class="play">play</button>
</div>
</script>
</section>
<h3>YouTube</h3>
<section>
<div class="playset">
<div>
Video: Jonathan Burrows The Stop Quartet
(<span class="currenttime"></span>/<span class="duration"></span>)
</div>
<div class="playable" data-src="http://www.youtube.com/watch?v=7z-5WmS4QDA"></div>
<button class="play">play</button>
</div>
<script type="syntaxhighlighter" class="brush: html">
<div class="playset">
<div>
Video: Jonathan Burrows The Stop Quartet
(<span class="currenttime"></span>/<span class="duration"></span>)
</div>
<div class="playable" data-src="http://www.youtube.com/watch?v=7z-5WmS4QDA"></div>
<button class="play">play</button>
</div>
</script>
</section>
<h2>Virtual Timeline</h2>
<div class="playset">
<div>Virtual clip (<span class="currenttime"></span>/<span class="duration"></span>)</div>
<div class="playable" data-type="void"></div>
<button class="play">play</button>
</div>
<script type="syntaxhighlighter" class="brush: html">
<div class="playset">
<div>Virtual clip (<span class="currenttime"></span>/<span class="duration"></span>)</div>
<div class="playable" data-type="void"></div>
<button class="play">play</button>
</div>
</script>
</body>
</html>