1 define([ 'util/ensureCallback', 'util/cacheBust', 'util/timeout' ], function (ensureCallback
, cacheBust
, timeout
) {
4 function getPlayLatency(audio
, callback
) {
5 callback
= ensureCallback(callback
);
10 var endTime
= Date
.now();
12 audio
.removeEventListener('play', update
, false);
13 audio
.removeEventListener('timeupdate', update
, false);
16 callback(null, endTime
- startTime
);
19 audio
.addEventListener('play', update
, false);
20 audio
.addEventListener('timeupdate', update
, false);
22 startTime
= Date
.now();
26 function audioLatency(callback
) {
27 callback
= ensureCallback(callback
);
30 callback(new Error('Audio not supported'));
34 var audio
= new window
.Audio();
36 function onCanPlayThrough() {
37 audio
.removeEventListener('canplaythrough', onCanPlayThrough
, false);
39 // Run the test twice: once for "cold" time, once for "warm" time.
40 getPlayLatency(audio
, function (err
, coldTime
) {
46 getPlayLatency(audio
, function (err
, warmTime
) {
53 pass
: coldTime
<= MAX_LATENCY
&& warmTime
<= MAX_LATENCY
,
54 coldLatency
: coldTime
,
62 callback(new Error('Failed to load audio'));
65 var source
= document
.createElement('source');
66 source
.src
= cacheBust
.url('assets/silence.wav');
67 source
.addEventListener('error', onError
, false);
69 audio
.addEventListener('canplaythrough', onCanPlayThrough
, false);
70 audio
.addEventListener('error', onError
, false);
71 audio
.appendChild(source
);
74 // Work around Webkit bug (present in Chrome <= 15, Safari <= 5, at
75 // time of writing) where the browser will decide it doesn't /need/
76 // to download all these pesky audio files.
77 window
['audio__' + Math
.random()] = audio
;
80 return function (callback
) {
81 callback
= ensureCallback(callback
);
83 timeout(5000, audioLatency
, callback
);