add rudimentary Ox.AudioPlayer and Ox.AudioElement
This commit is contained in:
parent
7dac327396
commit
074b658814
2 changed files with 451 additions and 0 deletions
118
source/Ox.UI/js/Audio/AudioElement.js
Normal file
118
source/Ox.UI/js/Audio/AudioElement.js
Normal 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;
|
||||||
|
|
||||||
|
};
|
333
source/Ox.UI/js/Audio/AudioPlayer.js
Normal file
333
source/Ox.UI/js/Audio/AudioPlayer.js
Normal 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: ' 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(' — ')
|
||||||
|
});
|
||||||
|
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;
|
||||||
|
|
||||||
|
};
|
Loading…
Reference in a new issue