const globalTasks = {}; const mediaInfoCenter = {}; function createEmptyTaskView(taskId) { const li = document.createElement('li'); li.classList.add("list-group-item"); li.classList.add("task"); li.dataset.taskId = taskId; let html = ` <div class="file"> <div class="circle-progress-bar" data-value="0" data-bar-color="#666666" data-bar-stroke="4" data-bar-size="30"></div> <a href="" class="link-primary"></a> <span class="progress-percent" style="opacity: .7">- 99%</span> </div> <div class="control"> <button class="btn btn-danger cancel" data-task-id="${ taskId }"><i class="bi bi-stop-fill"></i> Stop</button> <div class="spinner-border text-secondary" role="status" style="display: none"> <span class="visually-hidden">Loading...</span> </div> </div> `; li.innerHTML = html; initSingleCircleProgressBar(li.querySelector(".circle-progress-bar")); return initTaskView(li); } function getTotalActiveTasks() { return Object.keys(globalTasks).length; } function initTaskView(view) { view.querySelector(".control .cancel").addEventListener("click", e => { const taskId = e.currentTarget.dataset.taskId; $(e.currentTarget).hide(); $(e.currentTarget).parent().find(".spinner-border").show(); $.getJSON(`/stop-transcoding?task_id=${taskId}`, function(resp) { if(resp.status == "stoped" && resp.task_id == taskId) { if(typeof globalTasks[resp.task_id] != "undefined") { // delete globalTasks[resp.task_id]; } } else { pushErrMsg("Failed to complete request to stop transcoding"); } }); }); return view; } function updateExistsView(data, view) { const taskContainer = $(view); const href = `/single?path=${ data.task.file }`; const fileLink = taskContainer.find(".file a"); if(fileLink.attr("href") != href) { fileLink.text(data.task.file.split("/").at(-1)); fileLink.attr("href", href); } let time = getTimeFromTranscodingProgressMessage(data.message); const mInf = getMediaInfo(data.task.file); if(!mInf) { return; } const progressPercent = calcTranscodingProgress(time, mInf.info.container.duration); const cpbar = taskContainer.find(".file .circle-progress-bar")[0]; if(cpbar.dataset.value != progressPercent) { taskContainer.find(".file .progress-percent").text(`- ${ progressPercent }%`); cpbar.dataset.value = progressPercent; } } function globalTranscodingTasksInit() { const tasksContainer = $(".transcoding-tasks-container > ul"); socket.on("progress", data => { if(typeof data.task.id == "undefined") { return; } if(typeof globalTasks[data.task.id] == "undefined") { // create new view const view = createEmptyTaskView(data.task.id); tasksContainer.append(view); globalTasks[data.task.id] = { "data": data, "view": view } } // update exists view updateExistsView(data, globalTasks[data.task.id].view); $(".total-tasks").text(getTotalActiveTasks()); }); socket.on("completed", data => { if(typeof globalTasks[data.task.id] != "undefined") { // remove task view $(globalTasks[data.task.id].view).remove(); delete globalTasks[data.task.id]; $(".total-tasks").text(getTotalActiveTasks()); } }); socket.on("canceled", data => { if(typeof globalTasks[data.task.id] != "undefined") { // remove task view $(globalTasks[data.task.id].view).remove(); delete globalTasks[data.task.id]; $(".total-tasks").text(getTotalActiveTasks()); } }); socket.on("error", data => { const cmd = data.task.command.join(" "); pushErrMsg(`${ data.message }<hr>${ cmd }`); }); } function getMediaInfo(path) { if(typeof mediaInfoCenter[path] == "undefined") { getSingleMediaFileInfo(path, resp => { console.log(resp); mediaInfoCenter[resp.path] = resp; }); return false; } return mediaInfoCenter[path]; } $(document).ready(function() { if(typeof mediaInfo != "undefined") { mediaInfoCenter[mediaInfo.path] = mediaInfo; } globalTranscodingTasksInit(); });