oxjs/source/Ox.UI/js/Audio/AudioPlayer.js

391 lines
12 KiB
JavaScript
Raw Normal View History

'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({
audio: function() {
self.options.position = -1;
self.options.track = -1;
that.options({
paused: true,
position: 0,
track: 0
});
},
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();
},
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));
},
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;
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);
self.$repeatButton = Ox.Button(
2014-08-19 08:18:35 +00:00
Ox.extend({overlap: 'left', type: 'image'}, getButtonOptions('repeat'))
)
.addClass('OxRepeatButton')
.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')
},
Ox.extend({id: 'play'}, getButtonOptions('play')),
{
id: 'next',
title: 'playNext',
2013-05-09 13:03:33 +00:00
tooltip: Ox._('Play Next Track')
}
],
overlap: 'right',
type: 'image',
})
.addClass('OxPlayButtons')
.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'),
width: 80
})
.addClass('OxPositionLabel')
2012-12-09 17:12:25 +00:00
.bindEvent({
anyclick: toggleTime
})
.appendTo(that);
self.$positionSlider = Ox.Range({
2012-12-11 21:49:53 +00:00
changeOnDrag: true,
max: 1,
2012-12-11 21:49:53 +00:00
min: 0,
step: 0.0000001,
})
.addClass('OxPositionSlider')
.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'),
type: 'image'
})
.addClass('OxMuteButton')
2012-12-09 17:12:25 +00:00
.bindEvent({
click: toggleMuted
})
.appendTo(that);
self.$volumeLabel = Ox.Label({
textAlign: 'center',
title: '&nbsp;&nbsp;100%',
2012-12-09 17:12:25 +00:00
width: 46
})
.addClass('OxVolumeLabel')
2012-12-09 17:12:25 +00:00
.bindEvent({
anyclick: function() {
setVolume(1);
}
})
.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,
size: 116,
2012-12-09 17:12:25 +00:00
step: 0.01,
value: self.options.volume,
})
.addClass('OxVolumeSlider')
.bindEvent({
change: function(data) {
2012-12-09 17:12:25 +00:00
setVolume(data.value);
}
})
.appendTo(that);
self.$audio = Ox.AudioElement({
2012-12-09 17:12:25 +00:00
src: self.options.audio[self.options.track].file
})
.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(' &middot; ');
}
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')};
} 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')}
: self.options.repeat == -1
2013-05-09 13:03:33 +00:00
? {title: 'repeatAll', tooltip: Ox._('Repeat One')}
: {title: 'repeatOne', tooltip: Ox._('Repeat None')};
} 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 17:12:25 +00:00
return options;
}
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, 'audio')
that.triggerEvent('playing', {position: self.options.position});
}
function playNext() {
var track = getNextTrack();
if (track === null) {
// ...
} else {
setTrack(track);
}
}
function setPosition(position, from) {
2012-12-09 17:12:25 +00:00
self.options.position = position;
if (from != 'audio') {
self.$audio.currentTime(position);
}
self.$positionSlider.options({
value: position / self.duration
});
2012-12-09 17:12:25 +00:00
setTime();
}
function setRepeat(repeat) {
self.options.repeat = repeat;
self.$repeatButton.options(getButtonOptions('repeat'));
}
function setSizes() {
that.css({width: self.options.width + 'px'});
2014-08-19 08:18:35 +00:00
self.$trackLabel.options({width: self.options.width - 46});
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 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
)
});
}
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 17:12:25 +00:00
self.$audio.options({src: self.options.audio[self.options.track].file});
!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: '&nbsp;&nbsp;' + Math.round(volume * 100) + '%'
});
}
function toggleMuted() {
2012-12-09 17:12:25 +00:00
self.options.muted = !self.options.muted;
setVolume(self.options.muted ? 0 : self.volume);
}
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();
}
return that;
2013-05-09 13:03:33 +00:00
};