add rudimentary Ox.AudioPlayer and Ox.AudioElement

This commit is contained in:
rolux 2012-12-09 01:44:17 +01:00
parent 7dac327396
commit 074b658814
2 changed files with 451 additions and 0 deletions

View file

@ -0,0 +1,118 @@
'use strict';
/*@
Ox.AudioElement <f> AudioElement Object
@*/
Ox.AudioElement = function(options, self) {
self = self || {};
var that = Ox.Element({}, self)
.defaults({
autoplay: false,
preload: 'none',
src: ''
})
.options(options || {})
.update({
src: function() {
self.audio.src = self.options.src;
}
});
self.loadedMetadata = false;
self.paused = true;
self.$audio = $('<audio>')
.attr({src: self.options.src})
.on({
ended: function() {
that.triggerEvent('ended');
},
loadedmetadata: function() {
that.triggerEvent('loadedmetadata', {
duration: self.audio.duration
});
},
seeked: function() {
that.triggerEvent('seeked');
},
seeking: function() {
that.triggerEvent('seeking');
}
})
.appendTo(that);
self.audio = self.$audio[0];
function getset(key, value) {
var ret;
if (Ox.isUndefined(value)) {
ret = self.audio[key];
} else {
self.audio[key] = value;
ret = that;
}
return ret;
}
/*@
currentTime <f> get/set currentTime
@*/
that.currentTime = function() {
var ret;
self.ended = false;
if (arguments.length == 0) {
ret = self.audio.currentTime;
} else {
self.audio.currentTime = arguments[0];
ret = that;
}
return ret;
};
/*@
pause <f> pause
@*/
that.pause = function() {
self.paused = true;
self.audio.pause();
return that;
};
/*@
play <f> play
@*/
that.play = function() {
if (self.ended) {
that.currentTime(0);
self.ended = false;
}
self.paused = false;
self.audio.play();
return that;
};
/*@
src <f> get/set source
@*/
that.src = function() {
var ret;
if (arguments.length == 0) {
ret = self.audio.src;
} else {
self.options.src = arguments[0];
self.audio.src = self.options.src;
ret = that;
}
return ret;
};
/*@
volume <f> get/set volume
@*/
that.volume = function(value) {
return getset('volume', arguments[0]);
};
return that;
};

View file

