Noark5 Metadata Editor for lydfiler i FLAC-format
Dette programmet ble til etter en diskusjon med Petter Reinholdtsen om FLAC-lagring og er en nettbasert editor for å håndtere metadata i henhold til Noark5-standarden for digitale arkivsystemer. Det er spesialutviklet for lydarkivmateriale i FLAC-format, og sikrer at metadata struktureres og lagres på en måte som oppfyller kravene til langtidsbevaring og dokumentasjonsforvaltning. Hovedfunksjoner:
🔹 Metadataregistrering: Brukeren kan redigere og lagre Noark5-kompatibel metadata, inkludert tittel, skaper, opprettelsesdato, emne, stikkord og proveniens. 🔹 Lagring i IndexedDB: Metadata og lydfiler lagres lokalt i IndexedDB, som gir en robust database for nettapplikasjoner uten ekstern server. 🔹 Automatisk lagring i LocalStorage: Metadatafeltene lagres midlertidig i LocalStorage, slik at brukeren ikke mister endringer ved en feilaktig oppdatering av siden. 🔹 Avspilling av lydfiler: Opplastede FLAC-filer kan forhåndslyttes direkte i nettleseren. 🔹 Filhåndtering: Programmet viser en liste over lagrede lydfiler med tilhørende metadata og gir mulighet for redigering.
Hvorfor Noark5? Programmet følger prinsippene i Noark5 for digital arkivering, slik at lydfiler og tilhørende metadata kan eksporteres eller integreres i et større arkivsystem. Bruken av FLAC sikrer tapsfri lydkvalitet, noe som er viktig for bevaring av autentiske lydopptak.
Løsningen er tiltenkt arkiver, forskningsinstitusjoner og offentlig forvaltning som ønsker en moderne, webbasert måte å håndtere og strukturere lydarkiver på i tråd med norske standarder.
https://www.oleaamot.com/research/noark5lyd.html
<!DOCTYPE html> <html lang="no"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Noark5 Metadata Editor</title> <script src="<https://code.jquery.com/jquery-3.6.0.min.js>"></script> <style> body { font-family: Arial, sans-serif; margin: 20px; } input, textarea { width: 100%; padding: 8px; margin: 5px 0; } button { padding: 10px; margin: 10px; cursor: pointer; } </style> </head> <body> <h1>Noark5 Metadata Editor</h1>
<h3>Last opp lydfil:</h3> <input type="file" id="fileInput" accept=".flac" />
<h3>Rediger Metadata:</h3> <label for="metadataTitle">Tittel:</label> <input type="text" id="metadataTitle" placeholder="Tittel på lydfil" />
<label for="metadataCreator">Skaper:</label> <input type="text" id="metadataCreator" placeholder="Skaper av lydfilen" />
<label for="metadataDate">Dato for opprettelse:</label> <input type="datetime-local" id="metadataDate" />
<label for="metadataSubject">Emne:</label> <input type="text" id="metadataSubject" placeholder="Emne for lydfilen" />
<label for="metadataKeywords">Stikkord:</label> <input type="text" id="metadataKeywords" placeholder="Stikkord, adskilt med komma" />
<label for="metadataProvenance">Proveniens:</label> <textarea id="metadataProvenance" placeholder="Opprinnelse til filen"></textarea>
<button id="saveMetadataButton" disabled>Lagre Metadata</button> <button id="clearMetadataButton">Tøm Metadata</button>
<h3>Lagrede filer:</h3> <div id="fileList"></div>
<script> const dbName = "audioArchiveDB"; let db;
// Åpne IndexedDB function openDB() { let request = indexedDB.open(dbName, 1); request.onsuccess = (e) => { db = e.target.result; loadFilesFromDB(); }; request.onerror = (e) => { console.error("Database error:", e.target.error); }; request.onupgradeneeded = (e) => { db = e.target.result; let store = db.createObjectStore("files", { keyPath: "id", autoIncrement: true }); store.createIndex("fileName", "fileName", { unique: false }); }; }
// Lagrer metadata i IndexedDB function storeFileInDB(file, metadata) { let transaction = db.transaction(["files"], "readwrite"); let store = transaction.objectStore("files"); store.add({ fileName: file.name, fileData: file, metadata: metadata }); loadFilesFromDB(); }
// Henter filer fra IndexedDB function loadFilesFromDB() { $("#fileList").empty(); let transaction = db.transaction(["files"], "readonly"); let store = transaction.objectStore("files"); let request = store.getAll();
request.onsuccess = (e) => { let files = e.target.result; if (files.length > 0) { files.forEach((file, index) => { let fileElement = $(` <div> <strong>Fil ${index + 1}:</strong> ${file.metadata.title} <br> <strong>Skaper:</strong> ${file.metadata.creator} <br> <strong>Dato:</strong> ${file.metadata.creationDate} <br> <audio controls> <source src="${URL.createObjectURL(file.fileData)}" type="audio/flac"> Nettleseren din støtter ikke FLAC. </audio> <button onclick="editMetadata(${file.id})">Rediger</button> </div> <hr> `); $("#fileList").append(fileElement); }); } else { $("#fileList").html("Ingen lydfiler lagret."); } }; }
// Fyll ut metadata-redigereren function editMetadata(fileId) { let transaction = db.transaction(["files"], "readonly"); let store = transaction.objectStore("files"); let request = store.get(fileId);
request.onsuccess = (e) => { let file = e.target.result; $("#metadataTitle").val(file.metadata.title); $("#metadataCreator").val(file.metadata.creator); $("#metadataDate").val(file.metadata.creationDate); $("#metadataSubject").val(file.metadata.subject); $("#metadataKeywords").val(file.metadata.keywords.join(", ")); $("#metadataProvenance").val(file.metadata.provenance);
$("#saveMetadataButton").prop("disabled", false).off("click").on("click", () => saveMetadata(fileId)); }; }
// Lagre metadata i IndexedDB function saveMetadata(fileId) { let transaction = db.transaction(["files"], "readwrite"); let store = transaction.objectStore("files"); let request = store.get(fileId);
request.onsuccess = (e) => { let file = e.target.result; file.metadata = { title: $("#metadataTitle").val(), creator: $("#metadataCreator").val(), creationDate: $("#metadataDate").val(), subject: $("#metadataSubject").val(), keywords: $("#metadataKeywords").val().split(",").map(keyword => keyword.trim()), provenance: $("#metadataProvenance").val() };
store.put(file); alert("Metadata lagret!"); loadFilesFromDB(); }; }
// Håndter filopplastning $("#fileInput").on("change", function(event) { let file = event.target.files[0]; if (file && file.type === "audio/flac") { let metadata = { title: file.name, creator: "Ukjent", creationDate: new Date().toISOString(), subject: "Lydarkiv", keywords: ["audio", "archive"], provenance: "Opplastet av bruker" }; storeFileInDB(file, metadata); } else { alert("Kun .flac-filer er tillatt."); } });
// Lagrer metadata til LocalStorage $("input, textarea").on("input", function() { localStorage.setItem($(this).attr("id"), $(this).val()); });
// Gjenoppretter metadata fra LocalStorage $(document).ready(() => { $("input, textarea").each(function() { let savedValue = localStorage.getItem($(this).attr("id")); if (savedValue) $(this).val(savedValue); });
openDB(); });
// Nullstill metadata $("#clearMetadataButton").on("click", function() { $("input, textarea").val(""); localStorage.clear(); }); </script> </body> </html>
Mvh, Ole Aamot