mjugrep/static/main.js

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);
});
});