2012-12-09 00:44:17 +00:00
|
|
|
'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({
|
2014-07-24 09:28:01 +00:00
|
|
|
audio: function() {
|
|
|
|
self.options.position = -1;
|
|
|
|
self.options.track = -1;
|
|
|
|
that.options({
|
|
|
|
paused: true,
|
|
|
|
position: 0,
|
|
|
|
track: 0
|
|
|
|
});
|
|
|
|
},
|
2012-12-09 00:44:17 +00:00
|
|
|
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();
|
|
|
|
},
|
2012-12-09 17:12:25 +00:00
|
|
|
time: function() {
|
|
|
|
self.options.time = self.options.time == 'elapsed'
|
|
|
|
? 'remaining' : 'elapsed';
|
|
|
|
toggleTime();
|
|
|
|
},
|
2012-12-09 00:44:17 +00:00
|
|
|
track: function() {
|
|
|
|
setTrack(self.options.track);
|
|
|
|
},
|
|
|
|
volume: function() {
|
|
|
|
setVolume(self.options.volume);
|
|
|
|
},
|
|
|
|
width: setSizes
|
|
|
|
})
|
|
|
|
.addClass('OxAudioPlayer')
|
|
|
|
.css({width: self.options.width + 'px'})
|
|
|
|
.bindEvent({
|
2012-12-11 15:35:45 +00:00
|
|
|
key_0: toggleMuted,
|
|
|
|
key_equal: function() {
|
|
|
|
setVolume(Ox.min(self.options.volume + 0.1, 1));
|
|
|
|
},
|
|
|
|
key_minus: function() {
|
|
|
|
setVolume(Ox.max(self.options.volume - 0.1, 0));
|
|
|
|
},
|
2012-12-09 00:44:17 +00:00
|
|
|
key_space: togglePaused
|
|
|
|
});
|
|
|
|
|
|
|
|
self.tracks = self.options.audio.length;
|
2012-12-09 17:12:25 +00:00
|
|
|
self.volume = self.options.muted ? 1 : self.options.volume;
|
2012-12-09 00:44:17 +00:00
|
|
|
|
2014-08-19 08:18:35 +00:00
|
|
|
self.$listButton = Ox.MenuButton({
|
|
|
|
items: self.options.audio.slice(
|
|
|
|
Math.max(self.options.track - 10, 0),
|
|
|
|
Math.min(self.options.track + 11, self.tracks)
|
|
|
|
).map(function(track, index) {
|
|
|
|
index += Math.max(self.options.track - 10, 0);
|
|
|
|
return {
|
|
|
|
id: index.toString(),
|
|
|
|
title: formatTrack(track),
|
|
|
|
checked: index == self.options.track
|
|
|
|
};
|
|
|
|
}),
|
|
|
|
maxWidth: 256,
|
|
|
|
overlap: 'left',
|
|
|
|
title: 'select',
|
|
|
|
type: 'image'
|
|
|
|
})
|
|
|
|
.addClass('OxListButton')
|
|
|
|
.appendTo(that);
|
|
|
|
|
|
|
|
self.$shuffleButton = Ox.Button(
|
|
|
|
Ox.extend({overlap: 'left', type: 'image'}, getButtonOptions('shuffle'))
|
|
|
|
)
|
|
|
|
.addClass('OxShuffleButton')
|
|
|
|
.bindEvent({
|
|
|
|
click: toggleShuffle
|
|
|
|
})
|
|
|
|
.appendTo(that);
|
|
|
|
|
2012-12-09 00:44:17 +00:00
|
|
|
self.$repeatButton = Ox.Button(
|
2014-08-19 08:18:35 +00:00
|
|
|
Ox.extend({overlap: 'left', type: 'image'}, getButtonOptions('repeat'))
|
2012-12-09 00:44:17 +00:00
|
|
|
)
|
2012-12-18 16:46:43 +00:00
|
|
|
.addClass('OxRepeatButton')
|
2012-12-09 00:44:17 +00:00
|
|
|
.bindEvent({
|
|
|
|
click: function() {
|
|
|
|
setRepeat(
|
|
|
|
self.options.repeat == 0 ? -1
|
|
|
|
: self.options.repeat == -1 ? 1
|
|
|
|
: 0
|
|
|
|
);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.appendTo(that);
|
|
|
|
|
|
|
|
self.$trackLabel = Ox.Label({
|
|
|
|
textAlign: 'center',
|
|
|
|
title: '',
|
|
|
|
})
|
|
|
|
.addClass('OxTrackLabel')
|
|
|
|
.appendTo(that);
|
|
|
|
|
|
|
|
self.$playButtons = Ox.ButtonGroup({
|
|
|
|
buttons: [
|
|
|
|
{
|
|
|
|
id: 'current',
|
|
|
|
title: 'playPrevious',
|
2013-05-09 13:03:33 +00:00
|
|
|
tooltip: Ox._('Play Current Track')
|
2012-12-09 00:44:17 +00:00
|
|
|
},
|
|
|
|
Ox.extend({id: 'play'}, getButtonOptions('play')),
|
|
|
|
{
|
|
|
|
id: 'next',
|
|
|
|
title: 'playNext',
|
2013-05-09 13:03:33 +00:00
|
|
|
tooltip: Ox._('Play Next Track')
|
2012-12-09 00:44:17 +00:00
|
|
|
}
|
|
|
|
],
|
|
|
|
overlap: 'right',
|
|
|
|
type: 'image',
|
|
|
|
})
|
2012-12-18 16:46:43 +00:00
|
|
|
.addClass('OxPlayButtons')
|
2012-12-09 00:44:17 +00:00
|
|
|
.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.$positionLabel = Ox.Label({
|
|
|
|
textAlign: 'center',
|
|
|
|
title: '00:00:00',
|
2013-05-09 13:03:33 +00:00
|
|
|
tooltip: Ox._('Show Remaining Time'),
|
2012-12-09 00:44:17 +00:00
|
|
|
width: 80
|
|
|
|
})
|
2012-12-18 16:46:43 +00:00
|
|
|
.addClass('OxPositionLabel')
|
2012-12-09 17:12:25 +00:00
|
|
|
.bindEvent({
|
|
|
|
anyclick: toggleTime
|
|
|
|
})
|
2012-12-09 00:44:17 +00:00
|
|
|
.appendTo(that);
|
|
|
|
|
|
|
|
self.$positionSlider = Ox.Range({
|
2012-12-11 21:49:53 +00:00
|
|
|
changeOnDrag: true,
|
2012-12-09 00:44:17 +00:00
|
|
|
max: 1,
|
2012-12-11 21:49:53 +00:00
|
|
|
min: 0,
|
2012-12-09 00:44:17 +00:00
|
|
|
step: 0.0000001,
|
|
|
|
})
|
2012-12-18 16:46:43 +00:00
|
|
|
.addClass('OxPositionSlider')
|
2012-12-09 00:44:17 +00:00
|
|
|
.bindEvent({
|
|
|
|
change: function(data) {
|
|
|
|
setPosition(data.value * self.duration);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.appendTo(that);
|
|
|
|
|
|
|
|
self.$muteButton = Ox.Button({
|
|
|
|
overlap: 'right',
|
|
|
|
title: 'mute',
|
2013-05-09 13:03:33 +00:00
|
|
|
tooltip: Ox._('Mute'),
|
2012-12-09 00:44:17 +00:00
|
|
|
type: 'image'
|
|
|
|
})
|
2012-12-18 16:46:43 +00:00
|
|
|
.addClass('OxMuteButton')
|
2012-12-09 17:12:25 +00:00
|
|
|
.bindEvent({
|
|
|
|
click: toggleMuted
|
|
|
|
})
|
2012-12-09 00:44:17 +00:00
|
|
|
.appendTo(that);
|
|
|
|
|
|
|
|
self.$volumeLabel = Ox.Label({
|
|
|
|
textAlign: 'center',
|
|
|
|
title: ' 100%',
|
2012-12-09 17:12:25 +00:00
|
|
|
width: 46
|
2012-12-09 00:44:17 +00:00
|
|
|
})
|
2012-12-18 16:46:43 +00:00
|
|
|
.addClass('OxVolumeLabel')
|
2012-12-09 17:12:25 +00:00
|
|
|
.bindEvent({
|
|
|
|
anyclick: function() {
|
|
|
|
setVolume(1);
|
|
|
|
}
|
|
|
|
})
|
2012-12-09 00:44:17 +00:00
|
|
|
.appendTo(that);
|
|
|
|
|
|
|
|
self.$volumeSlider = Ox.Range({
|
2012-12-11 21:49:53 +00:00
|
|
|
changeOnDrag: true,
|
2012-12-09 17:12:25 +00:00
|
|
|
max: 1,
|
|
|
|
min: 0,
|
2012-12-09 00:44:17 +00:00
|
|
|
size: 116,
|
2012-12-09 17:12:25 +00:00
|
|
|
step: 0.01,
|
|
|
|
value: self.options.volume,
|
2012-12-09 00:44:17 +00:00
|
|
|
})
|
2012-12-18 16:46:43 +00:00
|
|
|
.addClass('OxVolumeSlider')
|
2012-12-09 00:44:17 +00:00
|
|
|
.bindEvent({
|
|
|
|
change: function(data) {
|
2012-12-09 17:12:25 +00:00
|
|
|
setVolume(data.value);
|
2012-12-09 00:44:17 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.appendTo(that);
|
|
|
|
|
|
|
|
self.$audio = Ox.AudioElement({
|
2012-12-09 17:12:25 +00:00
|
|
|
src: self.options.audio[self.options.track].file
|
2012-12-09 00:44:17 +00:00
|
|
|
})
|
|
|
|
.bindEvent({
|
|
|
|
ended: function() {
|
|
|
|
playNext();
|
|
|
|
},
|
|
|
|
loadedmetadata: function(data) {
|
|
|
|
self.duration = data.duration;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.appendTo(that);
|
|
|
|
|
|
|
|
setTrack(self.options.track);
|
|
|
|
|
2014-08-19 08:18:35 +00:00
|
|
|
function formatTrack(data) {
|
|
|
|
return [
|
|
|
|
data.name, data.artist, data.album, data.year
|
|
|
|
].join(' · ');
|
|
|
|
}
|
|
|
|
|
2012-12-09 00:44:17 +00:00
|
|
|
function getButtonOptions(id) {
|
2012-12-09 17:12:25 +00:00
|
|
|
var options;
|
|
|
|
if (id == 'mute') {
|
|
|
|
options = self.options.muted || self.options.volume == 0
|
2013-05-09 13:03:33 +00:00
|
|
|
? {title: 'unmute', tooltip: Ox._('Unmute')}
|
2012-12-09 17:12:25 +00:00
|
|
|
: self.options.volume < 1/3
|
2013-05-09 13:03:33 +00:00
|
|
|
? {title: 'volumeUp', tooltip: Ox._('Mute')}
|
2012-12-09 17:12:25 +00:00
|
|
|
: self.options.volume < 2/3
|
2013-05-09 13:03:33 +00:00
|
|
|
? {title: 'volumeDown', tooltip: Ox._('Mute')}
|
|
|
|
: {title: 'mute', tooltip: Ox._('Mute')};
|
2012-12-09 17:12:25 +00:00
|
|
|
} else if (id == 'play') {
|
|
|
|
options = self.options.paused
|
2013-05-09 13:03:33 +00:00
|
|
|
? {title: 'play', tooltip: Ox._('Play')}
|
|
|
|
: {title: 'pause', tooltip: Ox._('Pause')};
|
2012-12-09 00:44:17 +00:00
|
|
|
} else if (id == 'repeat') {
|
2012-12-09 17:12:25 +00:00
|
|
|
options = self.options.repeat == 0
|
2013-05-09 13:03:33 +00:00
|
|
|
? {title: 'repeatNone', tooltip: Ox._('Repeat All')}
|
2012-12-09 00:44:17 +00:00
|
|
|
: self.options.repeat == -1
|
2013-05-09 13:03:33 +00:00
|
|
|
? {title: 'repeatAll', tooltip: Ox._('Repeat One')}
|
|
|
|
: {title: 'repeatOne', tooltip: Ox._('Repeat None')};
|
2012-12-09 00:44:17 +00:00
|
|
|
} else if (id == 'shuffle') {
|
2012-12-09 17:12:25 +00:00
|
|
|
options = self.options.shuffle
|
2013-05-09 13:03:33 +00:00
|
|
|
? {title: 'shuffleAll', tooltip: Ox._('Don\'t Shuffle')}
|
|
|
|
: {title: 'shuffleNone', tooltip: Ox._('Shuffle')};
|
2012-12-09 00:44:17 +00:00
|
|
|
}
|
2012-12-09 17:12:25 +00:00
|
|
|
return options;
|
2012-12-09 00:44:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
2014-07-24 09:28:01 +00:00
|
|
|
setPosition(self.options.position, 'audio')
|
2012-12-09 00:44:17 +00:00
|
|
|
that.triggerEvent('playing', {position: self.options.position});
|
|
|
|
}
|
|
|
|
|
|
|
|
function playNext() {
|
|
|
|
var track = getNextTrack();
|
|
|
|
if (track === null) {
|
2014-07-24 09:28:01 +00:00
|
|
|
// ...
|
2012-12-09 00:44:17 +00:00
|
|
|
} else {
|
|
|
|
setTrack(track);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function setPosition(position, from) {
|
2012-12-09 17:12:25 +00:00
|
|
|
self.options.position = position;
|
2014-07-24 09:28:01 +00:00
|
|
|
if (from != 'audio') {
|
2012-12-09 00:44:17 +00:00
|
|
|
self.$audio.currentTime(position);
|
|
|
|
}
|
|
|
|
self.$positionSlider.options({
|
|
|
|
value: position / self.duration
|
|
|
|
});
|
2012-12-09 17:12:25 +00:00
|
|
|
setTime();
|
2012-12-09 00:44:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function setRepeat(repeat) {
|
|
|
|
self.options.repeat = repeat;
|
|
|
|
self.$repeatButton.options(getButtonOptions('repeat'));
|
|
|
|
}
|
|
|
|
|
|
|
|
function setSizes() {
|
2012-12-18 16:46:43 +00:00
|
|
|
that.css({width: self.options.width + 'px'});
|
2014-08-19 08:18:35 +00:00
|
|
|
self.$trackLabel.options({width: self.options.width - 46});
|
2012-12-18 16:46:43 +00:00
|
|
|
self.$positionSlider.options({size: self.options.width - 262});
|
|
|
|
self.$positionLabel.css({left: self.options.width - 232 + 'px'});
|
|
|
|
self.$volumeLabel.css({left: self.options.width - 46 + 'px'})
|
2012-12-09 00:44:17 +00:00
|
|
|
}
|
|
|
|
|
2012-12-09 17:12:25 +00:00
|
|
|
function setTime() {
|
|
|
|
self.$positionLabel.options({
|
|
|
|
title: Ox.formatDuration(
|
|
|
|
self.options.time == 'elapsed'
|
|
|
|
? self.options.position
|
2012-12-10 00:02:42 +00:00
|
|
|
: self.options.audio[self.options.track].duration
|
2012-12-09 17:12:25 +00:00
|
|
|
- self.options.position
|
|
|
|
)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2012-12-09 00:44:17 +00:00
|
|
|
function setTrack(track) {
|
|
|
|
self.options.track = track;
|
|
|
|
self.$trackLabel.options({
|
2014-08-19 08:18:35 +00:00
|
|
|
title: formatTrack(self.options.audio[track])
|
2012-12-09 00:44:17 +00:00
|
|
|
});
|
2012-12-09 17:12:25 +00:00
|
|
|
self.$audio.options({src: self.options.audio[self.options.track].file});
|
2012-12-09 00:44:17 +00:00
|
|
|
!self.options.paused && self.$audio.play();
|
|
|
|
that.triggerEvent('track', {track: self.options.track});
|
|
|
|
}
|
|
|
|
|
|
|
|
function setVolume(volume) {
|
2012-12-09 17:12:25 +00:00
|
|
|
self.options.volume = volume;
|
|
|
|
if (volume > 0) {
|
|
|
|
self.volume = volume;
|
|
|
|
}
|
|
|
|
self.$audio.volume(volume);
|
|
|
|
self.$muteButton.options(getButtonOptions('mute'));
|
|
|
|
self.$volumeSlider.options({value: volume});
|
|
|
|
self.$volumeLabel.options({
|
|
|
|
title: ' ' + Math.round(volume * 100) + '%'
|
|
|
|
});
|
2012-12-09 00:44:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function toggleMuted() {
|
2012-12-09 17:12:25 +00:00
|
|
|
self.options.muted = !self.options.muted;
|
|
|
|
setVolume(self.options.muted ? 0 : self.volume);
|
2012-12-09 00:44:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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'))
|
|
|
|
}
|
|
|
|
|
2012-12-09 17:12:25 +00:00
|
|
|
function toggleTime() {
|
|
|
|
self.options.time = self.options.time == 'remaining'
|
|
|
|
? 'elapsed' : 'remaining';
|
|
|
|
setTime();
|
|
|
|
}
|
|
|
|
|
2012-12-09 00:44:17 +00:00
|
|
|
return that;
|
|
|
|
|
2013-05-09 13:03:33 +00:00
|
|
|
};
|