From e4791f989024410443059bee424606c0567bc5f7 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 22 Mar 2021 00:30:21 -0400 Subject: fixed audio/video synchronizatoin for screengrab videos. fixed following isLinkButton's in stackedTimelines. Made links from screenGrab videos to document whn presented in lightbox. --- src/client/documents/Documents.ts | 2 ++ src/client/views/LightboxView.tsx | 1 + .../views/collections/CollectionStackedTimeline.tsx | 18 ++++++++---------- src/client/views/nodes/AudioBox.tsx | 12 +++++------- src/client/views/nodes/ScreenshotBox.tsx | 6 +++--- src/client/views/nodes/VideoBox.tsx | 11 +++++++---- 6 files changed, 26 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 16b303f7d..da434ab77 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -164,6 +164,8 @@ export class DocumentOptions { version?: string; // version identifier for a document label?: string; hidden?: boolean; + autoPlayAnchors?: boolean; // whether to play audio/video when an anchor is clicked in a stackedTimeline. + dontPlayLinkOnSelect?: boolean; // whether an audio/video should start playing when a link is followed to it. toolTip?: string; // tooltip to display on hover dontUndo?: boolean; // whether button clicks should be undoable (this is set to true for Undo/Redo/and sidebar buttons that open the siebar panel) description?: string; // added for links diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 731d46502..48b8ca341 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -116,6 +116,7 @@ export class LightboxView extends React.Component { const target = LightboxView._docTarget = LightboxView._future?.pop(); const docView = target && DocumentManager.Instance.getLightboxDocumentView(target); if (docView && target) { + DocUtils.MakeLinkToActiveAudio(target); docView.focus(target, { originalTarget: target, willZoom: true, scale: 0.9 }); if (LightboxView._history?.lastElement().target !== target) LightboxView._history?.push({ doc, target }); } else { diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 16a1c02f7..cdb2468f2 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -18,6 +18,7 @@ import { DocumentView, DocAfterFocusFunc } from "../nodes/DocumentView"; import { LabelBox } from "../nodes/LabelBox"; import "./CollectionStackedTimeline.scss"; import { Transform } from "../../util/Transform"; +import { LinkManager } from "../../util/LinkManager"; type PanZoomDocument = makeInterface<[]>; const PanZoomDocument = makeInterface(); @@ -59,9 +60,7 @@ export class CollectionStackedTimeline extends CollectionSubView Math.max(0, Math.min(this.duration, screen_delta / width * this.duration)); rangeClickScript = () => CollectionStackedTimeline.RangeScript; - labelClickScript = () => CollectionStackedTimeline.LabelScript; rangePlayScript = () => CollectionStackedTimeline.RangePlayScript; - labelPlayScript = () => CollectionStackedTimeline.LabelPlayScript; // for creating key anchors with key events @action @@ -175,12 +172,12 @@ export class CollectionStackedTimeline extends CollectionSubView { const seekTimeInSeconds = this.anchorStart(anchorDoc); const endTime = this.anchorEnd(anchorDoc); - if (this.layoutDoc.autoPlay) { + if (this.layoutDoc.autoPlayAnchors) { if (this.props.playing()) this.props.Pause(); else this.props.playFrom(seekTimeInSeconds, endTime); } else { if (seekTimeInSeconds < NumCast(this.layoutDoc._currentTimecode) && endTime > NumCast(this.layoutDoc._currentTimecode)) { - if (!this.layoutDoc.autoPlay && this.props.playing()) { + if (!this.layoutDoc.autoPlayAnchors && this.props.playing()) { this.props.Pause(); } else { this.props.Play(); @@ -194,17 +191,18 @@ export class CollectionStackedTimeline extends CollectionSubView { + if (anchorDoc.isLinkButton) LinkManager.FollowLink(undefined, anchorDoc, this.props, false); const seekTimeInSeconds = this.anchorStart(anchorDoc); const endTime = this.anchorEnd(anchorDoc); if (seekTimeInSeconds < NumCast(this.layoutDoc._currentTimecode) + 1e-4 && endTime > NumCast(this.layoutDoc._currentTimecode) - 1e-4) { if (this.props.playing()) this.props.Pause(); - else if (this.layoutDoc.autoPlay) this.props.Play(); - else if (!this.layoutDoc.autoPlay) { + else if (this.layoutDoc.autoPlayAnchors) this.props.Play(); + else if (!this.layoutDoc.autoPlayAnchors) { const rect = this._timeline?.getBoundingClientRect(); rect && this.props.setTime(this.toTimeline(clientX - rect.x, rect.width)); } } else { - if (this.layoutDoc.autoPlay) this.props.playFrom(seekTimeInSeconds, endTime); + if (this.layoutDoc.autoPlayAnchors) this.props.playFrom(seekTimeInSeconds, endTime); else this.props.setTime(seekTimeInSeconds); } return { select: true }; @@ -276,7 +274,7 @@ export class CollectionStackedTimeline extends CollectionSubView this.props.isSelected(out) || this.props.isChildActive()} rootSelected={returnFalse} onClick={script} - onDoubleClick={this.props.Document.autoPlay ? undefined : doublescript} + onDoubleClick={this.layoutDoc.autoPlayAnchors ? undefined : doublescript} ignoreAutoHeight={false} hideResizeHandles={true} bringToFront={emptyFunction} diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 629d0c79b..393a80648 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -106,8 +106,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime)); - this._disposers.triggerAudio = reaction( () => !LinkDocPreview.LinkInfo && this.props.renderDepth !== -1 ? NumCast(this.Document._triggerAudio, null) : undefined, start => start !== undefined && setTimeout(() => { @@ -216,8 +214,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent { const funcs: ContextMenuProps[] = []; funcs.push({ description: (this.layoutDoc.hideAnchors ? "Don't hide" : "Hide") + " anchors", event: () => this.layoutDoc.hideAnchors = !this.layoutDoc.hideAnchors, icon: "expand-arrows-alt" }); - funcs.push({ description: (this.layoutDoc.playOnSelect ? "Don't play" : "Play") + " when link is selected", event: () => this.layoutDoc.playOnSelect = !this.layoutDoc.playOnSelect, icon: "expand-arrows-alt" }); - funcs.push({ description: (this.layoutDoc.autoPlay ? "Don't auto play" : "Auto play") + " anchors onClick", event: () => this.layoutDoc.autoPlay = !this.layoutDoc.autoPlay, icon: "expand-arrows-alt" }); + funcs.push({ description: (this.layoutDoc.dontAutoPlayFollowedLinks ? "" : "Don't") + " play when link is selected", event: () => this.layoutDoc.dontAutoPlayFollowedLinks = !this.layoutDoc.dontAutoPlayFollowedLinks, icon: "expand-arrows-alt" }); + funcs.push({ description: (this.layoutDoc.autoPlayAnchors ? "Don't auto play" : "Auto play") + " anchors onClick", event: () => this.layoutDoc.autoPlayAnchors = !this.layoutDoc.autoPlayAnchors, icon: "expand-arrows-alt" }); ContextMenu.Instance?.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" }); } @@ -330,7 +328,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { const stack = this._stackedTimeline.current; if (link.annotationOn === this.rootDoc) { - if (this.layoutDoc.playOnSelect) this.playFrom(stack?.anchorStart(link) || 0, stack?.anchorEnd(link)); + if (!this.layoutDoc.dontAutoPlayFollowedLinks) this.playFrom(stack?.anchorStart(link) || 0, stack?.anchorEnd(link)); else this._ele!.currentTime = this.layoutDoc._currentTimecode = (stack?.anchorStart(link) || 0); } else { @@ -339,7 +337,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent
- +
{this.audioState === "recording" || this.audioState === "paused" ?
e.stopPropagation()}> diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 403fb3573..0e69725ca 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -45,9 +45,9 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { + const startTime = Cast(this.layoutDoc._currentTimecode, "number", null) || (this._vrecorder ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined); return CollectionStackedTimeline.createAnchor(this.rootDoc, this.dataDoc, this.annotationKey, "_timecodeToShow" /* audioStart */, "_timecodeToHide" /* audioEnd */, - Cast(this.layoutDoc._currentTimecode, "number", null) || - (this._vrecorder ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined)) + startTime, startTime === undefined ? undefined : startTime + 3) || this.rootDoc; } @@ -165,7 +165,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { this._screenCapture = !this._screenCapture; if (this._screenCapture) { - this.dataDoc[this.props.fieldKey + "-recordingStart"] = new DateField(new Date()); this._arecorder = new MediaRecorder(await navigator.mediaDevices.getUserMedia({ audio: true })); this._achunks = []; this._arecorder.ondataavailable = (e: any) => this._achunks.push(e.data); @@ -179,6 +178,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent this.dataDoc[this.props.fieldKey + "-recordingStart"] = new DateField(new Date())); this._vrecorder.ondataavailable = (e: any) => this._vchunks.push(e.data); this._vrecorder.onstop = async (e: any) => { const file = new File(this._vchunks, `${this.rootDoc[Id]}.mkv`, { type: this._vchunks[0].type, lastModified: Date.now() }); diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index d475ab9f2..42258168c 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -84,12 +84,15 @@ export class VideoBox extends ViewBoxAnnotatableComponent { this._playing = true; try { + this._audioPlayer && this.player && (this._audioPlayer.currentTime = this.player?.currentTime); update && this.player?.play(); update && this._audioPlayer?.play(); update && this._youtubePlayer?.playVideo(); @@ -288,8 +291,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent this.layoutDoc.playOnSelect = !this.layoutDoc.playOnSelect, icon: "expand-arrows-alt" }); - subitems.push({ description: (this.layoutDoc.autoPlay ? "Don't auto play" : "Auto play") + " anchors onClick", event: () => this.layoutDoc.autoPlay = !this.layoutDoc.autoPlay, icon: "expand-arrows-alt" }); + subitems.push({ description: (this.layoutDoc.dontAutoPlayFollowedLinks ? "" : "Don't") + " play when link is selected", event: () => this.layoutDoc.dontAutoPlayFollowedLinks = !this.layoutDoc.dontAutoPlayFollowedLinks, icon: "expand-arrows-alt" }); + subitems.push({ description: (this.layoutDoc.autoPlayAnchors ? "Don't auto play" : "Auto play") + " anchors onClick", event: () => this.layoutDoc.autoPlayAnchors = !this.layoutDoc.autoPlayAnchors, icon: "expand-arrows-alt" }); ContextMenu.Instance.addItem({ description: "Options...", subitems: subitems, icon: "video" }); } } @@ -493,7 +496,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent