commit 0abcd235c987a3b42fa0e311b749b531486832a6 Author: Tomáš Mládek Date: Thu Feb 20 19:35:08 2020 +0100 initial commit, first workable version diff --git a/index.html b/index.html new file mode 100644 index 0000000..b59e9bf --- /dev/null +++ b/index.html @@ -0,0 +1,26 @@ + + + + + Zoom Marks Analyzer + + + +
+
Click or drop file here
+
+
+
MARKS
+
    +
    + +
    + + + + + diff --git a/main.css b/main.css new file mode 100644 index 0000000..e5c07ea --- /dev/null +++ b/main.css @@ -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; +} diff --git a/main.js b/main.js new file mode 100644 index 0000000..95d040a --- /dev/null +++ b/main.js @@ -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);