@ -0,0 +1,333 @@
'use strict';
/*@
Ox.AudioPlayer <f> Generic Audio Player
@*/
Ox.AudioPlayer = function(options, self) {
self = self || {};
var that = Ox.Element({}, self)
.defaults({
audio: [],
muted: false,
paused: false,
position: 0,
repeat: 0,
shuffle: false,
time: 'elapsed',
track: 0,
volume: 1,
width: 512
})
.options(options || {})
.update({
muted: function() {
self.options.muted = !self.options.muted;
toggleMuted();
},
paused: function() {
self.options.paused = !self.options.paused;
togglePaused();
},
position: function() {
setPosition(self.options.position);
},
repeat: function() {
setRepeat(self.options.repeat);
},
shuffle: function() {
self.options.shuffle = !self.options.shuffle;
toggleShuffle();
},
track: function() {
setTrack(self.options.track);
},
volume: function() {
setVolume(self.options.volume);
},
width: setSizes
})
.addClass('OxAudioPlayer')
.css({width: self.options.width + 'px'})
.bindEvent({
key_space: togglePaused
});
self.positionSliderWidth = self.options.width - 262;
self.tracks = self.options.audio.length;
self.$repeatButton = Ox.Button(
Ox.extend({overlap: 'right', type: 'image'}, getButtonOptions('repeat'))
)
.css({
borderBottomLeftRadius: 0
})
.bindEvent({
click: function() {
setRepeat(
self.options.repeat == 0 ? -1
: self.options.repeat == -1 ? 1
: 0
);
}
})
.appendTo(that);
self.$shuffleButton = Ox.Button(
Ox.extend({overlap: 'left', type: 'image'}, getButtonOptions('shuffle'))
)
.css({
right: 0,
borderBottomRightRadius: 0
})
.bindEvent({
click: toggleShuffle
})
.appendTo(that);
self.$trackLabel = Ox.Label({
textAlign: 'center',
title: '',
width: self.options.width - 32
})
.addClass('OxTrackLabel')
.appendTo(that);
self.$playButtons = Ox.ButtonGroup({
buttons: [
{
id: 'current',
title: 'playPrevious',
tooltip: 'Play Current Track'
},
Ox.extend({id: 'play'}, getButtonOptions('play')),
{
id: 'next',
title: 'playNext',
tooltip: 'Play Next Track'
}
],
overlap: 'right',
type: 'image',
})
.css({
top: '15px'
})
.bindEvent({
click: function(data) {
if (data.id == 'current') {
setPosition(0);
} else if (data.id == 'play') {
togglePaused();
} else if (data.id == 'next') {
playNext();
}
}
})
.appendTo(that);
$(self.$playButtons.find('.OxButton')[0]).css({borderTopLeftRadius: 0});
self.$positionLabel = Ox.Label({
textAlign: 'center',
title: '00:00:00',
tooltip: 'Show Remaining Time',
width: 80
})
.css({
left: self.positionSliderWidth + 30 + 'px',
top: '15px',
height: '13px',
paddingTop: '1px',
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
fontSize: '10px'
})
.appendTo(that);
self.$positionSlider = Ox.Range({
max: 1,
min: 0,
step: 0.0000001,
size: self.positionSliderWidth
})
.css({
left: '46px',
top: '15px'
})
.bindEvent({
change: function(data) {
setPosition(data.value * self.duration);
}
})
.appendTo(that);
self.$muteButton = Ox.Button({
overlap: 'right',
title: 'mute',
tooltip: 'Mute',
type: 'image'
})
.css({
right: '151px',
top: '15px'
})
.appendTo(that);
self.$volumeLabel = Ox.Label({
textAlign: 'center',
title: '&nbsp;&nbsp;100%',
width: 48
})
.css({
left: self.options.width - 48 + 'px',
top: '15px',
height: '13px',
paddingTop: '1px',
borderTopRightRadius: 0,
fontSize: '10px'
})
.appendTo(that);
self.$volumeSlider = Ox.Range({
size: 116,
value: self.options.volume * 100,
})
.css({
right: '35px',
top: '15px'
})
.bindEvent({
change: function(data) {
self.options.volume = data.value / 100;
self.$audio.volume(self.options.volume);
self.$volumeLabel.options({
title: data.value + '%'
});
}
})
.appendTo(that);
self.$audio = Ox.AudioElement({
src: self.options.audio[self.options.track].src
})
.bindEvent({
ended: function() {
playNext();
},
loadedmetadata: function(data) {
self.duration = data.duration;
}
})
.appendTo(that);
setTrack(self.options.track);
function getButtonOptions(id) {
if (id == 'play') {
return self.options.paused
? {title: 'play', tooltip: 'Play'}
: {title: 'pause', tooltip: 'Pause'}
} else if (id == 'repeat') {
return self.options.repeat == 0
? {title: 'repeatNone', tooltip: 'Repeat All'}
: self.options.repeat == -1
? {title: 'repeatAll', tooltip: 'Repeat One'}
: {title: 'repeatOne', tooltip: 'Repeat None'}
} else if (id == 'shuffle') {
return self.options.shuffle
? {title: 'shuffleAll', tooltip: 'Don\'t Shuffle'}
: {title: 'shuffleNone', tooltip: 'Shuffle'};
}
}
function getNextTrack() {
return self.options.repeat == 1 ? self.options.track
: self.options.track < self.tracks - 1 ? self.options.track + 1
: self.options.repeat == -1 ? 0
: null;
}
function playing() {
self.options.position = self.$audio.currentTime();
setPosition(self.options.position, 'video')
that.triggerEvent('playing', {position: self.options.position});
}
function playNext() {
var track = getNextTrack();
if (track === null) {
} else {
setTrack(track);
}
}
function setPosition(position, from) {
if (from != 'video') {
self.$audio.currentTime(position);
}
self.$positionSlider.options({
value: position / self.duration
});
self.$positionLabel.options({
title: Ox.formatDuration(
self.options.time == 'elapsed'
? self.options.position
: self.options.duration - self.options.position
)
});
}
function setRepeat(repeat) {
self.options.repeat = repeat;
self.$repeatButton.options(getButtonOptions('repeat'));
}
function setSizes() {
}
function setTrack(track) {
var data = self.options.audio[track];
self.options.track = track;
self.$trackLabel.options({
title: [
data.title, data.artist, data.album, data.year
].join(' &mdash; ')
});
self.$audio.options({src: self.options.audio[self.options.track].src});
!self.options.paused && self.$audio.play();
that.triggerEvent('track', {track: self.options.track});
}
function setVolume(volume) {
}
function toggleMuted() {
}
function togglePaused() {
self.options.paused = !self.options.paused;
self.$playButtons.buttonOptions('play', getButtonOptions('play'));
if (self.options.paused) {
self.$audio.pause();
clearInterval(self.playInterval);
} else {
self.$audio.play();
self.playInterval = setInterval(playing, 100);
}
that.triggerEvent('paused', {paused: self.options.paused});
}
function toggleShuffle() {
self.options.shuffle = !self.options.shuffle;
self.$shuffleButton.options(getButtonOptions('shuffle'))
}
return that;
};