1
0
Fork 0

It plays stuff, sort off

master
Matthieu Lalonde 12 years ago
parent 08b5a8e62a
commit d7243f5b3b

@ -81,6 +81,8 @@ _
, initialize: function() {
_.bindAll(this
, "_serversInited"
, "_routerActionAbout"
, "_routerActionPlaylist"
, "_routerActionClient"
@ -105,14 +107,19 @@ _
this.playlist = new PlaylistCollection();
this.servers.on("add", function (server) {
server.save();
});
var serverLength = 0
, serverCbInit = function (server) {
if (serverLength > 1) {
--serverLength;
} else {
that._serversInited();
}
};
async.waterfall([
function __asyncAppFetchServerCollection(callback) {
that.servers.fetch({
success: function (collection, modelsAttributes) {
success: function __fnApEventServersFetched(collection, modelsAttributes) {
if (modelsAttributes.length === 0) {
console.info("Adding default daap server");
collection.add(Config.daap);
@ -126,11 +133,14 @@ _
}
, function __asyncAppAttachStateEvents(servers, callback) {
async.forEach(that.servers.models, function (server) {
that._serverInit(server);
serverLength = servers.length;
async.forEach(that.servers.models, function __fnAppCbServerInit(server) {
that._serverInit(server, serverCbInit);
});
that.servers.on("add", function (server) {
that.servers.on("add", function __fnAppCbServerAdded(server) {
server.save();
that._serverInit(server);
});
@ -149,6 +159,7 @@ _
that.Views.Player = new PlayerView({
el: that.Views.App.Layout.panes.north
, servers: that.servers
});
that.Views.Footer = new FooterView({
@ -166,12 +177,12 @@ _
that.Views.Main.setView("playlist", that.Views.Playlist);
that.View.Main.on("action:item", function __fnAppEventMainViewActionItem (event) {
that.Views.Main.on("action:item", function __fnAppEventMainViewActionItem (event) {
});
that.View.Main.on("action:playorder", function __fnAppEventMainViewActionItem (event) {
that.Views.Main.on("action:playorder", function __fnAppEventMainViewActionItem (event) {
that.Views.Player.setPlayIndex(event);
});
that.Views.Footer.on("toggle:sidebar", function __fnAppEventTogglerSiderBar (event) {
@ -180,11 +191,11 @@ _
});
that.Views.Footer.on("toggle:random", function __fnAppEventTogglerRandom (event) {
// TODO:...
that.Views.Player.setRandomState(event);
});
that.Views.Footer.on("toggle:repeat", function __fnAppEventTogglerRepeater (event) {
// TODO:...
that.Views.Player.setRepeatState(event);
});
that.Views.Footer.on("show:about", that.__showModalAbout);
@ -228,6 +239,17 @@ _
return this;
}
, _serversInited: function () {
var that = this
;
console.debug("All Base Servers Inited!");
that.Views.Player.init();
that.Views.Player.playAtIndex(0);//Math.floor(Math.random() * that.Views.Player._playIndex.length));
}
, _routerDefaultAction: function () {
var that = this
;
@ -317,7 +339,7 @@ _
that.Views.Main.showView(server.get("hostname"));
}
, _serverInit: function(server) {
, _serverInit: function(server, cbInit) {
var that = this
;
@ -327,6 +349,10 @@ _
server.client.off("all");
server.client.on("inited", function __fnAppEventClientInited(client) {
cbInit(null, client);
});
server.client.on("state", function __fnAppEventClientStateChange(client, state) {
if (state === ClientModel.defaults._states.loading) {
if (that.loadingStates === 0) {

@ -0,0 +1,81 @@
/*jslint laxbreak:true */
/*jslint laxcomma:true */
/*jslint loopfunc:true */
/*jslint strict:true */
/*jslint browser:true */
/*jslint devel:true */
/**
* TODO: If the user agrees, set the username/passs in a cookie
**/
define([
], function (
) {
"use strict";
var MIMESClass = function() {};
MIMESClass.prototype.get = function (file) {
var fileExtension = '';
var dotPos = 0;
var audioType = undefined;
if ((dotPos = file.indexOf('.')) >= 0) {
fileExtension = file.substring(dotPos + 1);
} else {
fileExtension = file;
}
switch (fileExtension) {
// TODO: Add ogg/flac (video?)
case "mp3":
audioType = "audio/mpeg";
break;
case "au":
case "snd":
audioType = "audio/basic";
break;
case "wav":
audioType = "audio/x-wav";
break;
case "aif":
case "aifc":
audioType = "audio/aiff";
break;
case "m4a":
case "mp4":
case "mp4a":
audioType = "audio/mp4";
break;
case "ogg":
case "oga":
audioType = "audio/ogg";
break;
case "flac":
audioType = "audio/flac";
break;
case "axa":
audioType = "audio/annodex";
break;
case "vorb":
audioType = "audio/vorbis";
break;
case "spx":
audioType = "audio/speex";
break;
default:
console.info('Unknown type: ' + fileExtension);
break;
}
return audioType;
};
return new MIMESClass();
});

@ -4,7 +4,7 @@
/*jslint strict:true */
/*jslint browser:true */
/*jslint devel:true */
require.config({
requirejs.config({
shim: {
"jquery-ui": ["jquery"]
, "jquery-event-drag": ["jquery"]
@ -90,21 +90,43 @@ require.config({
, baseUrl: "/resources/js"
, urlArgs: "v=0.3.2"
});
require([
"app"
, catchError: true
});
requirejs([
"underscore"
, "jquery"
, "app"
, "text!../templates/app/modal-fatal.html"
]
, function __fnMainRequireLoader ( App, $ ) {
, function __fnMainRequireLoader (
_
, $
, App
, tmplModalFatal
) {
"use strict";
// JQuery Backwords compatibility fix
$.curCSS = $.css;
$("body").ready(function __fnAppRequireLoader () {
//try {
// We export App to window for debuging purposes.
window.App = new App();
/*} catch (e) {
console.log("LAWL");
$("body").html("");
var modalFatal = $(_.template(tmplModalFatal)({
ERROR_REPORTING: e.toString()
}));
modalFatal.modal();
}*/
});
});

@ -29,6 +29,7 @@ define([
, "buildRequestUid"
, "url"
, "urlHost"
, "urlMedia"
, "xhr"
, "fetchXHR"
@ -40,7 +41,7 @@ define([
, "fetchPlaylists"
, "fetchPlaylist"
, "fetchBrowse"
, "fetchgenres"
, "fetchGenres"
, "fetchArtists"
, "fetchAlbums"
@ -172,14 +173,18 @@ define([
uri = request; // Add leading slash here!
}
if (_.isNumber(this.collections.session.id)) {
if (_.isNumber(that.collections.session.id)) {
var prefix = "?";
if (uri.indexOf("?") >= 0) {
prefix = "&";
}
uri += prefix + "session-id=" + this.collections.session.id;
uri += prefix + "session-id=" + that.collections.session.id;
}
if (uri.charAt(0) !== "/" && uri.charAt(0) !== "?") {
uri = "/" + uri;
}
return this.attributes.protocol + "://" + this.urlHost() + uri;
@ -192,6 +197,14 @@ define([
return this.attributes.hostname + ":" + this.attributes.port;
}
, urlMedia: function (itemid, type, dbid) {
if (_.isUndefined(dbid) || !_.isNumber(dbid)) {
dbid = 1;
}
return this.url("/databases/" + dbid + "/items/" + itemid + "." + type);
}
// TODO: Could be interesting to set a useragent, could possibly affect transcoding on the server side
, xhr: function (url, responseType, callback) {
var that = this
@ -292,7 +305,18 @@ define([
var that = this
;
that.fetchXHR("/login", success, error);
// TODO: Check for a cookie here...
that.fetchXHR("/login", function __fetchServerInfoCallback(content) {
var Results = new DMAPModel(content, {
contentCodes: that.collections.contentCodes
});
that.collections.session.id = Results.get("dmap_sessionid");
if (_.isFunction(success)) {
success(that.collections.session);
}
}, error);
}
, fetchDatabases: function (success, error) {

@ -32,6 +32,8 @@ define([
// that.save();
}
that.trigger("inited", that);
//that.client.fetchDatabases(that.client.fetchDatabase);
});

@ -24,13 +24,23 @@ _
, preload: "auto"
, controls: false
, loop: false
, src: ""
, src: false
}
, obj: new Audio()
, $obj: null
, _states: {
stopped: 0
, error: 1
, loading: 2
, playing: 3
, paused: 4
}
, _state: 0
, constructor: function () {
var that = this
;
@ -45,6 +55,8 @@ _
, "__audioError"
, "__audioPause"
, "__audioPlay"
, "__audioSeeking"
, "__audioSeeked"
, "__audioTimeUpdate"
, "__audioLoadStart"
, "__audioCanPlay"
@ -53,18 +65,40 @@ _
that.$obj = $(that.obj);
that.obj.attributes = _.extend({}, that.obj.attributes, that._defaultOpts);
_.each(that._defaultOpts, function (value, key) {
if (value !== false) {
that.obj.setAttribute(key, value);
}
});
that._bindAudio();
return that;
}
/**
* PUBLIC
**/
, loadMedia: function (uri) {
, loadMedia: function (uri, mime, callback) {
var that = this
, audioSource = document.createElement('source')
;
that.obj.stop();
audioSource.src = uri;
that.obj.src = uri;
audioSource.type = mime;
that.obj.type = mime;
that.obj.innerHTML = "";
that.obj.appendChild(audioSource);
console.debug("Loading media: " + uri + "\t type: " + mime);
that._state = that._states.loading;
that.obj.load();
return callback && callback();
}
/**
* PRIVATE
@ -81,7 +115,7 @@ _
//that.$obj.on("suspend", that.__audioSuspend);
//that.$obj.on("abort", that.__audioAbort);
that.$obj.on("abort", that.__audioError);
that.$obj.on("error", that.__audioError);
@ -104,9 +138,9 @@ _
//that.$obj.on("canplaythrough", that.__audioCanPlayThrough);
//that.$obj.on("seeking", that.__audioSeeking);
that.$obj.on("seeking", that.__audioSeeking);
//that.$obj.on("seeked", that.__audioSeeked);
that.$obj.on("seeked", that.__audioSeeked);
that.$obj.on("timeupdate", that.__audioTimeUpdate);
@ -114,7 +148,7 @@ _
//that.$obj.on("ratechange", that.__audioRateChanged);
//that.$obj.on("durationchange", that.__audioDurationChange);
//that.$obj.on("durationchange", that.__audioDurationChange); // TODO: We probably need to implement this!
//that.$obj.on("volumechange", that.__audioVolumeChange);
}
@ -123,34 +157,73 @@ _
* EVENTS
**/
, __audioProgress: function (event) {
var that = this
;
that.trigger("progress", event);
}
, __audioError: function (event) {
var that = this
;
that._state = that._states.stopped;
that.trigger.apply(that, ["state", that._state]);
}
, __audioPause: function (event) {
var that = this
;
that._state = that._states.paused;
that.trigger.apply(that, ["state", that._state]);
}
, __audioPlay: function (event) {
var that = this
;
that._state = that._states.playing;
that.trigger.apply(that, ["state", that._state]);
}
, __audioSeeking: function (event) {
var that = this
;
that._state = that._states.loading;
that.trigger.apply(that, ["state", that._state]);
}
, __audioSeeked: function (event) {
var that = this
;
that.obj.play();
that._state = that._states.playing;
that.trigger.apply(that, ["state", that._state]);
}
, __audioTimeUpdate: function (event) {
var that = this
;
that.trigger("timeupdate", event);
}
, __audioLoadStart: function (event) {
var that = this
;
that._state = that._states.loading;
that.trigger.apply(that, ["state", that._state]);
}
, __audioCanPlay: function (event) {
@ -163,6 +236,9 @@ _
var that = this
;
that._state = that._states.stopped;
that.trigger("ended", event);
}
}, Backbone.Events));

@ -121,6 +121,10 @@ _
, dbId: dbId
}
});
that.Views.List.on("action:playorder", function __fnEventClientViewPlayOrder (event) {
that.trigger.apply(that, ["action:playorder", event]);
});
}
, resize: function () {

@ -97,7 +97,7 @@ _
if (!that.__timeoutDebounceRepeatButton) {
that.__timeoutDebounceRepeatButton = setTimeout(function () {
that.trigger("toggle:repeat", that._stateRepeat);
that.trigger("toggle:repeat", that._stateRepeat || null);
delete that.__timeoutDebounceRepeatButton;
}, 500);

@ -480,6 +480,8 @@ console.log(parentWidth, that.$el.innerWidth(), parentHeight, that.$el, parentEl
that.dataTable.fnDraw();
that.resize();
that._setPlayOrder();
}
, hide: function () {
@ -488,6 +490,39 @@ console.log(parentWidth, that.$el.innerWidth(), parentHeight, that.$el, parentEl
this.$el.hide();
}
, _setPlayOrder: function () {
var that = this
, playIndex = []
;
playIndex = _.map(that.dataTable.fnSettings().aiDisplay, function (id, index) {
var itemData = that.dataTable.fnGetData(id)
, itemIndex = {}
;
if (that.options.type === "playlist") {
itemIndex.hostname = itemData.server;
itemIndex.dbId = itemData.database;
itemIndex.playlist = true;
} else {
itemIndex.hostname = that.options.client.hostname;
itemIndex.dbId = that.options.client.dbId;
itemIndex.playlist = null;
}
itemIndex.dmap_itemname = itemData["dmap_itemname"];
itemIndex.daap_songartist = itemData["daap_songartist"];
itemIndex.daap_songtime = itemData["daap_songtime"];
itemIndex.type = itemData["daap_songformat"];
itemIndex.id = itemData["dmap_persistantid"] || itemData["dmap_itemid"] || itemData["dmap_containeritemid"] || itemData["id"];
return itemIndex;
});
that.trigger("action:playorder", playIndex);
}
});
return List;

@ -35,6 +35,7 @@ _
, "resizeView"
//, "toggleView"
, "destroyView"
, "_setPlayOrder"
);
//that.setView("playlist", new ListView(playlistCollection));
@ -67,6 +68,8 @@ _
that.$el.append(that.children[name].$el);
}
that.children[name].on("action:playorder", that._setPlayOrder);
if (that.children[name].show) {
that.children[name].show();
}
@ -102,9 +105,13 @@ _
that.children[name].$el.hide();
that.children[name].off("action:player");
setTimeout(function __fnTimeoutMainViewHide() {
that.children[name].$el.detach();
delete that.current;
return callback && callback();
}, 50);
}
@ -131,6 +138,13 @@ _
, destroyView: function (name) {
}
, _setPlayOrder: function (event) {
var that = this
;
that.trigger.apply(that, ["action:playorder", event]);
}
});
return Main;

@ -11,6 +11,8 @@ define([
, "modules/webaudio"
, "libs/mimes"
, "text!../../templates/player/layout.html"
, "text!../../templates/player/player-status.html"
]
@ -21,6 +23,8 @@ _
, WebAudio
, MIMES
, tmplPlayerLayout
, tmplPlayerStatus
) {
@ -50,6 +54,7 @@ _
Player = Backbone.View.extend({
elViewport: null
, $elViewport: null
, $elVolumeInput: null
, playIndex: []
@ -61,6 +66,12 @@ _
, _stateRepeat: null
, _statesRepeat: {
none: null
, one: false
, all: true
}
, _stateMute: null
, _stateVolume: null
@ -76,22 +87,24 @@ _
, paused: 3
}
, debouncers: {}
, events: {
//"click #add-friend": "showPrompt",
"click div:first-child > a.buttonPrev":
"click div:first-child > a.buttonPrev:not(.disabled)":
"__buttonPrevious"
, "click div:first-child > a.buttonNext":
, "click div:first-child > a.buttonNext:not(.disabled)":
"__buttonNext"
, "click div:first-child > a.buttonPlay":
, "click div:first-child > a.buttonPlay:not(.disabled)":
"__buttonPlayPause"
// Volume Down
, "click div:first-child > .playerVolumeWrapper > a:first-child":
, "click div:first-child > .playerVolumeWrapper > a:first-child:not(.disabled)":
"__buttonVolumeDown"
// Volume Up
, "click div:first-child > .playerVolumeWrapper > a:last-child":
, "click div:first-child > .playerVolumeWrapper > a:last-child:not(.disabled)":
"__buttonVolumeUp"
// Volume click
, "click div:first-child > .playerVolumeWrapper > input":
, "click div:first-child > .playerVolumeWrapper > input:not(disabled)":
"__buttonVolumeClick"
// Seek input
, "click div:last-child > .playerProgressWrapper > progress":
@ -104,10 +117,13 @@ _
_.bindAll(this
// Public
, "init"
, "setPlayIndex"
, "sortPlayIndex"
, "setRandomState"
, "setRepeatState"
, "playItem"
, "playAtIndex"
// Events
, "__buttonPlayPause"
, "__buttonNext"
@ -120,17 +136,27 @@ _
, "_waCreate"
, "_waBindEvents"
, "__waStateChanged"
, "_playerEnded"
, "__waEnded"
, "__waTimeUpdate"
, "_playerPlay"
, "_playerLoading"
, "_playNext"
, "_playPrevious"
, "_playerPause"
, "_playerUnpause"
, "_playerStop"
, "_playerStart"
, "_getVolume"
, "_setVolume"
, "_seek"
, "_playBtnSetState"
, "_disableControls"
, "_enableControls"
, "_getItemData"
, "_getItemMediaUrl"
, "_setViewport"
, "_progressSetLoadding"
, "_updateViewportProgress"
);
@ -141,7 +167,9 @@ _
that.elViewport = document.createElement("div");
that.$elViewport = $(that.elViewport);
that.$elViewport.html(_.template(tmplPlayerStatus)({}));
that._setViewport();
that.$elVolumeInput = that.$el.find(".playerVolumeWrapper > input");
that.$el.append(that.elViewport);
@ -153,18 +181,42 @@ _
/**
* PUBLIC
**/
, setPlayIndex: function (index) {
, init: function () {
var that = this
;
that._enableControls();
that.$elVolumeInput.val(that.webAudio.obj.volume);
}
, setPlayIndex: function (index, cursor) {
var that = this
;
if (that.webAudio._state === that.webAudio._states.loading) {
that._playerStop();
}
if (that.webAudio._state < that.webAudio._states.loading) {
that._playIndex = index;
that._playCursor = 0;
that._playCursor = cursor || 0;
if (that._stateRandom) {
that.setRandomState(that._stateRandom);
}
return that._playIndex;
} else {
return undefined;
}
}
, sortPlayIndex: function (index) {
var that = this
;
// TODO
}
, setRandomState: function (random) {
@ -172,10 +224,13 @@ _
;
if (random === true) {
that._playIndexOrdered = that._playIndex;
that._playIndex.shuffle();
}
// TODO: Set cursor back to the item that was playing
} else {
that._playIndex = that._playIndexOrdered;
}
return that._stateRandom = random;
}
@ -188,51 +243,123 @@ _
}
, playItem: function (item) {
var that = this
;
return that._playerPlay(item);
}
, playAtIndex: function (index) {
var that = this
;
that._playCursor = index;
that.playItem(that._playIndex[that._playCursor]);
}
/**
* EVENTS
**/
, __buttonPlayPause: function (event) {
var that = this
, $target = $(event.target)
;
switch (that.webAudio._state) {
case that.webAudio._states.stopped:
that._playNext();
break;
case that.webAudio._states.playing:
that._playerPause();
break;
case that.webAudio._states.paused:
that._playerUnpause();
break;
default:
break;
}
}
, __buttonNext: function (event) {
var that = this
;
that._playNext();
}
, __buttonPrevious: function (event) {
var that = this
;
that._playPrevious();
}
, __buttonVolumeUp: function (event) {
var that = this
, volume = that._getVolume()
;
if (volume < 1) {
if ((volume+0.1) > 1) {
volume = 1;
} else {
volume+= 0.1;
}
}
that._setVolume(volume);
}
, __buttonVolumeDown: function (event) {
var that = this
, volume = that._getVolume()
;
if (volume > 0) {
if ((volume-0.1) < 0) {
volume = 0;
} else{
volume-= 0.1;
}
}
that._setVolume(volume);
}
, __buttonVolumeClick: function (event) {
var that = this
, clientX = event.clientX
, left = event.target.offsetLeft
, clickoffset = clientX - left
, fraction = clickoffset/event.target.offsetWidth
;
that._setVolume(fraction);
}
, __buttonSeek: function (event) {
var that = this
;
if (_.isUndefined(that.debouncers["__buttonSeek"])) {
var clientX = event.clientX
, left = event.target.offsetLeft
, clickoffset = clientX - left
, percent = clickoffset/event.target.offsetWidth
, seekTime = percent * that.webAudio.obj.duration
;
that._seek(seekTime);
that.debouncers["__buttonSeek"] = setTimeout(function __fnPlayerViewButtonSeekDebounce () {
clearTimeout(that.debouncers["__buttonSeek"]);
delete that.debouncers["__buttonSeek"];
}, 800);
}
}
/**
@ -243,24 +370,84 @@ _
var that = this
;
return that.webAudio = new WebAudio();
that.webAudio = new WebAudio();
that._waBindEvents();
return that.webAudio;
}
, _waBindEvents: function () {
var that = this
;
that.webAudio.on("state", function __fnPlayerEventWebAudioState (state) {
that.__waStateChanged.apply(that, arguments);
});
that.webAudio.on("ended", function __fnPlayerEventWebAudioState (state) {
that.__waEnded.apply(that, arguments);
});
that.webAudio.on("timeupdate", function __fnPlayerEventWebAudioState () {
that.__waTimeUpdate.apply(that, arguments);
});
}
, __waStateChanged: function () {
, __waStateChanged: function (state) {
var that = this
;
that._playBtnSetState(state);
switch (state) {
case that.webAudio._states.stopped:
console.debug("Player State Stopped");
//that._setViewport();
that._enableControls();
break;
case that.webAudio._states.error:
console.debug("Player State error");
that._disableControls();
break;
case that.webAudio._states.loading:
console.debug("Player State loading");
that._progressSetLoadding();
that._disableControls();
break;
case that.webAudio._states.playing:
console.debug("Player State playing");
that._enableControls();
break;
case that.webAudio._states.paused:
console.debug("Player State paused");
that._enableControls();
break;
}
}
, __waEnded: function () {
var that = this
;
that._playNext();
}
, __waTimeUpdate: function (event) {
var that = this
;
that._updateViewportProgress(event.target.currentTime, event.target.duration);
}
// Player Controls
, _playerEnded: function () {
, _playerPlay: function (item) {
var that = this
;
that.webAudio.loadMedia(that._getItemMediaUrl(item), MIMES.get(item.type), function __fnPlayerViewCbLoaded () {
that._setViewport(item);
});
}
, _playerLoading: function () {
@ -273,24 +460,75 @@ _
var that = this
;
switch (that._stateRepeat) {
case that._statesRepeat.all:
case that._statesRepeat.none:
if (that._stateRepeat === that._statesRepeat.all
&& that._playIndex.length === (that._playCursor + 1)) {
that._playCursor = -1;
}
if (that._playIndex.length > (that._playCursor + 1)) {
that._playerPlay(that._playIndex[++that._playCursor]);
} else {
that._playerStop();
}
break;
case that._statesRepeat.one:
that._playerPlay(that._playIndex[that._playCursor]);
break;
}
}
, _playPrevious: function () {
var that = this
;
switch (that._stateRepeat) {
case that._statesRepeat.all:
case that._statesRepeat.none:
if (that._stateRepeat === that._statesRepeat.all
&& that._playCursor === 0) {
that._playCursor = that._playIndex.length;
}
if (that._playCursor > 0) {
that._playerPlay(that._playIndex[--that._playCursor]);
} else {
that._playerStop();
}
break;
case that._statesRepeat.one:
that._playerPlay(that._playIndex[that._playCursor]);
break;
}
}
, _playerPause: function () {
var that = this
;
that.webAudio.obj.pause();
}
, _playerUnpause: function () {
var that = this
;
that.webAudio.obj.play();
}
, _playerStop: function () {
var that = this
;
that.webAudio.obj.pause();
that.webAudio.obj.src = "";
that.webAudio.obj.innetHTML = "";
that._playCursor = 0;
that._setViewport();
}
, _playerStart: function () {
@ -299,35 +537,136 @@ _
}
, _getVolume: function () {
var that = this
;
return that.webAudio.obj.volume;
}
, _setVolume: function (volume) {
var that = this
;
that.$elVolumeInput.val(volume);
return that.webAudio.obj.volume = volume;
}
, _seek: function (seek) {
var that = this
;
if (that.webAudio._state === that.webAudio._states.playing) {
console.debug("Seeking player to " + seek);
that.webAudio.obj.currentTime = seek;
}
}
// Viewport methods
, _getItemData: function (item) {
, _playBtnSetState: function (state) {
var that = this
, $btn = that.$el.find("a.buttonPlay");
$btn.removeClass("paused");
$btn.removeClass("playing");
$btn.removeClass("stopped");
switch (state) {
case that.webAudio._states.stopped:
case that.webAudio._states.paused:
$btn.addClass("paused");
break;
case that.webAudio._states.loading:
case that.webAudio._states.ready:
case that.webAudio._states.playing:
$btn.addClass("playing");
break;
case -1:
$btn.addClass("stopped");
break;
}
}
, _disableControls: function () {
var that = this
;
that.$el.find(".enabled").addClass("disabled");
that.$el.find(".enabled").removeClass("enabled");
that.$el.find("[enabled]").attr("disabled", true);
that.$el.find("[enabled]").removeAttr("enabled");
//that.$el.find("progress").attr("disabled", true);
}
, _enableControls: function () {
var that = this
;
that.$el.find(".disabled").addClass("enabled");
that.$el.find(".disabled").removeClass("disabled");
that.$el.find("[disabled]").attr("enabled", true);
that.$el.find("[disabled]").removeAttr("disabled");
//that.$el.find("progress").removeAttr("disabled");
}
/*, _getItemData: function (item) {
var that = this
;
console.log(that.options.servers.get(item.hostname).client.collections);
return that.options.servers.get(item.hostname).client.collections.databases[item.id].get("dmap_listing").get(item.dbId);
}
*/
, _getItemMediaUrl: function (item) {
var that = this
;
return that.options.servers.get(item.hostname).client.urlMedia(item.id, item.type, item.dbId);
}
, _setViewport: function (item) {
var that = this
;
item = item || {};
that.$elViewport.html(_.template(tmplPlayerStatus)(item));
}
, _progressSetLoadding: function () {
var that = this
, $progress = that.$el.find(".playerProgressWrapper > progress")
;
$progress.removeAttr("value");
$progress.attr("disabled", true);
}
, _updateViewportProgress: function (progress, time) {
var that = this
;
progress = progress || 0;
time = time || 1;
if (that.$el.find("> .playerProgressWrapper")) {
var left = (time - progress)
, frac = progress / time
, precent = frac * 100
, elapsed = Math.floor(progress / 60).toFixed().pad(2, "0") + ":" + (progress % 60).toFixed().pad(2, "0")
, remain = "-" + Math.floor(left / 60).toFixed().pad(2, "0") + ":" + (left % 60).toFixed().pad(2, "0")
, $progress = that.$el.find(".playerProgressWrapper > progress")
;
that.$el.find(".playerProgressWrapper > span:first-child").text(elapsed);
that.$el.find(".playerProgressWrapper > span:last-child").text(remain);
$progress.removeAttr("disabled");
$progress.val(frac);
}
}
});

@ -0,0 +1,18 @@
define(["underscore","jquery","backbone","modules/webaudio","libs/mimes","text!../../templates/player/layout.html","text!../../templates/player/player-status.html"],function(e,g,h,d,a,f,b){if(!e.isFunction(Array.prototype.shuffle)){Array.prototype.shuffle=function(){var j=this.length,l=j;
if(j===0){return false;}while(l--){var m=parseInt(Math.random()*j,10);var k=this[l];this[l]=this[m];this[m]=k;}};}var c=h.View.extend({elViewport:null,$elViewport:null,$elVolumeInput:null,playIndex:[],playCursor:0,webAudio:null,_stateRandom:null,_stateRepeat:null,_stateMute:null,_stateVolume:null,_stateAudio:null,_state:null,_states:{stopped:0,loading:1,playing:2,paused:3},events:{"click div:first-child > a.buttonPrev":"__buttonPrevious","click div:first-child > a.buttonNext":"__buttonNext","click div:first-child > a.buttonPlay":"__buttonPlayPause","click div:first-child > .playerVolumeWrapper > a:first-child":"__buttonVolumeDown","click div:first-child > .playerVolumeWrapper > a:last-child":"__buttonVolumeUp","click div:first-child > .playerVolumeWrapper > input":"__buttonVolumeClick","click div:last-child > .playerProgressWrapper > progress":"__buttonSeek"},initialize:function(i){var j=this;
e.bindAll(this,"init","setPlayIndex","sortPlayIndex","setRandomState","setRepeatState","playItem","__buttonPlayPause","__buttonNext","__buttonPrevious","__buttonVolumeUp","__buttonVolumeDown","__buttonVolumeClick","__buttonSeek","_waCreate","_waBindEvents","__waStateChanged","_playerEnded","_playerLoading","_playNext","_playPrevious","_playerPause","_playerStop","_playerStart","_setVolume","_getItemData","_getItemMediaUrl","_setViewport","_updateViewportProgress");
c.__super__.initialize.apply(j);j.$el.html(f);j.elViewport=document.createElement("div");j.$elViewport=g(j.elViewport);j.$elViewport.html(e.template(b)({}));
j.$elVolumeInput=j.$el.find(".playerVolumeWrapper > input");j.$el.append(j.elViewport);j._waCreate();return j;},init:function(){var i=this;i.$el.find(".disabled").removeClass("disabled");
i.$el.find("[disabled]").removeAttr("disabled");i.$elVolumeInput.val(i.webAudio.obj.volume);},setPlayIndex:function(i,k){var j=this;j._playIndex=i;j._playCursor=k||0;
if(j._stateRandom){j.setRandomState(j._stateRandom);}return j._playIndex;},sortPlayIndex:function(i){var j=this;},setRandomState:function(j){var i=this;
if(j===true){i._playIndex.shuffle();}return i._stateRandom=j;},setRepeatState:function(j){var i=this;return i._stateRepeat=j;},playItem:function(j){var i=this;
i.webAudio.loadMedia(i._getItemMediaUrl(j),a.get(j.type));},__buttonPlayPause:function(j){var i=this;},__buttonNext:function(j){var i=this;},__buttonPrevious:function(j){var i=this;
},__buttonVolumeUp:function(k){var j=this,i=j._getVolume();if(i<1){if((i+0.1)>1){i=1;}else{i+=0.1;}}j._setVolume(i);},__buttonVolumeDown:function(k){var j=this,i=j._getVolume();
if(i>0){if((i-0.1)<0){i=0;}else{i-=0.1;}}j._setVolume(i);},__buttonVolumeClick:function(m){var l=this,k=m.clientX,n=m.target.offsetLeft,i=k-n,j=i/m.target.offsetWidth;
l._setVolume(j);},__buttonSeek:function(n){var m=this,l=m._getItem(),k=n.clientX,o=n.target.offsetLeft,i=k-o,j=i/n.target.offsetWidth,p=(j*(l.daap_songtime/1000));
m._seek(p);},_waCreate:function(){var i=this;i.webAudio=new d();i._waBindEvents();return i.webAudio;},_waBindEvents:function(){},__waStateChanged:function(){var i=this;
},_playerEnded:function(){var i=this;},_playerLoading:function(){var i=this;},_playNext:function(){var i=this;},_playPrevious:function(){var i=this;},_playerPause:function(){var i=this;
},_playerStop:function(){var i=this;},_playerStart:function(){var i=this;},_getVolume:function(){var i=this;return i.webAudio.obj.volume;},_setVolume:function(j){var i=this;
i.$elVolumeInput.val(j);return i.webAudio.obj.volume=j;},_seek:function(i){var j=this;console.debug("Seeking player to "+i);j.webAudio.obj.pause();j.webAudio.obj.currentTime=i;
j.webAudio.obj.play();},_getItemData:function(j){var i=this;},_getItemMediaUrl:function(j){var i=this;return i.options.servers.get(j.hostname).client.urlMedia(j.id,j.type,j.dbId);
},_setViewport:function(j){var i=this;},_updateViewportProgress:function(i,k){var j=this;}});return c;});

@ -5,7 +5,10 @@
<h3 id="myModalLabel">A fatal error has occured</h3>
</div>
<div class="modal-body" style="font-size: 1.2em">
You can try to reload the page...
<!--
{{ERROR_REPORTING}}
-->
</div>
<div class="modal-footer">
<button class="btn btn-mini btn-primary" data-dismiss="modal" aria-hidden="true"><i class="icon-refresh"></i>&nbsp;Reload</button>

@ -1,4 +1,4 @@
<% if (typeof dmap_itemnname !== "undefined") { %>
<% if (typeof dmap_itemname !== "undefined") { %>
<div class="daaprPlayerTitleIndicator">{{dmap_itemname}}</div>
<div class="daaprPlayerInfoIndicator">{{daap_songartist}}</div>
<div class="playerProgressWrapper">

Loading…
Cancel
Save