From 06bdd0dad15963ffc57e55ae4830582459f48b00 Mon Sep 17 00:00:00 2001 From: Ruben van de Ven Date: Tue, 31 May 2022 13:15:22 +0200 Subject: [PATCH] Fix playback of empty slice. --- app/svganim/strokes.py | 26 +++++++++++++++++++++----- app/www/annotate.js | 21 ++++++++++++++------- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/app/svganim/strokes.py b/app/svganim/strokes.py index 8a05cc9..0f7b923 100644 --- a/app/svganim/strokes.py +++ b/app/svganim/strokes.py @@ -232,7 +232,7 @@ class AnimationSlice: strokes = self.getStrokeSlices(frame_in, frame_out, t_in) # TODO shift t of points with t_in viewboxes = self.getViewboxesSlice(t_in, t_out) - print(viewboxes[0]) + audio = self.audio.getSlice(t_in, t_out) if self.audio else None return AnimationSlice([self.id[0], t_in, t_out], strokes, viewboxes, t_in, t_out, audio) @@ -287,8 +287,17 @@ class AnimationSlice: ) -> list[Stroke]: """Get list of Stroke/StrokeSlice based in in and out indexes Based on annotation.js getStrokesSliceForPathRange(in_point, out_point) + If either in point or out point is [None, None], return an empty set. """ slices = [] + if index_in[0] is None and index_in[1] is None: + # If no inpoint is set, in_point is after the last stroke + return slices + + if index_out[0] is None and index_out[1] is None: + # If no out point is set, out_point is before the last stroke + return slices + for i in range(index_in[0], index_out[0] + 1): try: stroke = self.strokes[i] @@ -308,8 +317,8 @@ class AnimationSlice: The In point version (so the first index after ms) Equal to annotations.js findPositionForTime(ms) """ - path_i = 0 - point_i = 0 + path_i = None + point_i = None for i, stroke in enumerate(self.strokes): start_at = stroke.points[0].t end_at = stroke.points[-1].t @@ -329,6 +338,9 @@ class AnimationSlice: if point.t > ms: break # stop when finding the next point after in point break # done :-) + if path_i is None or point_i is None: + logger.warn("in point after last stroke. Not sure if this works") + pass return (path_i, point_i) def getIndexForOutPoint(self, ms: Milliseconds) -> FrameIndex: @@ -342,8 +354,8 @@ class AnimationSlice: """Get the frame index (path, point) based on the given time Equal to annotations.js findPositionForTime(ms) """ - path_i = 0 - point_i = 0 + path_i = None + point_i = None for i, stroke in enumerate(self.strokes): start_at = stroke.points[0].t end_at = stroke.points[-1].t @@ -363,6 +375,10 @@ class AnimationSlice: # best option thus far path_i = i point_i = len(stroke.points) - 1 + + if path_i is None or point_i is None: + logger.warn("OUT point after last stroke. Not sure if this works") + pass return (path_i, point_i) audiocache = {} diff --git a/app/www/annotate.js b/app/www/annotate.js index 5eb92ba..77c5f4f 100644 --- a/app/www/annotate.js +++ b/app/www/annotate.js @@ -716,8 +716,8 @@ class Annotator extends EventTarget { // bgEl.setAttribute("height", this.dimensions[1]); // bgEl.classList.add('background'); // this.svgEl.prepend(bgEl); - - this.firstFrameTime = this.strokes[0].points[0][3]; + + this.firstFrameTime = this.strokes.length == 0 ? 0 : this.strokes[0].points[0][3]; this.lastFrameTime = this.getFinalFrameTime(); this.playheadEl.max = this.lastFrameTime; this.nextFrameTimeout = null; @@ -817,7 +817,7 @@ class Annotator extends EventTarget { this.audioEl.setAttribute('controls', true); this.audioEl.addEventListener('canplaythrough', (ev) => { - console.log('loaded audio', ev); + console.debug('loaded audio'); // this.audioEl.play(); }); @@ -959,6 +959,7 @@ class Annotator extends EventTarget { } getFinalFrameTime() { + if(this.strokes.length == 0) return null; // when no strokes are loaded (eg. for annotation) const points = this.strokes[this.strokes.length - 1].points; return points[points.length - 1][3]; } @@ -1093,9 +1094,15 @@ class Annotator extends EventTarget { } playStrokePosition(path_i, point_i, allow_interrupt) { + if (this.strokes.length === 0) { + console.debug('No video to play back'); + this.videoIsPlaying = false; + return; + } + if (allow_interrupt) { if (!this.videoIsPlaying) { - console.log('not playing because of interrupt'); + console.debug('not playing because of interrupt'); return; } } else { @@ -1121,7 +1128,7 @@ class Annotator extends EventTarget { playViewboxPosition(box_i, allow_interrupt) { if (allow_interrupt) { if (!this.videoIsPlaying) { - console.log('not playing because of interrupt'); + console.debug('not playing because of interrupt'); return; } } @@ -1196,7 +1203,7 @@ class Annotator extends EventTarget { this._setPausedFlag(false); const startPlayback = () => { - console.log('start playback'); + console.debug('start playback'); this.wrapperEl.classList.remove('loading'); // no loading anymore this.startTimeMs = window.performance.now() - this._currentTimeMs; @@ -1221,7 +1228,7 @@ class Annotator extends EventTarget { } if (this.audioEl.src.length && this.audioEl.readyState !== 4) { // not ready to play after seeking audio. - console.log('wait for audio before playback'); + console.debug('wait for audio before playback'); this.wrapperEl.classList.add('loading'); this.audioEl.addEventListener('canplaythrough', () => { startPlayback()