initial commit, first workable version

master
Tomáš Mládek 2020-02-20 19:35:08 +01:00
commit 0abcd235c9
3 changed files with 173 additions and 0 deletions

26
index.html Normal file
View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Zoom Marks Analyzer</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div id="app">
<div id="dropmark">Click or drop file here</div>
<div id="label"></div>
<div id="cuelist-outer">
<div>MARKS</div>
<ol id="cuelist"></ol>
</div>
<button id="export-button" disabled>Export as TSV...
<span class="subtitle">(For Adobe Audition)</span>
</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/wavefile@11.0.0/dist/wavefile.min.js"
integrity="sha384-W3PirarYaOAUEL6KdD+DTxgNwNV2WjP01eFWsWWBBzy4goLvqOd//bovJESrq043"
crossorigin="anonymous"></script>
<script src="main.js"></script>
</body>
</html>

61
main.css Normal file
View File

@ -0,0 +1,61 @@
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
font-family: monospace;
font-size: 12pt;
}
#app {
display: flex;
flex-direction: column;
align-items: center;
padding: 2em;
}
#dropmark {
font-size: 16pt;
border: 4px dashed gray;
padding: 2em 3em;
background: #f5f5f5;
cursor: pointer;
}
#label {
margin: 2em 0;
}
#cuelist-outer {
visibility: hidden;
flex-grow: 1;
}
#cuelist-outer div {
font-weight: bold;
text-align: center;
}
#cuelist li {
margin: .5em;
}
#export-button {
font-size: 16pt;
border: 4px solid gray;
padding: 1.5em 3em;
font-family: monospace;
}
#export-button .subtitle {
display: block;
font-size: 12pt;
}

86
main.js Normal file
View File

@ -0,0 +1,86 @@
const dropElement = document.getElementById("dropmark");
const label = document.getElementById("label");
const infoElement = document.getElementById("cuelist-outer");
const cueListElement = document.getElementById("cuelist");
const exportButton = document.getElementById("export-button");
function processFile (file) {
window.currentFile = file;
console.debug(window.currentFile);
file.arrayBuffer().then((arrayBuffer) => {
const buffer = new Uint8Array(arrayBuffer);
window.resultWav = new wavefile.WaveFile(buffer);
console.debug(window.resultWav);
window.cuePoints = window.resultWav.listCuePoints().map((point) => {
return new Date(point.position).toISOString().substr(11, 12);
});
console.debug(window.cuePoints);
displayMarks();
});
}
function displayMarks () {
const length = window.resultWav.data.chunkSize / window.resultWav.fmt.byteRate;
label.innerText = `${window.currentFile.name}: ${length.toFixed(2)}s`;
while (cueListElement.lastElementChild) {
cueListElement.removeChild(cueListElement.lastElementChild);
}
window.cuePoints.forEach((point) => {
const row = document.createElement("li");
row.innerText = point;
cueListElement.appendChild(row);
});
infoElement.style.visibility = "inherit";
exportButton.disabled = false;
}
function exportAsTSV () {
const filename = `${window.currentFile.name.replace(/\.(wav|WAV)$/, "")}_marks.csv`;
let text = "Name\tStart\tDuration\tTime Format\tType\tDescription\n";
window.cuePoints.forEach((point, idx) => {
text += `Mark ${idx}\t${point}\t0:00.000\tdecimal\tCue\n`;
});
console.debug(text);
const aElement = document.createElement("a");
aElement.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(text));
aElement.setAttribute("download", filename);
aElement.click();
}
function handleFileSelect (evt) {
evt.stopPropagation();
evt.preventDefault();
processFile(evt.dataTransfer.files.item(0));
}
function handleDragOver (evt) {
evt.stopPropagation();
evt.preventDefault();
}
function handleClick (evt) {
evt.stopPropagation();
evt.preventDefault();
const fileInput = document.createElement("input");
fileInput.type = "file";
fileInput.accept = ".wav";
fileInput.onchange = () => {
if (fileInput.files !== null) {
processFile(fileInput.files.item(0));
}
};
fileInput.click();
}
dropElement.addEventListener("dragover", handleDragOver, false);
dropElement.addEventListener("drop", handleFileSelect, false);
dropElement.addEventListener("click", handleClick, false);
exportButton.addEventListener("click", exportAsTSV, false);