video multi sync multi angle

by Craig Martin

HTML

<div id="container">
    <div id="notice">Attention! You'll need a high performance computer and a browser with extended HTML5 Support!
        <br />For best performance please close all running applications and use <a href="http://www.apple.com/safari/" target="_blank">Safari</a> (on Mac) or <a href="http://www.google.com/chrome/" target="_blank">Chrome</a> (on Windows).</div>
    <div class="player" id="player-1">
        <ul class="switch"></ul>
        <div class="videos"></div>
        <div class="loaded"><span class="back">0%</span><span class="front">0%</span>
        </div>
    </div>
    <div class="player" id="player-2">
        <ul class="switch"></ul>
        <div class="videos"></div>
        <div class="loaded"><span class="back">0%</span><span class="front">0%</span>
        </div>
    </div>
    <div class="player" id="player-3">
        <ul class="switch"></ul>
        <div class="videos"></div>
        <div class="loaded"><span class="back">0%</span><span class="front">0%</span>
        </div>
    </div>
    <div class="player" id="player-4">
        <ul class="switch"></ul>
        <div class="videos"></div>
        <div class="loaded"><span class="back">0%</span><span class="front">0%</span>
        </div>
    </div>
    <div class="player" id="player-5">
        <ul class="switch"></ul>
        <div class="loaded"><span class="back">0%</span><span class="front">0%</span>
        </div>
    </div>
</div>

CSS

article, aside, details, figcaption, figure, footer, header, hgroup, nav, section {
    display:block;
}
audio, canvas, video {
    display:inline-block;
    *display:inline;
    *zoom:1;
}
audio:not([controls]) {
    display:none;
}
[hidden] {
    display:none;
}
html {
    font-size:100%;
    overflow-y:scroll;
    -webkit-text-size-adjust:100%;
    -ms-text-size-adjust:100%;
}
body {
    margin:0;
    font-size:13px;
    line-height:1.231;
}
body, button, input, select, textarea {
    font-family:sans-serif;
    color:#222;
}
::-moz-selection {
    background:#fe57a1;
    color:#fff;
    text-shadow:none;
}
::selection {
    background:#fe57a1;
    color:#fff;
    text-shadow:none;
}
a {
    color:#00e;
}
a:visited {
    color:#551a8b;
}
a:hover {
    color:#06e;
}
a:focus {
    outline:thin dotted;
}
a:hover, a:active {
    outline:0;
}
abbr[title] {
    border-bottom:1px dotted;
}
b, strong {
    font-weight:bold;
}
blockquote {
    margin:1em 40px;
}
dfn {
    font-style:italic;
}
hr {
    display:block;
    height:1px;
    border:0;
    border-top:1px solid #ccc;
    margin:1em 0;
    padding:0;
}
ins {
    background:#ff9;
    color:#000;
    text-decoration:none;
}
mark {
    background:#ff0;
    color:#000;
    font-style:italic;
    font-weight:bold;
}
pre, code, kbd, samp {
    font-family:monospace, monospace;
    _font-family:'courier new', monospace;
    font-size:1em;
}
pre {
    white-space:pre;
    white-space:pre-wrap;
    word-wrap:break-word;
}
q {
    quotes:none;
}
q:before, q:after {
    content:"";
    content:none;
}
small {
    font-size:85%;
}
sub, sup {
    font-size:75%;
    line-height:0;
    position:relative;
    vertical-align:baseline;
}
sup {
    top:-0.5em;
}
sub {
    bottom:-0.25em;
}
ul, ol {
    margin:1em 0;
    padding:0 0 0 40px;
}
dd {
    margin:0 0 0 40px;
}
nav ul, nav ol {
    list-style:none;
    list-style-image:none;
    margin:0;
    padding:0;
}
img {
    border:0;
    -ms-interpolation-mode:bicubic;
   ...

JavaScript

/*
	pub/sub plugin by Peter Higgins ([email protected])
	Loosely based on Dojo publish/subscribe API, limited in scope. Rewritten blindly.
	Original is (c) Dojo Foundation 2004-2010. Released under either AFL or new BSD, see:
	http://dojofoundation.org/license for more information.
*/
function hasClass(a, b) {
    return a.className.match(new RegExp("(\\s|^)" + b + "(\\s|$)"))
}
function addClass(a, b) {
    this.hasClass(a, b) || (a.className += " " + b)
}
function removeClass(a, b) {
    if (hasClass(a, b)) {
        var c = new RegExp("(\\s|^)" + b + "(\\s|$)");
        a.className = a.className.replace(c, "")
    }
}
var $ = {};
(function (a) {
    var b = {};
    a.publish = function (c, e) {
        if (b[c]) {
            var f = b[c].length;
            while (f--) b[c][f].apply(a, e || [])
        }
    }, a.subscribe = function (a, c) {
        return b[a] || (b[a] = []), b[a].push(c), [a, c]
    }, a.unsubscribe = function (a) {
        var c = a[0];
        if (b[c]) {
            var d = b[c].length;
            while (d--) b[c][d].splice(idx, 1)
        }
    }
})($), window.log = function () {
    log.history = log.history || [], log.history.push(arguments);
    if (this.console) {
        arguments.callee = arguments.callee.caller;
        var a = [].slice.call(arguments);
        typeof console.log == "object" ? log.apply.call(console.log, console, a) : console.log.apply(console, a)
    }
},
function (a) {
    function b() {}
    for (var c = "assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn".split(","), d; d = c.pop();) a[d] = a[d] || b
}(function () {
    try {
        return console.log(), window.console
    } catch (a) {
        return window.console = {}
    }
}());
var Video = function (a) {
    if (typeof a != "string") throw new Error("A video src is required");
    this.el = document.createElement("video"), this.el.preload = "none",...