@checksub_team/peaks_timeline 2.0.1 → 2.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checksub_team/peaks_timeline",
3
- "version": "2.0.1",
3
+ "version": "2.1.0-alpha.0",
4
4
  "description": "JavaScript UI component for displaying audio waveforms",
5
5
  "main": "./peaks.js",
6
6
  "types": "./peaks.js.d.ts",
package/peaks.js CHANGED
@@ -14816,6 +14816,7 @@ module.exports = function (SourceGroup, Utils, Konva) {
14816
14816
  this._position = null;
14817
14817
  this._firstSourceId = null;
14818
14818
  this._sources = {};
14819
+ this._cachedStartSourceForActive = null;
14819
14820
  this._sourcesGroup = {};
14820
14821
  this._wrapped = false;
14821
14822
  this._group = new Konva.Group({
@@ -14831,6 +14832,9 @@ module.exports = function (SourceGroup, Utils, Konva) {
14831
14832
  this._height = this._peaks.options.emptyLineHeight;
14832
14833
  this._unwrappedCount = 0;
14833
14834
  }
14835
+ LineGroup.prototype.getSegmentsGroup = function () {
14836
+ return this._segmentsGroup;
14837
+ };
14834
14838
  LineGroup.prototype.getPosition = function () {
14835
14839
  return this._position;
14836
14840
  };
@@ -15285,6 +15289,44 @@ module.exports = function (SourceGroup, Utils, Konva) {
15285
15289
  };
15286
15290
  }
15287
15291
  };
15292
+ LineGroup.prototype.getActiveSource = function (time) {
15293
+ var activeSource = null;
15294
+ var previousSource = null;
15295
+ var currentSource = null;
15296
+ if (this._cachedStartSourceForActive) {
15297
+ if (this._cachedStartSourceForActive.startTime <= time) {
15298
+ if (this._cachedStartSourceForActive.endTime > time) {
15299
+ return this._cachedStartSourceForActive;
15300
+ } else {
15301
+ currentSource = this._sources[this._cachedStartSourceForActive.id];
15302
+ }
15303
+ }
15304
+ }
15305
+ do {
15306
+ if (!currentSource) {
15307
+ currentSource = this._sources[this._firstSourceId];
15308
+ } else {
15309
+ previousSource = currentSource;
15310
+ currentSource = this._sources[currentSource.nextSourceId];
15311
+ }
15312
+ if (currentSource) {
15313
+ if (currentSource.source.startTime > time) {
15314
+ if (previousSource) {
15315
+ this._cachedStartSourceForActive = previousSource.source;
15316
+ }
15317
+ break;
15318
+ }
15319
+ if (currentSource.source.startTime <= time && currentSource.source.endTime > time) {
15320
+ activeSource = currentSource.source;
15321
+ this._cachedStartSourceForActive = activeSource;
15322
+ break;
15323
+ }
15324
+ } else {
15325
+ break;
15326
+ }
15327
+ } while (currentSource.nextSourceId);
15328
+ return activeSource;
15329
+ };
15288
15330
  LineGroup.prototype.updatePosition = function (pos) {
15289
15331
  this._line.position = pos;
15290
15332
  this._position = pos;
@@ -15337,6 +15379,9 @@ module.exports = function (SegmentsGroup, LineGroup, LineIndicator, Utils) {
15337
15379
  this._peaks.on('segments.dragend', this._onSegmentUpdated.bind(this));
15338
15380
  this._peaks.on('lineIndicator.drag', this._onIndicatorDrag.bind(this));
15339
15381
  }
15382
+ LineGroups.prototype.getLineGroupsById = function () {
15383
+ return this._lineGroupsById;
15384
+ };
15340
15385
  LineGroups.prototype.fitToView = function () {
15341
15386
  this._lineIndicator.fitToView();
15342
15387
  };
@@ -16579,6 +16624,7 @@ module.exports = function (Utils, Konva) {
16579
16624
  this._time = null;
16580
16625
  this._playheadLayer = new Konva.Layer();
16581
16626
  this._activeSegments = {};
16627
+ this._activeSources = {};
16582
16628
  this._createPlayhead(this._playheadColor);
16583
16629
  if (showTime) {
16584
16630
  this._createPlayheadText(this._playheadTextColor);
@@ -16691,36 +16737,65 @@ module.exports = function (Utils, Konva) {
16691
16737
  this._syncPlayhead(time);
16692
16738
  };
16693
16739
  PlayheadLayer.prototype._syncPlayhead = function (time) {
16694
- var pixelIndex = this._view.timeToPixels(time);
16695
- var frameOffset = this._view.timeToPixels(this._view.getTimeOffset());
16740
+ if (this._time === time) {
16741
+ return;
16742
+ }
16743
+ this._time = time;
16744
+ this._updatePlayheadPixel(time);
16745
+ this._updateActiveSegmentsAndSources(time);
16746
+ this._updatePlayheadText(time);
16747
+ this._playheadLayer.batchDraw();
16748
+ };
16749
+ PlayheadLayer.prototype._updatePlayheadPixel = function (time) {
16750
+ const pixelIndex = this._view.timeToPixels(time);
16751
+ const frameOffset = this._view.timeToPixels(this._view.getTimeOffset());
16696
16752
  this._playheadPixel = pixelIndex;
16697
- var playheadX = this._playheadPixel - frameOffset;
16698
- var segmentsGroup = this._lines.getSegmentsGroups();
16753
+ const playheadX = this._playheadPixel - frameOffset;
16699
16754
  this._playheadGroup.setAttr('x', playheadX);
16700
- if (this._time !== time) {
16701
- for (var lineId in segmentsGroup) {
16702
- if (Utils.objectHasProperty(segmentsGroup, lineId)) {
16703
- var newActiveSegment = segmentsGroup[lineId].getActiveSegment(this._view.pixelsToTime(playheadX + frameOffset));
16704
- if (newActiveSegment !== this._activeSegments[lineId]) {
16705
- if (this._activeSegments[lineId]) {
16706
- this._peaks.emit('segments.exit', this._activeSegments[lineId]);
16707
- delete this._activeSegments[lineId];
16708
- }
16709
- if (newActiveSegment) {
16710
- this._peaks.emit('segments.enter', newActiveSegment);
16711
- this._activeSegments[lineId] = newActiveSegment;
16712
- }
16713
- }
16755
+ };
16756
+ PlayheadLayer.prototype._updateActiveSegmentsAndSources = function (time) {
16757
+ const lineGroups = this._lines.getLineGroupsById();
16758
+ for (var lineId in lineGroups) {
16759
+ if (Utils.objectHasProperty(lineGroups, lineId)) {
16760
+ const lineGroup = lineGroups[lineId];
16761
+ if (lineGroup.isSegmentsLine()) {
16762
+ this._updateActiveSegment(lineGroup.getSegmentsGroup(), lineId, time);
16763
+ } else {
16764
+ this._updateActiveSource(lineGroup, lineId, time);
16714
16765
  }
16715
16766
  }
16716
- if (this._playheadText) {
16717
- var text = Utils.formatTime(time, false);
16718
- this._playheadText.setText(text);
16719
- this._peaks.emit('playhead.moved', this._playheadText.getAbsolutePosition().x, this._playheadText.width());
16767
+ }
16768
+ };
16769
+ PlayheadLayer.prototype._updateActiveSegment = function (segmentsGroup, lineId, time) {
16770
+ const newActiveSegment = segmentsGroup.getActiveSegment(time);
16771
+ if (newActiveSegment !== this._activeSegments[lineId]) {
16772
+ if (this._activeSegments[lineId]) {
16773
+ this._peaks.emit('segments.exit', this._activeSegments[lineId]);
16774
+ delete this._activeSegments[lineId];
16775
+ }
16776
+ if (newActiveSegment) {
16777
+ this._peaks.emit('segments.enter', newActiveSegment);
16778
+ this._activeSegments[lineId] = newActiveSegment;
16720
16779
  }
16721
16780
  }
16722
- this._time = time;
16723
- this._playheadLayer.batchDraw();
16781
+ };
16782
+ PlayheadLayer.prototype._updateActiveSource = function (sourcesLineGroup, lineId, time) {
16783
+ const newActiveSource = sourcesLineGroup.getActiveSource(time);
16784
+ if (newActiveSource !== this._activeSources[lineId]) {
16785
+ if (this._activeSources[lineId]) {
16786
+ this._peaks.emit('sources.exit', this._activeSources[lineId]);
16787
+ delete this._activeSources[lineId];
16788
+ }
16789
+ if (newActiveSource) {
16790
+ this._peaks.emit('sources.enter', newActiveSource);
16791
+ this._activeSources[lineId] = newActiveSource;
16792
+ }
16793
+ }
16794
+ };
16795
+ PlayheadLayer.prototype._updatePlayheadText = function (time) {
16796
+ var text = Utils.formatTime(time, false);
16797
+ this._playheadText.setText(text);
16798
+ this._peaks.emit('playhead.moved', this._playheadText.getAbsolutePosition().x, this._playheadText.width());
16724
16799
  };
16725
16800
  PlayheadLayer.prototype.getPlayheadOffset = function () {
16726
16801
  return this._playheadPixel - this._view.getFrameOffset();
@@ -17210,6 +17285,7 @@ module.exports = function (SegmentShape, Utils, Konva) {
17210
17285
  this._firstSegmentId = null;
17211
17286
  this._segments = {};
17212
17287
  this._lastSegmentId = null;
17288
+ this._cachedStartSegmentForActive = null;
17213
17289
  this._segmentShapes = {};
17214
17290
  this._group = new Konva.Group();
17215
17291
  this._updatedSegments = [];
@@ -17253,27 +17329,40 @@ module.exports = function (SegmentShape, Utils, Konva) {
17253
17329
  };
17254
17330
  SegmentsGroup.prototype.getActiveSegment = function (time) {
17255
17331
  var activeSegment = null;
17332
+ var previousSegment = null;
17256
17333
  var currentSegment = null;
17257
- var nextSegmentId = null;
17334
+ if (this._cachedStartSegmentForActive) {
17335
+ if (this._cachedStartSegmentForActive.startTime <= time) {
17336
+ if (this._cachedStartSegmentForActive.endTime > time) {
17337
+ return this._cachedStartSegmentForActive;
17338
+ } else {
17339
+ currentSegment = this._segments[this._cachedStartSegmentForActive.id];
17340
+ }
17341
+ }
17342
+ }
17258
17343
  do {
17259
17344
  if (!currentSegment) {
17260
17345
  currentSegment = this._segments[this._firstSegmentId];
17261
17346
  } else {
17347
+ previousSegment = currentSegment;
17262
17348
  currentSegment = this._segments[currentSegment.nextSegmentId];
17263
17349
  }
17264
17350
  if (currentSegment) {
17265
17351
  if (currentSegment.segment.startTime > time) {
17352
+ if (previousSegment) {
17353
+ this._cachedStartSegmentForActive = previousSegment.segment;
17354
+ }
17266
17355
  break;
17267
17356
  }
17268
17357
  if (currentSegment.segment.startTime <= time && currentSegment.segment.endTime > time) {
17269
17358
  activeSegment = currentSegment.segment;
17359
+ this._cachedStartSegmentForActive = activeSegment;
17270
17360
  break;
17271
17361
  }
17272
17362
  } else {
17273
17363
  break;
17274
17364
  }
17275
- nextSegmentId = currentSegment.nextSegmentId;
17276
- } while (nextSegmentId);
17365
+ } while (currentSegment.nextSegmentId);
17277
17366
  return activeSegment;
17278
17367
  };
17279
17368
  SegmentsGroup.prototype.onSegmentsUpdate = function (segment) {
@@ -17752,6 +17841,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
17752
17841
  this._selected = this._source.selected;
17753
17842
  this._hovered = false;
17754
17843
  this._isDragged = false;
17844
+ this._destroyed = false;
17755
17845
  this._previewList = [];
17756
17846
  this._previewBuildQueue = new Set();
17757
17847
  this._markersGroup = this._createMarkers();
@@ -18336,6 +18426,9 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
18336
18426
  options.dataUri = content;
18337
18427
  }
18338
18428
  waveformBuilder.init(options, function (err, originalWaveformData) {
18429
+ if (self._destroyed) {
18430
+ return;
18431
+ }
18339
18432
  if (err) {
18340
18433
  throw err;
18341
18434
  }
@@ -19007,6 +19100,7 @@ module.exports = function (WaveformBuilder, WaveformShape, Loader, Utils, Konva)
19007
19100
  this._loader = null;
19008
19101
  }
19009
19102
  this._group.destroy();
19103
+ this._destroyed = true;
19010
19104
  };
19011
19105
  SourceGroup.getHeights = function (source, peaks) {
19012
19106
  var unwrappedHeight = source.binaryHeight && source.previewHeight ? source.binaryHeight + source.previewHeight : peaks.options.lineHeight;
@@ -19466,6 +19560,9 @@ module.exports = function (SourceGroup, LineGroups, DataRetriever, Invoker, Util
19466
19560
  SourcesLayer.prototype.getLineByPosition = function (pos) {
19467
19561
  return this._lineGroups.getLineByPosition(pos);
19468
19562
  };
19563
+ SourcesLayer.prototype.getLineGroups = function () {
19564
+ return this._lineGroups;
19565
+ };
19469
19566
  return SourcesLayer;
19470
19567
  }(_dereq_('./source-group'), _dereq_('./line-groups'), _dereq_('./data-retriever'), _dereq_('./invoker'), _dereq_('../utils'), _dereq_('konva'));
19471
19568
  },{"../utils":116,"./data-retriever":87,"./invoker":90,"./line-groups":92,"./source-group":102,"konva":43}],104:[function(_dereq_,module,exports){
@@ -22314,7 +22411,7 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
22314
22411
  self._sourcesLayer.addToStage(self._stage);
22315
22412
  self._sourcesLayer.add(self._tempGroup);
22316
22413
  self._axis.addFrontToStage(self._stage);
22317
- self._playheadLayer = new PlayheadLayer(peaks, self, self._sourcesLayer, self._options.showPlayheadTime);
22414
+ self._playheadLayer = new PlayheadLayer(peaks, self, self._sourcesLayer.getLineGroups(), self._options.showPlayheadTime);
22318
22415
  self._playheadLayer.addToStage(self._stage);
22319
22416
  var time = self._peaks.player.getCurrentTime();
22320
22417
  self._syncPlayhead(time);
@@ -23,6 +23,8 @@ define([
23
23
  this._firstSourceId = null;
24
24
  this._sources = {};
25
25
 
26
+ this._cachedStartSourceForActive = null;
27
+
26
28
  this._sourcesGroup = {};
27
29
  this._wrapped = false;
28
30
 
@@ -41,6 +43,10 @@ define([
41
43
  this._unwrappedCount = 0;
42
44
  }
43
45
 
46
+ LineGroup.prototype.getSegmentsGroup = function() {
47
+ return this._segmentsGroup;
48
+ };
49
+
44
50
  LineGroup.prototype.getPosition = function() {
45
51
  return this._position;
46
52
  };
@@ -672,6 +678,54 @@ define([
672
678
  }
673
679
  };
674
680
 
681
+ LineGroup.prototype.getActiveSource = function(time) {
682
+ var activeSource = null;
683
+ var previousSource = null;
684
+ var currentSource = null;
685
+
686
+ if (this._cachedStartSourceForActive) {
687
+ if (this._cachedStartSourceForActive.startTime <= time) {
688
+ if (this._cachedStartSourceForActive.endTime > time) {
689
+ return this._cachedStartSourceForActive;
690
+ }
691
+ else {
692
+ currentSource = this._sources[this._cachedStartSourceForActive.id];
693
+ }
694
+ }
695
+ }
696
+
697
+ do {
698
+ if (!currentSource) {
699
+ currentSource = this._sources[this._firstSourceId];
700
+ }
701
+ else {
702
+ previousSource = currentSource;
703
+ currentSource = this._sources[currentSource.nextSourceId];
704
+ }
705
+
706
+ if (currentSource) {
707
+ if (currentSource.source.startTime > time) {
708
+ // We didn't find an active source and will not in the remainings sources
709
+ if (previousSource) {
710
+ this._cachedStartSourceForActive = previousSource.source;
711
+ }
712
+ break;
713
+ }
714
+
715
+ if (currentSource.source.startTime <= time && currentSource.source.endTime > time) {
716
+ activeSource = currentSource.source;
717
+ this._cachedStartSourceForActive = activeSource;
718
+ break;
719
+ }
720
+ }
721
+ else {
722
+ break;
723
+ }
724
+ } while (currentSource.nextSourceId);
725
+
726
+ return activeSource;
727
+ };
728
+
675
729
  LineGroup.prototype.updatePosition = function(pos) {
676
730
  this._line.position = pos;
677
731
  this._position = pos;
@@ -65,6 +65,10 @@ define([
65
65
  this._peaks.on('lineIndicator.drag', this._onIndicatorDrag.bind(this));
66
66
  }
67
67
 
68
+ LineGroups.prototype.getLineGroupsById = function() {
69
+ return this._lineGroupsById;
70
+ };
71
+
68
72
  LineGroups.prototype.fitToView = function() {
69
73
  this._lineIndicator.fitToView();
70
74
  };
@@ -39,6 +39,7 @@ define([
39
39
  this._playheadLayer = new Konva.Layer();
40
40
 
41
41
  this._activeSegments = {};
42
+ this._activeSources = {};
42
43
 
43
44
  this._createPlayhead(this._playheadColor);
44
45
 
@@ -225,51 +226,113 @@ define([
225
226
  */
226
227
 
227
228
  PlayheadLayer.prototype._syncPlayhead = function(time) {
228
- var pixelIndex = this._view.timeToPixels(time);
229
- var frameOffset = this._view.timeToPixels(this._view.getTimeOffset());
229
+ if (this._time === time) {
230
+ return;
231
+ }
230
232
 
231
- this._playheadPixel = pixelIndex;
233
+ this._time = time;
234
+ this._updatePlayheadPixel(time);
235
+ this._updateActiveSegmentsAndSources(time);
236
+ this._updatePlayheadText(time);
237
+ this._playheadLayer.batchDraw();
238
+ };
232
239
 
233
- var playheadX = this._playheadPixel - frameOffset;
234
- var segmentsGroup = this._lines.getSegmentsGroups();
240
+ /**
241
+ * Update cached pixel values and position of the playhead group.
242
+ * @private
243
+ * @param {Number} time
244
+ * @returns {Number} playheadX localized to frame (without frameOffset)
245
+ */
246
+ PlayheadLayer.prototype._updatePlayheadPixel = function(time) {
247
+ const pixelIndex = this._view.timeToPixels(time);
248
+ const frameOffset = this._view.timeToPixels(this._view.getTimeOffset());
249
+
250
+ this._playheadPixel = pixelIndex;
251
+ const playheadX = this._playheadPixel - frameOffset;
235
252
 
236
253
  this._playheadGroup.setAttr('x', playheadX);
254
+ };
237
255
 
238
- if (this._time !== time) {
239
- for (var lineId in segmentsGroup) {
240
- if (Utils.objectHasProperty(segmentsGroup, lineId)) {
241
- var newActiveSegment = segmentsGroup[lineId].getActiveSegment(
242
- this._view.pixelsToTime(playheadX + frameOffset)
243
- );
244
-
245
- if (newActiveSegment !== this._activeSegments[lineId]) {
246
- if (this._activeSegments[lineId]) {
247
- this._peaks.emit('segments.exit', this._activeSegments[lineId]);
248
- delete this._activeSegments[lineId];
249
- }
250
- if (newActiveSegment) {
251
- this._peaks.emit('segments.enter', newActiveSegment);
252
- this._activeSegments[lineId] = newActiveSegment;
253
- }
254
- }
256
+ /**
257
+ * Compute and emit sources/segments enter/exit events.
258
+ * @private
259
+ * @param {Number} time
260
+ */
261
+ PlayheadLayer.prototype._updateActiveSegmentsAndSources = function(time) {
262
+ const lineGroups = this._lines.getLineGroupsById();
263
+
264
+ for (var lineId in lineGroups) {
265
+ if (Utils.objectHasProperty(lineGroups, lineId)) {
266
+ const lineGroup = lineGroups[lineId];
267
+
268
+ if (lineGroup.isSegmentsLine()) {
269
+ this._updateActiveSegment(lineGroup.getSegmentsGroup(), lineId, time);
270
+ }
271
+ else {
272
+ this._updateActiveSource(lineGroup, lineId, time);
255
273
  }
256
274
  }
275
+ }
276
+ };
257
277
 
258
- if (this._playheadText) {
259
- var text = Utils.formatTime(time, false);
278
+ /**
279
+ * Compute and emit segment enter/exit events for a specific segment group.
280
+ * @private
281
+ * @param {SegmentsGroup} segmentsGroup
282
+ * @param {Number} lineId
283
+ * @param {Number} time
284
+ */
285
+ PlayheadLayer.prototype._updateActiveSegment = function(segmentsGroup, lineId, time) {
286
+ const newActiveSegment = segmentsGroup.getActiveSegment(time);
260
287
 
261
- this._playheadText.setText(text);
288
+ if (newActiveSegment !== this._activeSegments[lineId]) {
289
+ if (this._activeSegments[lineId]) {
290
+ this._peaks.emit('segments.exit', this._activeSegments[lineId]);
291
+ delete this._activeSegments[lineId];
292
+ }
293
+ if (newActiveSegment) {
294
+ this._peaks.emit('segments.enter', newActiveSegment);
295
+ this._activeSegments[lineId] = newActiveSegment;
296
+ }
297
+ }
298
+ };
262
299
 
263
- this._peaks.emit(
264
- 'playhead.moved',
265
- this._playheadText.getAbsolutePosition().x,
266
- this._playheadText.width()
267
- );
300
+ /**
301
+ * Compute and emit source enter/exit events for a specific source line group.
302
+ * @private
303
+ * @param {LineGroup} sourcesLineGroup
304
+ * @param {Number} lineId
305
+ * @param {Number} time
306
+ */
307
+ PlayheadLayer.prototype._updateActiveSource = function(sourcesLineGroup, lineId, time) {
308
+ const newActiveSource = sourcesLineGroup.getActiveSource(time);
309
+
310
+ if (newActiveSource !== this._activeSources[lineId]) {
311
+ if (this._activeSources[lineId]) {
312
+ this._peaks.emit('sources.exit', this._activeSources[lineId]);
313
+ delete this._activeSources[lineId];
314
+ }
315
+ if (newActiveSource) {
316
+ this._peaks.emit('sources.enter', newActiveSource);
317
+ this._activeSources[lineId] = newActiveSource;
268
318
  }
269
319
  }
320
+ };
270
321
 
271
- this._time = time;
272
- this._playheadLayer.batchDraw();
322
+ /**
323
+ * Update the playhead time label and emit playhead.moved event.
324
+ * @private
325
+ * @param {Number} time
326
+ */
327
+ PlayheadLayer.prototype._updatePlayheadText = function(time) {
328
+ var text = Utils.formatTime(time, false);
329
+
330
+ this._playheadText.setText(text);
331
+ this._peaks.emit(
332
+ 'playhead.moved',
333
+ this._playheadText.getAbsolutePosition().x,
334
+ this._playheadText.width()
335
+ );
273
336
  };
274
337
 
275
338
  /**
@@ -37,6 +37,8 @@ define([
37
37
  this._segments = {};
38
38
  this._lastSegmentId = null;
39
39
 
40
+ this._cachedStartSegmentForActive = null;
41
+
40
42
  this._segmentShapes = {};
41
43
  this._group = new Konva.Group();
42
44
 
@@ -104,34 +106,48 @@ define([
104
106
 
105
107
  SegmentsGroup.prototype.getActiveSegment = function(time) {
106
108
  var activeSegment = null;
109
+ var previousSegment = null;
107
110
  var currentSegment = null;
108
- var nextSegmentId = null;
111
+
112
+ if (this._cachedStartSegmentForActive) {
113
+ if (this._cachedStartSegmentForActive.startTime <= time) {
114
+ if (this._cachedStartSegmentForActive.endTime > time) {
115
+ return this._cachedStartSegmentForActive;
116
+ }
117
+ else {
118
+ currentSegment = this._segments[this._cachedStartSegmentForActive.id];
119
+ }
120
+ }
121
+ }
109
122
 
110
123
  do {
111
124
  if (!currentSegment) {
112
125
  currentSegment = this._segments[this._firstSegmentId];
113
126
  }
114
127
  else {
128
+ previousSegment = currentSegment;
115
129
  currentSegment = this._segments[currentSegment.nextSegmentId];
116
130
  }
117
131
 
118
132
  if (currentSegment) {
119
133
  if (currentSegment.segment.startTime > time) {
120
134
  // We didn't find an active segment and will not in the remainings segments
135
+ if (previousSegment) {
136
+ this._cachedStartSegmentForActive = previousSegment.segment;
137
+ }
121
138
  break;
122
139
  }
123
140
 
124
141
  if (currentSegment.segment.startTime <= time && currentSegment.segment.endTime > time) {
125
142
  activeSegment = currentSegment.segment;
143
+ this._cachedStartSegmentForActive = activeSegment;
126
144
  break;
127
145
  }
128
146
  }
129
147
  else {
130
148
  break;
131
149
  }
132
-
133
- nextSegmentId = currentSegment.nextSegmentId;
134
- } while (nextSegmentId);
150
+ } while (currentSegment.nextSegmentId);
135
151
 
136
152
  return activeSegment;
137
153
  };
@@ -59,6 +59,7 @@ define([
59
59
  this._selected = this._source.selected;
60
60
  this._hovered = false;
61
61
  this._isDragged = false;
62
+ this._destroyed = false;
62
63
 
63
64
  this._previewList = [];
64
65
  // internal queue state for async preview creation
@@ -842,6 +843,10 @@ define([
842
843
  }
843
844
 
844
845
  waveformBuilder.init(options, function(err, originalWaveformData) {
846
+ if (self._destroyed) {
847
+ return;
848
+ }
849
+
845
850
  if (err) {
846
851
  throw err;
847
852
  }
@@ -1713,6 +1718,8 @@ define([
1713
1718
  }
1714
1719
 
1715
1720
  this._group.destroy();
1721
+
1722
+ this._destroyed = true;
1716
1723
  };
1717
1724
 
1718
1725
  /**
@@ -726,6 +726,10 @@ define([
726
726
  return this._lineGroups.getLineByPosition(pos);
727
727
  };
728
728
 
729
+ SourcesLayer.prototype.getLineGroups = function() {
730
+ return this._lineGroups;
731
+ };
732
+
729
733
  /**
730
734
  * Object for storing data and UI of a source.
731
735
  *
@@ -346,7 +346,7 @@ define([
346
346
  * @param {WaveformBuilderInitCallback} callback
347
347
  */
348
348
 
349
- WaveformBuilder.prototype._buildWaveformDataFromObjectUrl = function(options, callback) {
349
+ WaveformBuilder.prototype._buildWaveformDataFromObjectUrl = function(options, callback) {
350
350
  var self = this;
351
351
 
352
352
  var webAudioOptions = {
package/src/view.js CHANGED
@@ -140,7 +140,7 @@ define([
140
140
  self._playheadLayer = new PlayheadLayer(
141
141
  peaks,
142
142
  self,
143
- self._sourcesLayer,
143
+ self._sourcesLayer.getLineGroups(),
144
144
  self._options.showPlayheadTime
145
145
  );
146
146