@checksub_team/peaks_timeline 1.4.17
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/CHANGELOG.md +530 -0
- package/COPYING +165 -0
- package/README.md +1184 -0
- package/package.json +88 -0
- package/peaks.js +20174 -0
- package/peaks.js.d.ts +332 -0
- package/src/data-retriever.js +90 -0
- package/src/data.js +56 -0
- package/src/default-segment-marker.js +132 -0
- package/src/keyboard-handler.js +112 -0
- package/src/line-indicator.js +312 -0
- package/src/line.js +629 -0
- package/src/lines.js +356 -0
- package/src/main.js +663 -0
- package/src/marker-factories.js +91 -0
- package/src/mode-layer.js +361 -0
- package/src/mouse-drag-handler.js +207 -0
- package/src/player.js +178 -0
- package/src/playhead-layer.js +413 -0
- package/src/segment-marker.js +155 -0
- package/src/segment-shape.js +345 -0
- package/src/segment.js +229 -0
- package/src/segments-group.js +697 -0
- package/src/source-group.js +975 -0
- package/src/source.js +688 -0
- package/src/sources-layer.js +509 -0
- package/src/timeline-axis.js +238 -0
- package/src/timeline-segments.js +389 -0
- package/src/timeline-sources.js +431 -0
- package/src/timeline-zoomview.js +866 -0
- package/src/utils.js +339 -0
- package/src/waveform-builder.js +458 -0
- package/src/waveform-shape.js +223 -0
package/src/main.js
ADDED
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file
|
|
3
|
+
*
|
|
4
|
+
* Defines the {@link Peaks} class.
|
|
5
|
+
*
|
|
6
|
+
* @module main
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
define([
|
|
10
|
+
'colors.css',
|
|
11
|
+
'eventemitter2',
|
|
12
|
+
'./timeline-segments',
|
|
13
|
+
'./timeline-sources',
|
|
14
|
+
'./keyboard-handler',
|
|
15
|
+
'./player',
|
|
16
|
+
'./marker-factories',
|
|
17
|
+
'./timeline-zoomview',
|
|
18
|
+
'./utils'
|
|
19
|
+
], function(
|
|
20
|
+
Colors,
|
|
21
|
+
EventEmitter,
|
|
22
|
+
TimelineSegments,
|
|
23
|
+
TimelineSources,
|
|
24
|
+
KeyboardHandler,
|
|
25
|
+
Player,
|
|
26
|
+
MarkerFactories,
|
|
27
|
+
TimelineZoomView,
|
|
28
|
+
Utils) {
|
|
29
|
+
'use strict';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Initialises a new Peaks instance with default option settings.
|
|
33
|
+
*
|
|
34
|
+
* @class
|
|
35
|
+
* @alias Peaks
|
|
36
|
+
*
|
|
37
|
+
* @param {Object} opts Configuration options
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
function Peaks() {
|
|
41
|
+
EventEmitter.call(this, { wildcard: true });
|
|
42
|
+
|
|
43
|
+
this.options = {
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Array of scale factors (samples per pixel) for the zoom levels
|
|
47
|
+
* (big >> small)
|
|
48
|
+
*/
|
|
49
|
+
zoomRange: [5, 2000],
|
|
50
|
+
|
|
51
|
+
initialZoomLevel: 100,
|
|
52
|
+
|
|
53
|
+
minScale: 40,
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Data URI where to get the waveform data.
|
|
57
|
+
*
|
|
58
|
+
* If a string, we assume that `this.dataUriDefaultFormat` is the default
|
|
59
|
+
* `xhr.responseType` value.
|
|
60
|
+
*
|
|
61
|
+
* @since 0.0.1
|
|
62
|
+
*
|
|
63
|
+
* ```js
|
|
64
|
+
* dataUri: 'url/to/data.json?waveformId=1337'
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* If an object, each key is an `xhr.responseType` which will contain its
|
|
68
|
+
* associated source URI.
|
|
69
|
+
*
|
|
70
|
+
* @since 0.3.0
|
|
71
|
+
*
|
|
72
|
+
* ```js
|
|
73
|
+
* dataUri: {
|
|
74
|
+
* arraybuffer: 'url/to/data.dat',
|
|
75
|
+
* json: 'url/to/data.json'
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
dataUri: null,
|
|
80
|
+
|
|
81
|
+
objectUrl: null,
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Will be used as a `xhr.responseType` if `dataUri` is a string, and not
|
|
85
|
+
* an object. Here for backward compatibility purpose only.
|
|
86
|
+
*
|
|
87
|
+
* @since 0.3.0
|
|
88
|
+
*/
|
|
89
|
+
dataUriDefaultFormat: 'json',
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* If true, all ajax requests (e.g. to fetch waveform data) will be made
|
|
93
|
+
* with credentials (i.e. browser-controlled cookies).
|
|
94
|
+
*
|
|
95
|
+
* @type {Boolean}
|
|
96
|
+
*/
|
|
97
|
+
withCredentials: false,
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Will report errors to that function
|
|
101
|
+
*
|
|
102
|
+
* @type {Function=}
|
|
103
|
+
* @since 0.4.4
|
|
104
|
+
*/
|
|
105
|
+
logger: null,
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Deprecation messages logger.
|
|
109
|
+
*
|
|
110
|
+
* @type {Function}
|
|
111
|
+
* @since 0.4.8
|
|
112
|
+
*/
|
|
113
|
+
// eslint-disable-next-line no-console
|
|
114
|
+
deprecationLogger: console.log.bind(console),
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Bind keyboard controls
|
|
118
|
+
*/
|
|
119
|
+
keyboard: false,
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Keyboard nudge increment in seconds (left arrow/right arrow)
|
|
123
|
+
*/
|
|
124
|
+
nudgeIncrement: 1.0,
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Colour for the zoomed in waveform
|
|
128
|
+
*/
|
|
129
|
+
zoomWaveformColor: 'rgba(180, 180, 180, 1)',
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Random colour per segment (overrides segmentColor)
|
|
133
|
+
*/
|
|
134
|
+
randomizeSegmentColor: true,
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Block mouse clicks if a meta key is pressed
|
|
138
|
+
*/
|
|
139
|
+
blockUpdatingOnMouseClickWithMetaKey: false,
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Default height of the waveform canvases in pixels.
|
|
143
|
+
* The height of the canvas might grow depending on the number of line inside.
|
|
144
|
+
*/
|
|
145
|
+
height: 200,
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Colour for segments on the waveform
|
|
149
|
+
*/
|
|
150
|
+
segmentColor: Colors.orange,
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Colour of the play head
|
|
154
|
+
*/
|
|
155
|
+
playheadColor: Colors.red,
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Colour of the play head text
|
|
159
|
+
*/
|
|
160
|
+
playheadTextColor: Colors.red,
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Show current time position by the play head marker
|
|
164
|
+
* (zoom view only)
|
|
165
|
+
*/
|
|
166
|
+
showPlayheadTime: true,
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Show segment markers, allowing to resize a segment by dragging its handles
|
|
170
|
+
*/
|
|
171
|
+
showSegmentMarkers: true,
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Colour of the axis gridlines
|
|
175
|
+
*/
|
|
176
|
+
axisGridlineColor: '#ccc',
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Colour of the axis labels
|
|
180
|
+
*/
|
|
181
|
+
axisLabelColor: Colors.gray,
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
*
|
|
185
|
+
*/
|
|
186
|
+
template: [
|
|
187
|
+
'<div class="timeline">',
|
|
188
|
+
'<div class="zoom-container"></div>',
|
|
189
|
+
'</div>'
|
|
190
|
+
].join(''),
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* An object containing an AudioContext, used when creating waveform data
|
|
194
|
+
* using the Web Audio API
|
|
195
|
+
*/
|
|
196
|
+
|
|
197
|
+
webAudio: null,
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Point/Segment marker customisation.
|
|
201
|
+
*
|
|
202
|
+
* @todo This part of the API is not stable.
|
|
203
|
+
*/
|
|
204
|
+
createSegmentMarker: MarkerFactories.createSegmentMarker,
|
|
205
|
+
createSegmentLabel: MarkerFactories.createSegmentLabel,
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* External sources information.
|
|
209
|
+
*
|
|
210
|
+
* ```js
|
|
211
|
+
* sources: {
|
|
212
|
+
* id: 'unique-identifier-for-this-source',
|
|
213
|
+
* title: 'Source #1',
|
|
214
|
+
* url: 'https://my-website/my-resource.mp3',
|
|
215
|
+
* dataUri: {
|
|
216
|
+
* arraybuffer: 'url/to/data.dat',
|
|
217
|
+
* json: 'url/to/data.json'
|
|
218
|
+
* },
|
|
219
|
+
* start: 1.03,
|
|
220
|
+
* end: 5.06,
|
|
221
|
+
* color: #0000ff,
|
|
222
|
+
* wrapped: false, //show only a line or peaks/preview
|
|
223
|
+
* position: 0 //position in the timeline (here on the first line)
|
|
224
|
+
* }
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
sources: null,
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Height of a line, in pixels.
|
|
231
|
+
* This height will correspond to the height of the background when the element is unwrapped.
|
|
232
|
+
*/
|
|
233
|
+
lineHeight: 80,
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Ratio by which lineHeight must be multiplied to obtain the segment's line height.
|
|
237
|
+
*/
|
|
238
|
+
segmentHeight: 32,
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Height of a line, in pixels.
|
|
242
|
+
* This height will correspond to the height of the group
|
|
243
|
+
* containing the line and title of the wrapped source.
|
|
244
|
+
*/
|
|
245
|
+
wrappedLineHeight: 20,
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Height of an empty line, in pixels.
|
|
249
|
+
*/
|
|
250
|
+
emptyLineHeight: 10,
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Empty space between 2 sources, in pixels.
|
|
254
|
+
*/
|
|
255
|
+
interline: 10,
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Empty space before the first source and after the last source, in pixels.
|
|
259
|
+
*/
|
|
260
|
+
padding: 30,
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Horizontal empty space after the longest source, in pixels.
|
|
264
|
+
*/
|
|
265
|
+
horizontalPadding: 0,
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Threshold around a segment where the dragged segment is magnetized
|
|
269
|
+
* toward the former, in pixels.
|
|
270
|
+
*/
|
|
271
|
+
segmentMagnetThreshold: 15,
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Enable or disable the timeline vertical scrolling
|
|
275
|
+
*/
|
|
276
|
+
enableVerticalScrolling: true,
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Width of the left line indicator, in pixels
|
|
280
|
+
*/
|
|
281
|
+
lineIndicatorWidth: 20,
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Color of the line indicators
|
|
285
|
+
*/
|
|
286
|
+
lineIndicatorColor: 'gray',
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Color for the indicator when selected
|
|
290
|
+
*/
|
|
291
|
+
lineIndicatorSelected: '#ccc',
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Threshold size on the left and right border of the view,
|
|
295
|
+
* where auto scrolling is activated, between 0 and 1.
|
|
296
|
+
*/
|
|
297
|
+
autoScrollThreshold: 0.05,
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Indicates whether or not the context menu should be displayed
|
|
301
|
+
* on right click in the line indicator.
|
|
302
|
+
*/
|
|
303
|
+
enableLineIndicatorContextMenu: true,
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* The minimal size of a source, in seconds
|
|
307
|
+
*/
|
|
308
|
+
minSourceSize: 0.05,
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* The minimal size of a segment, in seconds
|
|
312
|
+
*/
|
|
313
|
+
minSegmentSize: 0.2
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Asynchronous errors logger.
|
|
318
|
+
*
|
|
319
|
+
* @type {Function}
|
|
320
|
+
*/
|
|
321
|
+
// eslint-disable-next-line no-console
|
|
322
|
+
this.logger = console.error.bind(console);
|
|
323
|
+
|
|
324
|
+
return this;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
Peaks.prototype = Object.create(EventEmitter.prototype);
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Creates and initialises a new Peaks instance with the given options.
|
|
331
|
+
*
|
|
332
|
+
* @param {Object} opts Configuration options
|
|
333
|
+
*
|
|
334
|
+
* @return {Peaks}
|
|
335
|
+
*/
|
|
336
|
+
|
|
337
|
+
Peaks.init = function(opts, callback) {
|
|
338
|
+
var instance = new Peaks();
|
|
339
|
+
|
|
340
|
+
opts = opts || {};
|
|
341
|
+
|
|
342
|
+
var err = instance._setOptions(opts);
|
|
343
|
+
|
|
344
|
+
if (err) {
|
|
345
|
+
callback(err);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/*
|
|
350
|
+
Setup the fonts
|
|
351
|
+
*/
|
|
352
|
+
/* eslint-disable max-len */
|
|
353
|
+
var fonts = [
|
|
354
|
+
'https://fonts.gstatic.com/s/opensans/v27/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4kaVIGxA.woff2',
|
|
355
|
+
'https://fonts.gstatic.com/s/opensans/v27/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4jaVIGxA.woff2',
|
|
356
|
+
'https://fonts.gstatic.com/s/opensans/v27/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4iaVIGxA.woff2',
|
|
357
|
+
'https://fonts.gstatic.com/s/opensans/v27/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4vaVIGxA.woff2',
|
|
358
|
+
'https://fonts.gstatic.com/s/opensans/v27/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0B4gaVI.woff2'
|
|
359
|
+
];
|
|
360
|
+
/* eslint-enable max-len */
|
|
361
|
+
|
|
362
|
+
fonts.forEach(function(fontUrl) {
|
|
363
|
+
var fontFace = new FontFace(
|
|
364
|
+
'Open Sans',
|
|
365
|
+
'url(' + fontUrl + ')'
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
document.fonts.add(fontFace);
|
|
369
|
+
fontFace.load();
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
/*
|
|
373
|
+
Setup the layout
|
|
374
|
+
*/
|
|
375
|
+
if (!instance.options.containers) {
|
|
376
|
+
callback(new TypeError('Peaks.init(): The containers option must be a valid DOM object'));
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
var zoomviewContainer = instance.options.containers.zoomview;
|
|
381
|
+
|
|
382
|
+
if (!Utils.isHTMLElement(zoomviewContainer)) {
|
|
383
|
+
// eslint-disable-next-line max-len
|
|
384
|
+
callback(new TypeError('Peaks.init(): The containers options must be valid HTML elements'));
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if (zoomviewContainer && zoomviewContainer.clientWidth <= 0) {
|
|
389
|
+
// eslint-disable-next-line max-len
|
|
390
|
+
callback(new TypeError('Peaks.init(): Please ensure that the container is visible and has non-zero width'));
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (instance.options.keyboard) {
|
|
395
|
+
instance.keyboardHandler = new KeyboardHandler(instance);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
instance.player = new Player(instance);
|
|
399
|
+
instance.segments = new TimelineSegments(instance);
|
|
400
|
+
instance.sources = new TimelineSources(instance);
|
|
401
|
+
|
|
402
|
+
// Setup the UI components
|
|
403
|
+
instance.view = new TimelineZoomView(
|
|
404
|
+
zoomviewContainer,
|
|
405
|
+
instance
|
|
406
|
+
);
|
|
407
|
+
|
|
408
|
+
instance._addWindowResizeHandler();
|
|
409
|
+
|
|
410
|
+
if (instance.options.sources) {
|
|
411
|
+
instance.sources.add(instance.options.sources);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
document.fonts.ready.then(function() {
|
|
415
|
+
setTimeout(function() {
|
|
416
|
+
instance.emit('peaks.ready');
|
|
417
|
+
}, 0);
|
|
418
|
+
|
|
419
|
+
if (callback) {
|
|
420
|
+
callback(null, instance);
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
return instance;
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
Peaks.prototype._setOptions = function(opts) {
|
|
427
|
+
// eslint-disable-next-line no-console
|
|
428
|
+
opts.deprecationLogger = opts.deprecationLogger || console.log.bind(console);
|
|
429
|
+
|
|
430
|
+
if (opts.overviewHighlightRectangleColor) {
|
|
431
|
+
opts.overviewHighlightColor = opts.overviewHighlightRectangleColor;
|
|
432
|
+
// eslint-disable-next-line max-len
|
|
433
|
+
opts.deprecationLogger('Peaks.init(): The overviewHighlightRectangleColor option is deprecated, please use overviewHighlightColor instead');
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (opts.inMarkerColor) {
|
|
437
|
+
opts.segmentStartMarkerColor = opts.inMarkerColor;
|
|
438
|
+
// eslint-disable-next-line max-len
|
|
439
|
+
opts.deprecationLogger('Peaks.init(): The inMarkerColor option is deprecated, please use segmentStartMarkerColor instead');
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (opts.outMarkerColor) {
|
|
443
|
+
opts.segmentEndMarkerColor = opts.outMarkerColor;
|
|
444
|
+
// eslint-disable-next-line max-len
|
|
445
|
+
opts.deprecationLogger('Peaks.init(): The outMarkerColor option is deprecated, please use segmentEndMarkerColor instead');
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
if (!opts.container && !opts.containers) {
|
|
449
|
+
// eslint-disable-next-line max-len
|
|
450
|
+
return new Error('Peaks.init(): Please specify either a container or containers option');
|
|
451
|
+
}
|
|
452
|
+
else if (Boolean(opts.container) === Boolean(opts.containers)) {
|
|
453
|
+
// eslint-disable-next-line max-len
|
|
454
|
+
return new Error('Peaks.init(): Please specify either a container or containers option, but not both');
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (opts.template && opts.containers) {
|
|
458
|
+
// eslint-disable-next-line max-len
|
|
459
|
+
return new Error('Peaks.init(): Please specify either a template or a containers option, but not both');
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// The 'containers' option overrides 'template'.
|
|
463
|
+
if (opts.containers) {
|
|
464
|
+
opts.template = null;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (opts.logger && !Utils.isFunction(opts.logger)) {
|
|
468
|
+
// eslint-disable-next-line max-len
|
|
469
|
+
return new TypeError('Peaks.init(): The logger option should be a function');
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
if (opts.segments && !Array.isArray(opts.segments)) {
|
|
473
|
+
// eslint-disable-next-line max-len
|
|
474
|
+
return new TypeError('Peaks.init(): options.segments must be an array of segment objects');
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (opts.points && !Array.isArray(opts.points)) {
|
|
478
|
+
// eslint-disable-next-line max-len
|
|
479
|
+
return new TypeError('Peaks.init(): options.points must be an array of point objects');
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
Utils.extend(this.options, opts);
|
|
483
|
+
|
|
484
|
+
if (!Array.isArray(this.options.zoomRange)) {
|
|
485
|
+
return new TypeError('Peaks.init(): The zoomRange option should be an array');
|
|
486
|
+
}
|
|
487
|
+
else if (this.options.zoomRange.length === 0) {
|
|
488
|
+
return new Error('Peaks.init(): The zoomRange array must not be empty');
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
if (!Utils.isInAscendingOrder(this.options.zoomRange)) {
|
|
492
|
+
return new Error('Peaks.init(): The zoomRange array must be sorted in ascending order');
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
if (opts.logger) {
|
|
497
|
+
this.logger = opts.logger;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return null;
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Remote waveform data options for [Peaks.setSource]{@link Peaks#setSource}.
|
|
505
|
+
*
|
|
506
|
+
* @typedef {Object} RemoteWaveformDataOptions
|
|
507
|
+
* @global
|
|
508
|
+
* @property {String=} arraybuffer
|
|
509
|
+
* @property {String=} json
|
|
510
|
+
*/
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Local waveform data options for [Peaks.setSource]{@link Peaks#setSource}.
|
|
514
|
+
*
|
|
515
|
+
* @typedef {Object} LocalWaveformDataOptions
|
|
516
|
+
* @global
|
|
517
|
+
* @property {ArrayBuffer=} arraybuffer
|
|
518
|
+
* @property {Object=} json
|
|
519
|
+
*/
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Web Audio options for [Peaks.setSource]{@link Peaks#setSource}.
|
|
523
|
+
*
|
|
524
|
+
* @typedef {Object} WebAudioOptions
|
|
525
|
+
* @global
|
|
526
|
+
* @property {AudioContext} audioContext
|
|
527
|
+
* @property {AudioBuffer=} audioBuffer
|
|
528
|
+
* @property {Boolean=} multiChannel
|
|
529
|
+
*/
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Options for [Peaks.setSource]{@link Peaks#setSource}.
|
|
533
|
+
*
|
|
534
|
+
* @typedef {Object} PeaksSetSourceOptions
|
|
535
|
+
* @global
|
|
536
|
+
* @property {String} mediaUrl
|
|
537
|
+
* @property {RemoteWaveformDataOptions=} dataUri
|
|
538
|
+
* @property {LocalWaveformDataOptions=} waveformData
|
|
539
|
+
* @property {WebAudioOptions=} webAudio
|
|
540
|
+
* @property {Boolean=} withCredentials
|
|
541
|
+
* @property {Array<Number>=} zoomRange
|
|
542
|
+
*/
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Source for [Peaks.setSource]{@link Peaks#setSource}.
|
|
546
|
+
*
|
|
547
|
+
* @typedef {Object} RemoteWaveformDataOptions
|
|
548
|
+
* @global
|
|
549
|
+
* @property {String=} arraybuffer
|
|
550
|
+
* @property {String=} json
|
|
551
|
+
*/
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Add a new source to the {@link Peaks} instance.
|
|
555
|
+
*
|
|
556
|
+
* @param {Object} source
|
|
557
|
+
*/
|
|
558
|
+
|
|
559
|
+
Peaks.prototype.addSource = function(source) {
|
|
560
|
+
this.sources.add(source);
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Destroy a source from the {@link Peaks} instance.
|
|
565
|
+
*
|
|
566
|
+
* @param {String} sourceId
|
|
567
|
+
*/
|
|
568
|
+
|
|
569
|
+
Peaks.prototype.destroySource = function(sourceId) {
|
|
570
|
+
this.sources.destroyById(sourceId);
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Show a source from the {@link Peaks} instance.
|
|
575
|
+
*
|
|
576
|
+
* @param {String} sourceId
|
|
577
|
+
*/
|
|
578
|
+
|
|
579
|
+
Peaks.prototype.showSource = function(sourceId) {
|
|
580
|
+
this.sources.showById(sourceId);
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Hide a source from the {@link Peaks} instance.
|
|
585
|
+
*
|
|
586
|
+
* @param {String} sourceId
|
|
587
|
+
*/
|
|
588
|
+
|
|
589
|
+
Peaks.prototype.hideSource = function(sourceId) {
|
|
590
|
+
this.sources.hideById(sourceId);
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
Peaks.prototype.showSegments = function(position) {
|
|
594
|
+
this.segments.addSegmentsToPosition(position);
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
Peaks.prototype.setDefaultMode = function() {
|
|
598
|
+
this.emit('default_mode');
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
Peaks.prototype.setCutMode = function() {
|
|
602
|
+
this.emit('cut_mode');
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
Peaks.prototype.getVisibleSegments = function() {
|
|
606
|
+
return this.view
|
|
607
|
+
.getSegmentsGroup()
|
|
608
|
+
.getVisibleSegments();
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
Peaks.prototype.getDuration = function() {
|
|
612
|
+
return this.view.pixelsToTime(this.view.getTimelineLength());
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
Peaks.prototype.overrideInteractions = function(bool, areInteractionsAllowed) {
|
|
616
|
+
return this.view
|
|
617
|
+
.overrideInteractions(bool, areInteractionsAllowed);
|
|
618
|
+
};
|
|
619
|
+
|
|
620
|
+
Peaks.prototype.allowInteractions = function(forSources, forSegments) {
|
|
621
|
+
return this.view
|
|
622
|
+
.allowInteractions(forSources, forSegments);
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
Peaks.prototype._addWindowResizeHandler = function() {
|
|
626
|
+
this._onResize = this._onResize.bind(this);
|
|
627
|
+
window.addEventListener('resize', this._onResize);
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
Peaks.prototype._onResize = function() {
|
|
631
|
+
this.emit('window_resize');
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
Peaks.prototype._removeWindowResizeHandler = function() {
|
|
635
|
+
window.removeEventListener('resize', this._onResize);
|
|
636
|
+
};
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* Cleans up a Peaks instance after use.
|
|
640
|
+
*/
|
|
641
|
+
|
|
642
|
+
Peaks.prototype.destroy = function() {
|
|
643
|
+
this._removeWindowResizeHandler();
|
|
644
|
+
|
|
645
|
+
if (this.keyboardHandler) {
|
|
646
|
+
this.keyboardHandler.destroy();
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
if (this.view) {
|
|
650
|
+
this.view.destroy();
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
if (this.player) {
|
|
654
|
+
this.player.destroy();
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
if (this._cueEmitter) {
|
|
658
|
+
this._cueEmitter.destroy();
|
|
659
|
+
}
|
|
660
|
+
};
|
|
661
|
+
|
|
662
|
+
return Peaks;
|
|
663
|
+
});
|