Seeking works in firefox

- Added support for indicating multiple buffered
  ranges (Firefox)
- Added volume slider (Chromium)
- Replaced stop button with faux pause button
- Added 'ended' event handler
This commit is contained in:
Joar Wandborg 2012-03-29 16:06:36 +02:00
parent 352a180765
commit 97e40b5285
2 changed files with 148 additions and 34 deletions

View File

@ -10,6 +10,7 @@
height: 100%;
-webkit-transition: width .1s ease-out;
-moz-transition: width .1s ease-out;
transition: width .1s ease-out;
}
.audio-control-play-pause {
position: absolute;
@ -23,21 +24,37 @@
}
.audio-control-play-pause.playing {
color: #b71500;
letter-spacing: -17px;
margin-left: -7px;
}
.audio-control-play-pause.paused {
/* Warning: this means the the play button shows! */
color: rgb(134, 212, 177);
}
.buffered {
.buffered-indicators {
position: absolute;
bottom: 0;
left: 0;
height: 2px;
width: 0;
-webkit-transition: width 1s ease-out;
-moz-transition: width 1s ease-out;
background: rgba(134, 177, 212, 1);
cursor: pointer;
}
.buffered-indicators div {
position: absolute;
height: 2px;
left: 0;
background: rgba(134, 177, 212, 1);
-webkit-transition: left 1s ease-out;
-moz-transition: left 1s ease-out;
transition: left 1s ease-out;
-webkit-transition: width 1s ease-out;
-moz-transition: width 1s ease-out;
transition: width 1s ease-out;
cursor: pointer;
}
.seekbar {
position: absolute;
top: 0;
@ -45,9 +62,23 @@
width: 100%;
height: 100%;
}
.audio-currentTime {
position: absolute;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
}
.audio-volume {
position: absolute;
left: 50px;
bottom: 10px;
opacity: 0.3;
-moz-transition: opacity .1s ease-in-out;
-webkit-transition: opacity .1s ease-in-out;
transition: opacity .1s ease-in-out;
}
.audio-spectrogram:hover .audio-volume {
opacity: 1;
}

View File

@ -21,46 +21,110 @@ var audioPlayer = new Object();
(function (audioPlayer) {
audioPlayer.init = function (audioElement) {
audioPlayer.audioElement = audioElement;
console.log(audioElement);
attachEvents();
$(audioElement).hide();
};
function attachEvents () {
audioPlayer.audioElement.addEventListener('durationchange', audioPlayer.durationChange, true);
audioPlayer.audioElement.addEventListener('timeupdate', audioPlayer.timeUpdate, true);
audioPlayer.audioElement.addEventListener('progress', audioPlayer.onProgress, true);
audioPlayer.audioElement.addEventListener(
'durationchange', audioPlayer.durationChange, true);
audioPlayer.audioElement.addEventListener(
'timeupdate', audioPlayer.timeUpdate, true);
audioPlayer.audioElement.addEventListener(
'progress', audioPlayer.onProgress, true);
audioPlayer.audioElement.addEventListener(
'ended', audioPlayer.onEnded, true);
$(document).ready( function () {
$('.audio-spectrogram').delegate('.seekbar', 'click', audioPlayer.onSeek);
$('.audio-spectrogram').delegate('.audio-control-play-pause', 'click', audioPlayer.playPause);
$('.audio-spectrogram').delegate(
'.seekbar', 'click', audioPlayer.onSeek);
$('.audio-spectrogram').delegate(
'.audio-control-play-pause', 'click', audioPlayer.playPause);
$('.audio-spectrogram').delegate(
'.audio-volume', 'change', audioPlayer.onVolumeChange);
$('.audio-media').delegate(
'.audio-spectrogram', 'attachedControls',
audioPlayer.onControlsAttached);
});
}
audioPlayer.onProgress = function(a, b, c) {
console.log(a, b, c);
buffered = audioPlayer.audioElement.buffered;
audioPlayer.onVolumeChange = function(e) {
console.log('volume change', e);
audioPlayer.audioElement.volume = e.target.value;
}
audioPlayer.onControlsAttached = function(e) {
console.log('Controls attached', e);
$('.audio-spectrogram .audio-volume').val(
Math.round(audioPlayer.audioElement.volume, 2));
}
audioPlayer.onProgress = function(e) {
/**
* Handler for file download progress
*/
console.log(e);
var buffered = audioPlayer.audioElement.buffered;
ranges = new Array();
for (i = 0; i < buffered.length; i++) {
ranges[i] = new Array();
ranges[i][0] = buffered.start(i);
ranges[i][1] = buffered.end(i);
var indicators = $('.audio-spectrogram .buffered-indicators div');
for (var i = 0; i < buffered.length; i++) {
if (!(i in indicators)) {
$('<div style="display: none;"></div>')
.appendTo($('.audio-spectrogram .buffered-indicators'))
.fadeIn(500);
indicators = $('.audio-spectrogram .buffered-indicators div');
}
var posStart = ((buffered.start(i) / audioPlayer.audioElement.duration)
* audioPlayer.imageElement.width());
var posStop = ((buffered.end(i) / audioPlayer.audioElement.duration)
* audioPlayer.imageElement.width());
console.log('indicators', indicators);
var indicator = $(indicators[i]);
indicator.css('left', posStart);
indicator.css('width', posStop - posStart);
}
/*
* Clean up unused indicators
*/
if (indicators.length > buffered.length) {
for (var i = buffered.length; i < indicators.length; i++) {
$(indicators[i]).fadeOut(500, function () {
this.remove();
});
}
}
console.log('ranges', ranges);
$('.audio-spectrogram .buffered').width(
(ranges[0][1] / audioPlayer.audioElement.duration) * audioPlayer.imageElement.width());
};
audioPlayer.onSeek = function (e) {
/**
* Callback handler for seek event, which is a .click() event on the
* .seekbar element
*/
console.log('onSeek', e);
im = audioPlayer.imageElement;
pos = e.offsetX / im.width();
var im = audioPlayer.imageElement;
var pos = (e.offsetX || e.originalEvent.layerX) / im.width();
audioPlayer.audioElement.currentTime = pos * audioPlayer.audioElement.duration;
audioPlayer.audioElement.play();
audioPlayer.setState(audioPlayer.PLAYING);
};
audioPlayer.onEnded = function (e) {
audioPlayer.setState(audioPlayer.PAUSED);
}
audioPlayer.playPause = function (e) {
console.log('playPause', e);
if (audioPlayer.audioElement.paused) {
@ -81,13 +145,15 @@ var audioPlayer = new Object();
audioPlayer.setState = function (state) {
if (state == audioPlayer.state) {
return;
} else {
audioPlayer.state = state;
}
switch (state) {
case audioPlayer.PLAYING:
$('.audio-spectrogram .audio-control-play-pause')
.removeClass('paused').addClass('playing')
.text('');
.text('▮▮');
break;
case audioPlayer.PAUSED:
$('.audio-spectrogram .audio-control-play-pause')
@ -98,37 +164,55 @@ var audioPlayer = new Object();
};
audioPlayer.durationChange = function () {
duration = audioPlayer.audioElement.duration;
// ???
};
audioPlayer.timeUpdate = function () {
currentTime = audioPlayer.audioElement.currentTime;
playhead = audioPlayer.imageElement.parent().find('.playhead');
playhead.css('width', (currentTime / audioPlayer.audioElement.duration) * audioPlayer.imageElement.width());
time = formatTime(currentTime);
duration = formatTime(audioPlayer.audioElement.duration);
audioPlayer.imageElement.parent().find('.audio-currentTime').text(time + '/' + duration);
/**
* Callback handler for the timeupdate event, responsible for
* updating the playhead
*/
var currentTime = audioPlayer.audioElement.currentTime;
var playhead = audioPlayer.imageElement.parent().find('.playhead');
playhead.css('width', (currentTime / audioPlayer.audioElement.duration)
* audioPlayer.imageElement.width());
var time = formatTime(currentTime);
var duration = formatTime(audioPlayer.audioElement.duration);
audioPlayer.imageElement.parent()
.find('.audio-currentTime')
.text(time + '/' + duration);
};
function formatTime(seconds) {
/**
* Format a time duration in (hh:)?mm:ss manner
*/
var h = Math.floor(seconds / (60 * 60));
var m = Math.floor((seconds - h * 60 * 60) / 60);
var s = Math.round(seconds - h * 60 * 60 - m * 60);
return '' + (h ? (h < 10 ? '0' + h : h) + ':' : '') + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
}
audioPlayer.formatTime = formatTime;
audioPlayer.attachToImage = function (imageElement) {
/**
* Attach the player to an image element
*/
console.log(imageElement);
im = $(imageElement);
var im = $(imageElement);
audioPlayer.imageElement = im;
$('<div class="playhead"></div>').appendTo(im.parent());
$('<div class="buffered"></div>').appendTo(im.parent());
$('<div class="buffered-indicators"></div>').appendTo(im.parent());
$('<div class="seekbar"></div>').appendTo(im.parent());
$('<div class="audio-control-play-pause paused">▶</div>').appendTo(im.parent());
$('<div class="audio-currentTime">00:00</div>').appendTo(im.parent());
$('<input placeholder="Range input not supported" class="audio-volume"'
+'type="range" min="0" max="1" step="0.01" />').appendTo(im.parent());
$('.audio-spectrogram').trigger('attachedControls');
};
})(audioPlayer);
@ -143,4 +227,3 @@ $(document).ready(function () {
audioPlayer.init(audioElements[0]);
audioPlayer.attachToImage($('.audio-spectrogram img')[0]);
});