From 73a5034e02a99b8caaa81a29a1d7dcacd9d8841a Mon Sep 17 00:00:00 2001 From: Jamie Hardt Date: Wed, 23 Nov 2022 18:02:46 -0800 Subject: [PATCH] Documentation --- README.rst | 61 ++ _build/html/_static/previewerEventHandler.js | 590 +++++++++++++++++++ docs/source/index.rst | 3 +- docs/source/quickstart.rst | 3 + metadata.py | 2 +- 5 files changed, 657 insertions(+), 2 deletions(-) create mode 100644 README.rst create mode 100644 _build/html/_static/previewerEventHandler.js create mode 100644 docs/source/quickstart.rst diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..d3c320a --- /dev/null +++ b/README.rst @@ -0,0 +1,61 @@ + +wavinfo +======= + +The `wavinfo` package allows you to probe WAVE and `RF64/WAVE files`_ +and extract extended metadata, with an emphasis on film, video and professional +music production metadata. + +Metadata Standard Support +------------------------- + +`wavinfo` reads: + +* `__Broadcast-WAVE__` metadata, including embedded program + loudness and coding history, and `SMPTE UMID`. +* `__ADM__` track metadata[3][adm], including channel, pack formats, object and content names. +* `__iXML__` production recorder metadata[4][ixml], including project, scene, and take tags, recorder notes + and file family information. +* Most of the common `__RIFF_INFO__` metadata fields. +* The __wav_format__ is also parsed, so you can access the basic sample rate and channel count + information. + +In progress: + +* [Dolby RMU][dolby] metadata and [EBU Tech 3285 Supplement 6][ebu3285s6]. +* iXML `STEINBERG` sound library attributes. +* __NetMix__ library attributes. +* Pro Tools __embedded_regions__. + +How To Use +---------- + +Check out the quick start, but using `wavinfo` is very simple. + +.. code-block:: python + :caption: Reading metadata + from wavinfo import WavInfoReader + + path = '../tests/test_files/A101_1.WAV' + + metadata = WavInfoReader(path) + + +Installation +------------ + +The best way to install `wavinfo` is thew `pypi`: + +.. code-block:: shell + $ pip3 install wavinfo + + + + +.. _ebu3306: https://tech.ebu.ch/docs/tech/tech3306v1_1.pdf +.. _smpte_330m2011: http://standards.smpte.org/content/978-1-61482-678-1/st-330-2011/SEC1.abstract +.. _ebu_bwf: https://tech.ebu.ch/docs/tech/tech3285.pdf +.. _adm: https://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.2076-2-201910-I!!PDF-E.pdf +.. _ixml: http://www.ixml.info +.. _info-tags: https://exiftool.org/TagNames/RIFF.html#Info + diff --git a/_build/html/_static/previewerEventHandler.js b/_build/html/_static/previewerEventHandler.js new file mode 100644 index 0000000..70f2bf0 --- /dev/null +++ b/_build/html/_static/previewerEventHandler.js @@ -0,0 +1,590 @@ +"use strict"; +(() => { + // node_modules/morphdom/dist/morphdom-esm.js + var DOCUMENT_FRAGMENT_NODE = 11; + function morphAttrs(fromNode, toNode) { + var toNodeAttrs = toNode.attributes; + var attr; + var attrName; + var attrNamespaceURI; + var attrValue; + var fromValue; + if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE || fromNode.nodeType === DOCUMENT_FRAGMENT_NODE) { + return; + } + for (var i = toNodeAttrs.length - 1; i >= 0; i--) { + attr = toNodeAttrs[i]; + attrName = attr.name; + attrNamespaceURI = attr.namespaceURI; + attrValue = attr.value; + if (attrNamespaceURI) { + attrName = attr.localName || attrName; + fromValue = fromNode.getAttributeNS(attrNamespaceURI, attrName); + if (fromValue !== attrValue) { + if (attr.prefix === "xmlns") { + attrName = attr.name; + } + fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue); + } + } else { + fromValue = fromNode.getAttribute(attrName); + if (fromValue !== attrValue) { + fromNode.setAttribute(attrName, attrValue); + } + } + } + var fromNodeAttrs = fromNode.attributes; + for (var d = fromNodeAttrs.length - 1; d >= 0; d--) { + attr = fromNodeAttrs[d]; + attrName = attr.name; + attrNamespaceURI = attr.namespaceURI; + if (attrNamespaceURI) { + attrName = attr.localName || attrName; + if (!toNode.hasAttributeNS(attrNamespaceURI, attrName)) { + fromNode.removeAttributeNS(attrNamespaceURI, attrName); + } + } else { + if (!toNode.hasAttribute(attrName)) { + fromNode.removeAttribute(attrName); + } + } + } + } + var range; + var NS_XHTML = "http://www.w3.org/1999/xhtml"; + var doc = typeof document === "undefined" ? void 0 : document; + var HAS_TEMPLATE_SUPPORT = !!doc && "content" in doc.createElement("template"); + var HAS_RANGE_SUPPORT = !!doc && doc.createRange && "createContextualFragment" in doc.createRange(); + function createFragmentFromTemplate(str) { + var template = doc.createElement("template"); + template.innerHTML = str; + return template.content.childNodes[0]; + } + function createFragmentFromRange(str) { + if (!range) { + range = doc.createRange(); + range.selectNode(doc.body); + } + var fragment = range.createContextualFragment(str); + return fragment.childNodes[0]; + } + function createFragmentFromWrap(str) { + var fragment = doc.createElement("body"); + fragment.innerHTML = str; + return fragment.childNodes[0]; + } + function toElement(str) { + str = str.trim(); + if (HAS_TEMPLATE_SUPPORT) { + return createFragmentFromTemplate(str); + } else if (HAS_RANGE_SUPPORT) { + return createFragmentFromRange(str); + } + return createFragmentFromWrap(str); + } + function compareNodeNames(fromEl, toEl) { + var fromNodeName = fromEl.nodeName; + var toNodeName = toEl.nodeName; + var fromCodeStart, toCodeStart; + if (fromNodeName === toNodeName) { + return true; + } + fromCodeStart = fromNodeName.charCodeAt(0); + toCodeStart = toNodeName.charCodeAt(0); + if (fromCodeStart <= 90 && toCodeStart >= 97) { + return fromNodeName === toNodeName.toUpperCase(); + } else if (toCodeStart <= 90 && fromCodeStart >= 97) { + return toNodeName === fromNodeName.toUpperCase(); + } else { + return false; + } + } + function createElementNS(name, namespaceURI) { + return !namespaceURI || namespaceURI === NS_XHTML ? doc.createElement(name) : doc.createElementNS(namespaceURI, name); + } + function moveChildren(fromEl, toEl) { + var curChild = fromEl.firstChild; + while (curChild) { + var nextChild = curChild.nextSibling; + toEl.appendChild(curChild); + curChild = nextChild; + } + return toEl; + } + function syncBooleanAttrProp(fromEl, toEl, name) { + if (fromEl[name] !== toEl[name]) { + fromEl[name] = toEl[name]; + if (fromEl[name]) { + fromEl.setAttribute(name, ""); + } else { + fromEl.removeAttribute(name); + } + } + } + var specialElHandlers = { + OPTION: function(fromEl, toEl) { + var parentNode = fromEl.parentNode; + if (parentNode) { + var parentName = parentNode.nodeName.toUpperCase(); + if (parentName === "OPTGROUP") { + parentNode = parentNode.parentNode; + parentName = parentNode && parentNode.nodeName.toUpperCase(); + } + if (parentName === "SELECT" && !parentNode.hasAttribute("multiple")) { + if (fromEl.hasAttribute("selected") && !toEl.selected) { + fromEl.setAttribute("selected", "selected"); + fromEl.removeAttribute("selected"); + } + parentNode.selectedIndex = -1; + } + } + syncBooleanAttrProp(fromEl, toEl, "selected"); + }, + INPUT: function(fromEl, toEl) { + syncBooleanAttrProp(fromEl, toEl, "checked"); + syncBooleanAttrProp(fromEl, toEl, "disabled"); + if (fromEl.value !== toEl.value) { + fromEl.value = toEl.value; + } + if (!toEl.hasAttribute("value")) { + fromEl.removeAttribute("value"); + } + }, + TEXTAREA: function(fromEl, toEl) { + var newValue = toEl.value; + if (fromEl.value !== newValue) { + fromEl.value = newValue; + } + var firstChild = fromEl.firstChild; + if (firstChild) { + var oldValue = firstChild.nodeValue; + if (oldValue == newValue || !newValue && oldValue == fromEl.placeholder) { + return; + } + firstChild.nodeValue = newValue; + } + }, + SELECT: function(fromEl, toEl) { + if (!toEl.hasAttribute("multiple")) { + var selectedIndex = -1; + var i = 0; + var curChild = fromEl.firstChild; + var optgroup; + var nodeName; + while (curChild) { + nodeName = curChild.nodeName && curChild.nodeName.toUpperCase(); + if (nodeName === "OPTGROUP") { + optgroup = curChild; + curChild = optgroup.firstChild; + } else { + if (nodeName === "OPTION") { + if (curChild.hasAttribute("selected")) { + selectedIndex = i; + break; + } + i++; + } + curChild = curChild.nextSibling; + if (!curChild && optgroup) { + curChild = optgroup.nextSibling; + optgroup = null; + } + } + } + fromEl.selectedIndex = selectedIndex; + } + } + }; + var ELEMENT_NODE = 1; + var DOCUMENT_FRAGMENT_NODE$1 = 11; + var TEXT_NODE = 3; + var COMMENT_NODE = 8; + function noop() { + } + function defaultGetNodeKey(node) { + if (node) { + return node.getAttribute && node.getAttribute("id") || node.id; + } + } + function morphdomFactory(morphAttrs2) { + return function morphdom2(fromNode, toNode, options) { + if (!options) { + options = {}; + } + if (typeof toNode === "string") { + if (fromNode.nodeName === "#document" || fromNode.nodeName === "HTML" || fromNode.nodeName === "BODY") { + var toNodeHtml = toNode; + toNode = doc.createElement("html"); + toNode.innerHTML = toNodeHtml; + } else { + toNode = toElement(toNode); + } + } + var getNodeKey = options.getNodeKey || defaultGetNodeKey; + var onBeforeNodeAdded = options.onBeforeNodeAdded || noop; + var onNodeAdded = options.onNodeAdded || noop; + var onBeforeElUpdated = options.onBeforeElUpdated || noop; + var onElUpdated = options.onElUpdated || noop; + var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop; + var onNodeDiscarded = options.onNodeDiscarded || noop; + var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop; + var childrenOnly = options.childrenOnly === true; + var fromNodesLookup = /* @__PURE__ */ Object.create(null); + var keyedRemovalList = []; + function addKeyedRemoval(key) { + keyedRemovalList.push(key); + } + function walkDiscardedChildNodes(node, skipKeyedNodes) { + if (node.nodeType === ELEMENT_NODE) { + var curChild = node.firstChild; + while (curChild) { + var key = void 0; + if (skipKeyedNodes && (key = getNodeKey(curChild))) { + addKeyedRemoval(key); + } else { + onNodeDiscarded(curChild); + if (curChild.firstChild) { + walkDiscardedChildNodes(curChild, skipKeyedNodes); + } + } + curChild = curChild.nextSibling; + } + } + } + function removeNode(node, parentNode, skipKeyedNodes) { + if (onBeforeNodeDiscarded(node) === false) { + return; + } + if (parentNode) { + parentNode.removeChild(node); + } + onNodeDiscarded(node); + walkDiscardedChildNodes(node, skipKeyedNodes); + } + function indexTree(node) { + if (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE$1) { + var curChild = node.firstChild; + while (curChild) { + var key = getNodeKey(curChild); + if (key) { + fromNodesLookup[key] = curChild; + } + indexTree(curChild); + curChild = curChild.nextSibling; + } + } + } + indexTree(fromNode); + function handleNodeAdded(el) { + onNodeAdded(el); + var curChild = el.firstChild; + while (curChild) { + var nextSibling = curChild.nextSibling; + var key = getNodeKey(curChild); + if (key) { + var unmatchedFromEl = fromNodesLookup[key]; + if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) { + curChild.parentNode.replaceChild(unmatchedFromEl, curChild); + morphEl(unmatchedFromEl, curChild); + } else { + handleNodeAdded(curChild); + } + } else { + handleNodeAdded(curChild); + } + curChild = nextSibling; + } + } + function cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey) { + while (curFromNodeChild) { + var fromNextSibling = curFromNodeChild.nextSibling; + if (curFromNodeKey = getNodeKey(curFromNodeChild)) { + addKeyedRemoval(curFromNodeKey); + } else { + removeNode(curFromNodeChild, fromEl, true); + } + curFromNodeChild = fromNextSibling; + } + } + function morphEl(fromEl, toEl, childrenOnly2) { + var toElKey = getNodeKey(toEl); + if (toElKey) { + delete fromNodesLookup[toElKey]; + } + if (!childrenOnly2) { + if (onBeforeElUpdated(fromEl, toEl) === false) { + return; + } + morphAttrs2(fromEl, toEl); + onElUpdated(fromEl); + if (onBeforeElChildrenUpdated(fromEl, toEl) === false) { + return; + } + } + if (fromEl.nodeName !== "TEXTAREA") { + morphChildren(fromEl, toEl); + } else { + specialElHandlers.TEXTAREA(fromEl, toEl); + } + } + function morphChildren(fromEl, toEl) { + var curToNodeChild = toEl.firstChild; + var curFromNodeChild = fromEl.firstChild; + var curToNodeKey; + var curFromNodeKey; + var fromNextSibling; + var toNextSibling; + var matchingFromEl; + outer: + while (curToNodeChild) { + toNextSibling = curToNodeChild.nextSibling; + curToNodeKey = getNodeKey(curToNodeChild); + while (curFromNodeChild) { + fromNextSibling = curFromNodeChild.nextSibling; + if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) { + curToNodeChild = toNextSibling; + curFromNodeChild = fromNextSibling; + continue outer; + } + curFromNodeKey = getNodeKey(curFromNodeChild); + var curFromNodeType = curFromNodeChild.nodeType; + var isCompatible = void 0; + if (curFromNodeType === curToNodeChild.nodeType) { + if (curFromNodeType === ELEMENT_NODE) { + if (curToNodeKey) { + if (curToNodeKey !== curFromNodeKey) { + if (matchingFromEl = fromNodesLookup[curToNodeKey]) { + if (fromNextSibling === matchingFromEl) { + isCompatible = false; + } else { + fromEl.insertBefore(matchingFromEl, curFromNodeChild); + if (curFromNodeKey) { + addKeyedRemoval(curFromNodeKey); + } else { + removeNode(curFromNodeChild, fromEl, true); + } + curFromNodeChild = matchingFromEl; + } + } else { + isCompatible = false; + } + } + } else if (curFromNodeKey) { + isCompatible = false; + } + isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild); + if (isCompatible) { + morphEl(curFromNodeChild, curToNodeChild); + } + } else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) { + isCompatible = true; + if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) { + curFromNodeChild.nodeValue = curToNodeChild.nodeValue; + } + } + } + if (isCompatible) { + curToNodeChild = toNextSibling; + curFromNodeChild = fromNextSibling; + continue outer; + } + if (curFromNodeKey) { + addKeyedRemoval(curFromNodeKey); + } else { + removeNode(curFromNodeChild, fromEl, true); + } + curFromNodeChild = fromNextSibling; + } + if (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) { + fromEl.appendChild(matchingFromEl); + morphEl(matchingFromEl, curToNodeChild); + } else { + var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild); + if (onBeforeNodeAddedResult !== false) { + if (onBeforeNodeAddedResult) { + curToNodeChild = onBeforeNodeAddedResult; + } + if (curToNodeChild.actualize) { + curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc); + } + fromEl.appendChild(curToNodeChild); + handleNodeAdded(curToNodeChild); + } + } + curToNodeChild = toNextSibling; + curFromNodeChild = fromNextSibling; + } + cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey); + var specialElHandler = specialElHandlers[fromEl.nodeName]; + if (specialElHandler) { + specialElHandler(fromEl, toEl); + } + } + var morphedNode = fromNode; + var morphedNodeType = morphedNode.nodeType; + var toNodeType = toNode.nodeType; + if (!childrenOnly) { + if (morphedNodeType === ELEMENT_NODE) { + if (toNodeType === ELEMENT_NODE) { + if (!compareNodeNames(fromNode, toNode)) { + onNodeDiscarded(fromNode); + morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI)); + } + } else { + morphedNode = toNode; + } + } else if (morphedNodeType === TEXT_NODE || morphedNodeType === COMMENT_NODE) { + if (toNodeType === morphedNodeType) { + if (morphedNode.nodeValue !== toNode.nodeValue) { + morphedNode.nodeValue = toNode.nodeValue; + } + return morphedNode; + } else { + morphedNode = toNode; + } + } + } + if (morphedNode === toNode) { + onNodeDiscarded(fromNode); + } else { + if (toNode.isSameNode && toNode.isSameNode(morphedNode)) { + return; + } + morphEl(morphedNode, toNode, childrenOnly); + if (keyedRemovalList) { + for (var i = 0, len = keyedRemovalList.length; i < len; i++) { + var elToRemove = fromNodesLookup[keyedRemovalList[i]]; + if (elToRemove) { + removeNode(elToRemove, elToRemove.parentNode, false); + } + } + } + } + if (!childrenOnly && morphedNode !== fromNode && fromNode.parentNode) { + if (morphedNode.actualize) { + morphedNode = morphedNode.actualize(fromNode.ownerDocument || doc); + } + fromNode.parentNode.replaceChild(morphedNode, fromNode); + } + return morphedNode; + }; + } + var morphdom = morphdomFactory(morphAttrs); + var morphdom_esm_default = morphdom; + + // preview-src/previewerEventHandler.js + var vscode = acquireVsCodeApi(); + function getLineNumber(elem) { + const classname = elem.className; + const line_classname = classname.split(" ").find((cn) => cn.startsWith("linemarker-")); + const marker_vs = line_classname.split("-")[1]; + return marker_vs; + } + window.addEventListener( + "click", + (event) => { + if (event.ctrlKey) { + const pos = event.clientY + window.scrollY; + const elems = document.getElementsByClassName("linemarker"); + if (elems.length === 0) { + return; + } + let found = false; + let marker_start = 0; + let marker_end = 0; + for (let i = 0; i < elems.length; i++) { + const elem = elems.item(i); + const role = elem.parentElement.getAttribute("role"); + if (role === "navigation") { + continue; + } + const pos_elem = elem.getBoundingClientRect().top + window.scrollY; + if (pos_elem > pos) { + if (i > 0) { + marker_start = getLineNumber(elems.item(i - 1)); + marker_end = getLineNumber(elem); + } else { + marker_start = -1; + marker_end = getLineNumber(elem); + } + found = true; + break; + } + } + if (found === false) { + marker_start = getLineNumber(elems.item(elems.length - 1)); + marker_end = -1; + } + vscode.postMessage({ + command: "show_range", + start: marker_start, + end: marker_end + }); + event.stopPropagation(); + event.stopImmediatePropagation(); + event.preventDefault(); + return false; + } + }, + true + ); + window.addEventListener("message", (event) => { + const message = event.data; + switch (message.method) { + case "updateContent": { + const parser = new DOMParser(); + const target_doc = parser.parseFromString( + event.data.content, + "text/html" + ); + morphdom_esm_default(document.body, target_doc.body, { + childrenOnly: true + }); + window.document.dispatchEvent( + new Event("DOMContentLoaded", { + bubbles: true, + cancelable: true + }) + ); + MathJax.typeset(); + break; + } + case "updateView": { + console.log("updateView"); + const vs_top_line = message.line; + const elems = document.getElementsByClassName("linemarker"); + for (let i = 0; i < elems.length; i++) { + const elem = elems.item(i); + const role = elem.parentElement.getAttribute("role"); + if (role === "navigation") { + continue; + } + const classname = elem.className; + const marker_wv = elem.getBoundingClientRect().top + window.scrollY; + const line_classname = classname.split(" ").find((cn) => cn.startsWith("linemarker-")); + const marker_vs = line_classname.split("-")[1]; + if (marker_vs > vs_top_line) { + let prev_marker_wv = 0; + let prev_marker_vs = 0; + if (i > 0) { + const prev_elem = elems.item(i - 1); + prev_marker_wv = prev_elem.getBoundingClientRect().top + window.scrollY; + const prev_classname = prev_elem.className; + const prev_line_classname = prev_classname.split(" ").find((cn) => cn.startsWith("linemarker-")); + prev_marker_vs = prev_line_classname.split("-")[1]; + } + const wv_diff = marker_wv - prev_marker_wv; + const vs_diff = marker_vs - prev_marker_vs; + const fact = (marker_vs - vs_top_line) / vs_diff; + const top_wv = marker_wv - fact * wv_diff; + window.scroll(0, top_wv - 20); + break; + } + } + } + } + }); + window.onload = function() { + vscode.postMessage({ command: "load" }); + }; +})(); diff --git a/docs/source/index.rst b/docs/source/index.rst index 75767e2..99cf24d 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -9,7 +9,8 @@ Welcome to wavinfo's documentation! .. toctree:: :maxdepth: 2 :caption: Notes - + + quickstart metadata_scopes/adm.rst metadata_scopes/bext.rst metadata_scopes/info.rst diff --git a/docs/source/quickstart.rst b/docs/source/quickstart.rst new file mode 100644 index 0000000..d62f207 --- /dev/null +++ b/docs/source/quickstart.rst @@ -0,0 +1,3 @@ +ptulsconv Quickstart +==================== + diff --git a/metadata.py b/metadata.py index c818b8a..eb554e7 100644 --- a/metadata.py +++ b/metadata.py @@ -1,6 +1,6 @@ """ Wavinfo """ -__version__ = '2.0.0' +__version__ = '2.0.1' __author__ = 'Jamie Hardt ' __license__ = "MIT"