From 5dcc72c2c61e3aafc30b041e312784d881de72d8 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Wed, 22 Jul 2020 20:54:40 -0700 Subject: turn markers into documents and kind of got linking to work --- src/client/documents/Documents.ts | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 8e7d125b0..b94670cd5 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -189,6 +189,9 @@ export interface DocumentOptions { searchQuery?: string; // for queryBox filterQuery?: string; linearViewIsExpanded?: boolean; // is linear view expanded + isLabel?: boolean; // whether the document is a label or not (video / audio) + audioStart?: number; // the time frame where the audio should begin playing + audioEnd?: number; // the time frame where the audio should stop playing } class EmptyBox { -- cgit v1.2.3-70-g09d2 From 8722fe67029f76f572eacd6e02d623690ca94793 Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Sun, 26 Jul 2020 22:08:13 -0700 Subject: added options to hide markers/labels --- src/client/documents/Documents.ts | 1 + src/client/views/nodes/AudioBox.tsx | 110 ++++++++++++++++++++---------------- src/fields/ScriptField.ts | 1 - 3 files changed, 62 insertions(+), 50 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 170426db3..ffc22292e 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -562,6 +562,7 @@ export namespace Docs { viewDoc.author = Doc.CurrentUserEmail; viewDoc.type !== DocumentType.LINK && DocUtils.MakeLinkToActiveAudio(viewDoc); + console.log("audio link!"); return Doc.assign(viewDoc, delegateProps, true); } diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index bfa48578b..0cab0fc61 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -176,7 +176,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent -1) { setTimeout(() => this.playFrom(0), -seekTimeInSeconds * 1000); } else { - console.log("dude"); this.pause(); } } else if (seekTimeInSeconds <= this._ele.duration) { @@ -227,7 +226,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent { const funcs: ContextMenuProps[] = []; funcs.push({ description: (this.layoutDoc.playOnSelect ? "Don't play" : "Play") + " when document selected", event: () => this.layoutDoc.playOnSelect = !this.layoutDoc.playOnSelect, icon: "expand-arrows-alt" }); - + funcs.push({ description: (this.layoutDoc.hideMarkers ? "Don't hide" : "Hide") + " markers", event: () => this.layoutDoc.hideMarkers = !this.layoutDoc.hideMarkers, icon: "expand-arrows-alt" }) + funcs.push({ description: (this.layoutDoc.hideLabels ? "Don't hide" : "Hide") + " labels", event: () => this.layoutDoc.hideLabels = !this.layoutDoc.hideLabels, icon: "expand-arrows-alt" }) + funcs.push({ description: (this.layoutDoc.playOnClick ? "Don't play" : "Play") + " onClick", event: () => this.layoutDoc.playOnClick = !this.layoutDoc.playOnClick, icon: "expand-arrows-alt" }) ContextMenu.Instance?.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" }); } @@ -433,8 +434,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent AudioBox.LabelScript; // see if time is encapsulated by comparing time on both sides (for moving onto a new row in the timeline for the markers) + check = (e: React.PointerEvent) => { + if (e.target as HTMLElement === document.getElementById("timeline")) { + return true; + } + } render() { - trace(); + //trace(); const interactive = this.active() ? "-interactive" : ""; return
{!this.path ? @@ -568,56 +572,56 @@ export class AudioBox extends ViewBoxAnnotatableComponent {DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => { - // let text = Docs.Create.TextDocument("hello", { title: "label", _showSidebar: false, _autoHeight: false }); let rect; (!m.isLabel) ? - - rect = -
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation() }} > -
this.onPointerDown(e, m, true)}>
- - {/* */} - {/*
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)) }}>
*/} -
this.onPointerDown(e, m, false)}>
-
+ (this.layoutDoc.hideMarkers) ? (null) : + rect = +
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation() }} > +
this.onPointerDown(e, m, true)}>
+ + {/* */} + {/*
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)) }}>
*/} +
this.onPointerDown(e, m, false)}>
+
: - rect = -
- -
; + (this.layoutDoc.hideLabels) ? (null) : + rect = +
+ +
; return rect; })} {DocListCast(this.dataDoc.links).map((l, i) => { - console.log("hi"); + let la1 = l.anchor1 as Doc; let la2 = l.anchor2 as Doc; let linkTime = NumCast(l.anchor2_timecode); @@ -627,6 +631,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent e.stopPropagation()}> @@ -648,7 +660,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); this.pause(); e.stopPropagation(); e.preventDefault(); } }} />
; })} -
{ e.stopPropagation(); e.preventDefault(); console.log("hi"); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} /> +
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} /> {this.audio}
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts index 4604a2132..bd08b2f32 100644 --- a/src/fields/ScriptField.ts +++ b/src/fields/ScriptField.ts @@ -53,7 +53,6 @@ async function deserializeScript(script: ScriptField) { if (script.script.originalScript === 'convertToButtons(dragData)') { return (script as any).script = (ScriptField.ConvertToButtons ?? (ScriptField.ConvertToButtons = ComputedField.MakeFunction('convertToButtons(dragData)', { dragData: "DocumentDragData" })))?.script; } - console.log(script.script.originalScript); const captures: ProxyField = (script as any).captures; if (captures) { const doc = (await captures.value())!; -- cgit v1.2.3-70-g09d2 From 28ab7ecd633e92619adfcbd1ce3ca72ddbba7ea8 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 29 Jul 2020 01:05:43 -0400 Subject: fixed up dot anchors on audio labels/anchors --- src/client/documents/Documents.ts | 5 ++++- .../CollectionFreeFormLinkView.tsx | 6 +++--- src/client/views/nodes/AudioBox.tsx | 25 +++++++++------------- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/LinkAnchorBox.tsx | 2 +- src/client/views/nodes/formattedText/marks_rts.ts | 6 +++--- 6 files changed, 22 insertions(+), 24 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index fb9f6fe46..122383744 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -192,6 +192,7 @@ export interface DocumentOptions { filterQuery?: string; linearViewIsExpanded?: boolean; // is linear view expanded isLabel?: boolean; // whether the document is a label or not (video / audio) + useLinkSmallAnchor?: boolean; // whether links to this document should use a miniature linkAnchorBox audioStart?: number; // the time frame where the audio should begin playing audioEnd?: number; // the time frame where the audio should stop playing } @@ -627,7 +628,7 @@ export namespace Docs { } export function AudioDocument(url: string, options: DocumentOptions = {}) { - const instance = InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), options); + const instance = InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), { hideLinkButton: true, useLinkSmallAnchor: true, ...options }); Doc.GetProto(instance).backgroundColor = ComputedField.MakeFunction("this._audioState === 'playing' ? 'green':'gray'"); return instance; } @@ -925,6 +926,8 @@ export namespace DocUtils { if (target.doc === Doc.UserDoc()) return undefined; const linkDoc = Docs.Create.LinkDocument(source, target, { linkRelationship, layoutKey: "layout_linkView", description }, id); + Doc.GetProto(linkDoc)["anchor1-useLinkSmallAnchor"] = source.doc.useLinkSmallAnchor; + Doc.GetProto(linkDoc)["anchor2-useLinkSmallAnchor"] = target.doc.useLinkSmallAnchor; linkDoc.linkDisplay = true; linkDoc.hidden = true; linkDoc.layout_linkView = Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index bfe569853..3a2979696 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -54,15 +54,15 @@ export class CollectionFreeFormLinkView extends React.Component ele.getAttribute("targetids")?.includes(AanchorId)); - const targetBhyperlink = linkEles.find((ele: any) => ele.getAttribute("targetids")?.includes(BanchorId)); + const targetAhyperlink = linkEles.find((ele: any) => ele.dataset.targetids?.includes(AanchorId)); + const targetBhyperlink = linkEles.find((ele: any) => ele.dataset.targetids?.includes(BanchorId)); if (!targetBhyperlink) { this.props.A.rootDoc[afield + "_x"] = (apt.point.x - abounds.left) / abounds.width * 100; this.props.A.rootDoc[afield + "_y"] = (apt.point.y - abounds.top) / abounds.height * 100; diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 02932baac..34f87fc10 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -355,7 +355,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent e.stopPropagation()}> {/*
*/} @@ -672,15 +665,17 @@ export class AudioBox extends ViewBoxAnnotatableComponent - {/*
*/} -
Doc.linkFollowHighlight(la1)} + backgroundColor={returnTransparent} + ContentScaling={returnOne} + forcedBackgroundColor={returnTransparent} + pointerEvents={false} + LayoutTemplate={undefined} + LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(l, la2)}`)} + /> +
Doc.linkFollowHighlight(la1)} onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { const wasPaused = this.audioState === "paused"; this.playFrom(linkTime); this.pause(); e.stopPropagation(); e.preventDefault(); } }} />
; })} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 74634f837..77932d58e 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1098,7 +1098,7 @@ export class DocumentView extends DocComponent(Docu return (this.props.treeViewDoc && this.props.LayoutTemplateString) || // render nothing for: tree view anchor dots this.layoutDoc.presBox || // presentationbox nodes this.props.dontRegisterView ? (null) : // view that are not registered - DocUtils.FilterDocs(LinkManager.Instance.getAllDirectLinks(this.Document), this.props.docFilters(), []).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) => + DocUtils.FilterDocs(LinkManager.Instance.getAllDirectLinks(this.Document), this.props.docFilters(), []).filter(d => !d.hidden && this.isNonTemporalLink(d)).map((d, i) => -- cgit v1.2.3-70-g09d2 From 58f75d38dcfd113c90e4e27e55468d06412c653e Mon Sep 17 00:00:00 2001 From: Lionel Han <47760119+IGoByJoe@users.noreply.github.com> Date: Sat, 1 Aug 2020 16:34:48 -0700 Subject: fixed bugs and added waveform (need fix) --- package-lock.json | 36 ++++++++++++++ package.json | 2 + src/client/documents/Documents.ts | 2 +- src/client/views/nodes/AudioBox.scss | 10 +++- src/client/views/nodes/AudioBox.tsx | 91 +++++++++++++++++++++++++++++++++++- src/typings/index.d.ts | 1 + 6 files changed, 139 insertions(+), 3 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/package-lock.json b/package-lock.json index 698bd60cc..31369f427 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2198,6 +2198,37 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -14119,6 +14150,11 @@ "prop-types": "^15.6.2" } }, + "react-audio-waveform": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/react-audio-waveform/-/react-audio-waveform-0.0.5.tgz", + "integrity": "sha512-4dJwhl+LQRuywzmmjuhWT5GueT3Ai2ZhB+loVxg0sRdhplyDp96xAu10/V/+J25Cl7YqNtl2DWSxvSoI/i6l6w==" + }, "react-autosuggest": { "version": "9.4.3", "resolved": "https://registry.npmjs.org/react-autosuggest/-/react-autosuggest-9.4.3.tgz", diff --git a/package.json b/package.json index 6c466825e..44304ce87 100644 --- a/package.json +++ b/package.json @@ -131,6 +131,7 @@ "archiver": "^3.1.1", "array-batcher": "^1.2.3", "async": "^2.6.2", + "axios": "^0.19.2", "babel-runtime": "^6.26.0", "bcrypt-nodejs": "0.0.3", "bezier-curve": "^1.0.0", @@ -216,6 +217,7 @@ "raw-loader": "^1.0.0", "rc-switch": "^1.9.0", "react": "^16.12.0", + "react-audio-waveform": "0.0.5", "react-autosuggest": "^9.4.3", "react-color": "^2.18.1", "react-compound-slider": "^2.5.0", diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 122383744..88f470576 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -628,7 +628,7 @@ export namespace Docs { } export function AudioDocument(url: string, options: DocumentOptions = {}) { - const instance = InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), { hideLinkButton: true, useLinkSmallAnchor: true, ...options }); + const instance = InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), { ...options }); // hideLinkButton: false, useLinkSmallAnchor: false, Doc.GetProto(instance).backgroundColor = ComputedField.MakeFunction("this._audioState === 'playing' ? 'green':'gray'"); return instance; } diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss index 6d52988bb..35ab5da8b 100644 --- a/src/client/views/nodes/AudioBox.scss +++ b/src/client/views/nodes/AudioBox.scss @@ -140,6 +140,14 @@ height: 100%; background-color: red; position: absolute; + top: 0px; + } + + .waveform { + position: relative; + width: 100%; + height: 100%; + overflow: hidden; } .audiobox-linker, @@ -259,7 +267,7 @@ .audiobox-marker-container1:hover, .audiobox-marker-minicontainer:hover { - opacity: 1; + opacity: 0.8; } .audiobox-marker-minicontainer { diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 34f87fc10..3d1932883 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -29,7 +29,8 @@ import { LabelBox } from "./LabelBox"; import { Transform } from "../../util/Transform"; import { Scripting } from "../../util/Scripting"; import { ColorBox } from "./ColorBox"; - +import Waveform from "react-audio-waveform" +import axios from "axios" // testing testing @@ -73,6 +74,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent = []; _first: boolean = false; + _buckets: Array = new Array(); private _isPointerDown = false; private _currMarker: any; @@ -80,6 +82,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent = []; + // @observable private _buckets: Array = new Array(); @observable private _paused: boolean = false; @observable private static _scrubTime = 0; @@ -299,6 +302,81 @@ export class AudioBox extends ViewBoxAnnotatableComponent { + let audioCtx = new (window.AudioContext)(); + const buckets: number[] = []; + + axios({ url: this.path, responseType: "arraybuffer" }) + .then(async response => { + let audioData = response.data; + + await audioCtx.decodeAudioData(audioData, buffer => { + let decodedAudioData = buffer.getChannelData(0); + const NUMBER_OF_BUCKETS = 100; + let bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS); + + for (let i = 0; i < NUMBER_OF_BUCKETS; i++) { + let startingPoint = i * bucketDataSize; + let endingPoint = i * bucketDataSize + bucketDataSize; + let max = 0; + for (let j = startingPoint; j < endingPoint; j++) { + if (decodedAudioData[j] > max) { + max = decodedAudioData[j]; + } + } + let size = Math.abs(max); + buckets.push(size / 2); + this._buckets.push(size / 2); + } + + }); + return buckets; + }); + } + + @computed get peaks() { + // let audioCtx = new (window.AudioContext)(); + // let buckets: number[] = []; + + // return (async () => { + // await axios({ url: this.path, responseType: "arraybuffer" }) + // .then(response => { + // let audioData = response.data; + + // audioCtx.decodeAudioData(audioData, buffer => { + // let decodedAudioData = buffer.getChannelData(0); + // const NUMBER_OF_BUCKETS = 100; + // let bucketDataSize = Math.floor(decodedAudioData.length / NUMBER_OF_BUCKETS); + + + + // for (let i = 0; i < NUMBER_OF_BUCKETS; i++) { + // let startingPoint = i * bucketDataSize; + // let endingPoint = i * bucketDataSize + bucketDataSize; + // let max = 0; + // for (let j = startingPoint; j < endingPoint; j++) { + // if (decodedAudioData[j] > max) { + // max = decodedAudioData[j]; + // } + // } + // let size = Math.abs(max); + // console.log(size); + // buckets.push(size / 2); + // console.log(buckets); + // } + // }); + // console.log(buckets); + // return buckets; + // }); + // console.log(buckets.length); + // return buckets; + // })(); + + + return this.buckets(); + } + @computed get audio() { const interactive = this.active() ? "-interactive" : ""; return