230 lines
6.9 KiB
JavaScript
230 lines
6.9 KiB
JavaScript
|
|
// Probe for supported codecs
|
|
AUDIO_CODECS = [
|
|
'audio/ogg',
|
|
'audio/mpeg',
|
|
'audio/flac',
|
|
];
|
|
|
|
timeout = null;
|
|
es = null;
|
|
prev = null;
|
|
|
|
function humanize_duration(d) {
|
|
var seconds = Math.floor(d % 60);
|
|
var minutes = Math.floor(d / 60) % 60;
|
|
var hours = Math.floor(d / 3600);
|
|
if (seconds < 10) seconds = '0' + seconds;
|
|
if (minutes < 10) minutes = '0' + minutes;
|
|
if (hours < 10) hours = '0' + hours;
|
|
return hours + ":" + minutes + ":" + seconds;
|
|
}
|
|
|
|
function onDelayedSearch() {
|
|
var expr = $("#search").val();
|
|
if (expr == window.expr) return;
|
|
console.info("Searching", expr);
|
|
results.rows().clear().draw(false);
|
|
if (es) {
|
|
es.close();
|
|
$("#results tbody").empty();
|
|
}
|
|
|
|
es = new EventSource("/api/search/?expr=" + expr);
|
|
|
|
// Close socket event listener
|
|
es.addEventListener("close", function(e) {
|
|
console.info("Closing search socket");
|
|
});
|
|
|
|
// Open socket event listener
|
|
es.addEventListener("open", function(e) {
|
|
console.info("Opened event stream for search expression", expr);
|
|
})
|
|
|
|
// Search end result marker
|
|
es.addEventListener("done", function(e) {
|
|
var totals = JSON.parse(e.data)
|
|
console.info("Finished searching, total", totals.relevant_files, "relevant files and", totals.hits, "hits");
|
|
es.close();
|
|
})
|
|
|
|
// Keep track of relative path of the XSPF blobs
|
|
es.addEventListener("chdir", function(e) {
|
|
console.info("Moving to directory:", e.data);
|
|
window.relpath = e.data;
|
|
|
|
})
|
|
|
|
// If XSPF blob is received append it to search results
|
|
es.addEventListener("xspf", function(e) {
|
|
var $trackMetadatas = $("playlist trackList track", $.parseXML(e.data));
|
|
$trackMetadatas.each(function(index, element) {
|
|
|
|
var location = element.getElementsByTagName("location")[0];
|
|
var filename = location.innerHTML;
|
|
|
|
// Decode escaped XML
|
|
var filename = decodeURIComponent(location.innerHTML);
|
|
if (filename.indexOf("/") >= 0) {
|
|
filename = filename.substring(filename.lastIndexOf("/") + 1);
|
|
}
|
|
|
|
// Escape quotes for jQuery
|
|
filename = filename.replace("\"", "\\\"");
|
|
results.row.add([
|
|
window.relpath + "/" + filename,
|
|
$("creator", element).html() || "-",
|
|
$("album", element).html() || "-",
|
|
$("trackNum", element).html() || "-",
|
|
$("title", element).html() || "-",
|
|
humanize_duration(parseInt($("duration", element).html())/1000),
|
|
$("meta[rel='mimetype']", element).html(),
|
|
Math.floor(parseInt($("meta[rel='bitrate']", element).html())/1000)+"kbps",
|
|
// $("meta[rel='bit_depth']", element).html() + "bit @ " + $("meta[rel='sample_rate']", element).html(),
|
|
"bla"
|
|
]).on('click', 'tr', function () {
|
|
$(this).toggleClass('selected');
|
|
});
|
|
clearTimeout(window.timeoutDraw);
|
|
window.timeoutDraw = setTimeout(results.draw, 100);
|
|
});
|
|
});
|
|
}
|
|
|
|
function playNextAudioTrack() {
|
|
queue.row(queue.row({selected:true}).index()+1).select();
|
|
}
|
|
|
|
|
|
function playPrevAudioTrack() {
|
|
queue.row(queue.row({selected:true}).index()-1).select();
|
|
}
|
|
|
|
|
|
function playTrack(url, mimetype) {
|
|
var url = "/api/stream/" + url;
|
|
console.info("Playing:", url, mimetype);
|
|
|
|
$("#seek").val(0);
|
|
$("#offset").html("00:00:00");
|
|
$("#player").unbind("ended").bind("ended", function () {
|
|
playNextAudioTrack();
|
|
});
|
|
$("#player").empty();
|
|
|
|
if (window.AUDIO_CODECS_SUPPORTED.indexOf(mimetype) >= 0) {
|
|
$("#player").append("<source src=\"" + url + "\" type=\"" + mimetype + "\"/>");
|
|
} else {
|
|
console.info("Codec", mimetype, "not supported by browser");
|
|
}
|
|
|
|
for (var j = 0; j < window.AUDIO_CODECS_SUPPORTED.length; j++) {
|
|
var alternative = window.AUDIO_CODECS_SUPPORTED[j];
|
|
if (mimetype != alternative) {
|
|
$("#player").append("<source src=\"/transcode/?mimetype=" + alternative + "&url=" + url.replace("&", "%26") + "\" type=\"" + alternative + "\"/>");
|
|
}
|
|
}
|
|
$("#player").trigger("load");
|
|
$("#player").trigger("play");
|
|
}
|
|
|
|
$(document).ready(function() {
|
|
$('#results tbody').on('dblclick', 'tr', function () {
|
|
console.info("Got double click");
|
|
queue.rows.add(results.rows({ selected: true }).data());
|
|
queue.rows.add([results.row(this).data()]);
|
|
results.rows().deselect();
|
|
results.draw(false);
|
|
queue.draw(false);
|
|
});
|
|
|
|
$("#playback-next").on("click", function() {
|
|
playNextAudioTrack();
|
|
});
|
|
$("#playback-prev").on("click", function() {
|
|
playPrevAudioTrack();
|
|
});
|
|
$("#queue-selection").on("click", function() {
|
|
queue.rows.add(results.rows({ selected: true }).data()).draw(false);
|
|
});
|
|
$("#queue-all").on("click", function() {
|
|
queue.rows.add(results.data()).draw(false);
|
|
});
|
|
$("#queue thead").html($("#results thead").html());
|
|
$("#queue-clear").on("click", function() {
|
|
queue.rows().clear().draw(false);
|
|
});
|
|
|
|
window.results = $('#results').DataTable({
|
|
autoWidth: false,
|
|
columns: [
|
|
null,
|
|
{width:"20%"},
|
|
{width:"20%"},
|
|
{width:"1em"},
|
|
{width:"20%"},
|
|
],
|
|
|
|
paging: true,
|
|
ordering: false,
|
|
searching: false,
|
|
select: {
|
|
style: 'multi'
|
|
},
|
|
columnDefs: [
|
|
{
|
|
"targets": [ 0, 6, 7, 8 ],
|
|
"visible": false,
|
|
"searchable": false
|
|
},
|
|
]
|
|
});
|
|
window.queue = $('#queue').DataTable({
|
|
autoWidth: false,
|
|
columns: [
|
|
null,
|
|
{width:"20%"},
|
|
{width:"20%"},
|
|
{width:"1em"},
|
|
{width:"20%"},
|
|
],
|
|
paging: true,
|
|
ordering: false,
|
|
searching: false,
|
|
select: {
|
|
style: 'single'
|
|
},
|
|
columnDefs: [
|
|
{
|
|
"targets": [ 0, 6, 7, 8 ],
|
|
"visible": false,
|
|
"searchable": false
|
|
},
|
|
],
|
|
}).on("select", function(e, dt, type, indexes) {
|
|
var item = queue.row(indexes).data();
|
|
playTrack(item[0], item[6]);
|
|
});
|
|
|
|
window.AUDIO_CODECS_SUPPORTED = [];
|
|
|
|
var audioPlayer = document.getElementById("player");
|
|
for (var j = 0; j < window.AUDIO_CODECS.length; j++) {
|
|
if (audioPlayer.canPlayType(window.AUDIO_CODECS[j])) {
|
|
window.AUDIO_CODECS_SUPPORTED.push(AUDIO_CODECS[j]);
|
|
}
|
|
}
|
|
|
|
console.info("This browser supports following audio codecs:", window.AUDIO_CODECS_SUPPORTED);
|
|
$("#search").keyup(function() {
|
|
if (prev == $("#search").val())
|
|
return;
|
|
prev = $("#search").val();
|
|
clearTimeout(window.timeout);
|
|
window.timeout = setTimeout(function() {
|
|
onDelayedSearch();
|
|
}, 200);
|
|
});
|
|
});
|