@checksub_team/peaks_timeline
Version:
JavaScript UI component for displaying audio waveforms
1,375 lines (1,242 loc) • 42.4 kB
JavaScript
/**
* @file
*
* Defines the {@link source} class.
*
* @module source
*/
define([
'../source-keys',
'../utils'
], function(SourceKeys, Utils) {
'use strict';
// Keys that belong to the Source API / options bag.
// Any other user-provided keys are treated as metadata fields and preserved
// as enumerable own-properties on the Source instance.
var RESERVED_SOURCE_KEYS = SourceKeys;
function validateSource(peaks, options, context) {
if (!Utils.isValidTime(options.startTime)) {
throw new TypeError('peaks.sources.' + context + ': startTime should be a valid number');
}
if (!Utils.isValidTime(options.endTime)) {
throw new TypeError('peaks.sources.' + context + ': endTime should be a valid number');
}
if (!Utils.isValidTime(options.duration) || options.duration <= 0) {
options.duration = 0;
}
else if (options.duration < peaks.options.minSourceSize) {
options.duration = peaks.options.minSourceSize;
}
options.duration = Utils.roundTime(options.duration);
if (options.startTime < 0) {
throw new RangeError('peaks.sources.' + context + ': startTime should be positive');
}
if (options.endTime < 0) {
throw new RangeError('peaks.sources.' + context + ': endTime should be positive');
}
if (options.endTime <= options.startTime) {
throw new RangeError(
'peaks.sources.' + context + ': endTime should be greater than startTime'
);
}
if (options.endTime - options.startTime < peaks.options.minSourceSize) {
options.endTime = options.startTime + peaks.options.minSourceSize;
}
if (!Utils.isValidTime(options.mediaStartTime) || options.mediaStartTime < 0) {
options.mediaStartTime = 0;
}
if (!Utils.isValidTime(options.mediaEndTime)
|| (options.mediaEndTime < options.mediaStartTime)
|| (options.mediaEndTime - options.mediaStartTime !== options.endTime - options.startTime)) {
options.mediaEndTime = options.mediaStartTime + (options.endTime - options.startTime);
}
if (options.duration && options.mediaEndTime > options.duration) {
var timeWidth = options.mediaEndTime - options.mediaStartTime;
options.mediaEndTime = options.duration;
if (options.duration > timeWidth) {
options.mediaStartTime = options.mediaEndTime - timeWidth;
options.endTime = options.startTime + timeWidth;
}
else {
options.mediaStartTime = 0;
options.endTime = options.startTime + options.duration;
}
}
options.startTime = Utils.roundTime(options.startTime);
options.endTime = Utils.roundTime(options.endTime);
options.mediaStartTime = Utils.roundTime(options.mediaStartTime);
options.mediaEndTime = Utils.roundTime(options.mediaEndTime);
if (Utils.isNullOrUndefined(options.title)) {
options.title = '';
}
else if (!Utils.isString(options.title)) {
throw new TypeError('peaks.sources.' + context + ': title must be a string');
}
if (Utils.isNullOrUndefined(options.titleAlignments)) {
options.titleAlignments = [];
}
else if (!Array.isArray(options.titleAlignments)) {
throw new TypeError('peaks.sources.' + context + ': titleAlignments must be an array');
}
if (Utils.isNullOrUndefined(options.url)) {
options.url = '';
}
else if (!Utils.isString(options.url)) {
throw new TypeError('peaks.sources.' + context + ': url must be a string');
}
if (Utils.isNullOrUndefined(options.previewUrl)) {
options.previewUrl = '';
}
else if (!Utils.isString(options.previewUrl)) {
throw new TypeError('peaks.sources.' + context + ': previewUrl must be a string');
}
if (Utils.isNullOrUndefined(options.binaryUrl)) {
options.binaryUrl = '';
}
else if (!Utils.isString(options.binaryUrl)) {
throw new TypeError('peaks.sources.' + context + ': binaryUrl must be a string');
}
if (!Utils.isValidColor(options.color)) {
options.color = peaks.options.zoomWaveformColor;
}
if (!Utils.isValidColor(options.backgroundColor)) {
throw new TypeError(
'peaks.sources.' + context + ': backgroundColor should be a valid CSS color'
);
}
if (Utils.isNullOrUndefined(options.selectedBackgroundColor)) {
options.selectedBackgroundColor = options.backgroundColor;
}
else if (!Utils.isValidColor(options.selectedBackgroundColor)) {
throw new TypeError(
'peaks.sources.' + context + ': selectedBackgroundColor should be a valid CSS color'
);
}
if (Utils.isNullOrUndefined(options.hoverBackgroundColor)) {
options.hoverBackgroundColor = Utils.shadeColor(options.backgroundColor, 30);
}
else if (!Utils.isValidColor(options.hoverBackgroundColor)) {
throw new TypeError(
'peaks.sources.' + context + ': hoverBackgroundColor should be a valid CSS color'
);
}
if (Utils.isNullOrUndefined(options.borderColor)) {
options.borderColor = options.color;
}
else if (!Utils.isValidColor(options.borderColor)) {
throw new TypeError(
'peaks.sources.' + context + ': borderColor should be a valid CSS color'
);
}
if (Utils.isNullOrUndefined(options.selectedBorderColor)) {
options.selectedBorderColor = Utils.shadeColor(options.borderColor, 30);
}
else if (!Utils.isValidColor(options.selectedBorderColor)) {
throw new TypeError(
'peaks.sources.' + context + ': selectedBorderColor should be a valid CSS color'
);
}
if (Utils.isNullOrUndefined(options.warningColor)) {
options.warningColor = null;
}
else if (!Utils.isValidColor(options.warningColor)) {
throw new TypeError(
'peaks.sources.' + context + ': warningColor should be a valid CSS color'
);
}
if (Utils.isNullOrUndefined(options.warningWidth)) {
options.warningWidth = 10;
}
else if (!Utils.isNumber(options.warningWidth)) {
throw new TypeError('peaks.sources.' + context + ': warningWidth should be a number');
}
if (Utils.isNullOrUndefined(options.volumeSliderColor)) {
options.volumeSliderColor = '#000000';
}
else if (!Utils.isValidColor(options.volumeSliderColor)) {
throw new TypeError(
'peaks.sources.' + context + ': volumeSliderColor should be a valid CSS color'
);
}
if (Utils.isNullOrUndefined(options.volumeSliderWidth)) {
options.volumeSliderWidth = 2;
}
else if (!Utils.isNumber(options.volumeSliderWidth)) {
throw new TypeError('peaks.sources.' + context + ': volumeSliderWidth should be a number');
}
if (Utils.isNullOrUndefined(options.volumeSliderDraggingWidth)) {
options.volumeSliderDraggingWidth = options.volumeSliderWidth;
}
else if (!Utils.isNumber(options.volumeSliderDraggingWidth)) {
throw new TypeError(
'peaks.sources.' + context + ': volumeSliderDraggingWidth should be a number'
);
}
if (Utils.isNullOrUndefined(options.textFont)) {
options.textFont = 'Arial';
}
if (Utils.isNullOrUndefined(options.textFontSize)) {
options.textFontSize = 12;
}
if (Utils.isNullOrUndefined(options.textColor)) {
options.textColor = '#000000';
}
else if (!Utils.isValidColor(options.textColor)) {
throw new TypeError('peaks.sources.' + context + ': textColor should be a valid CSS color');
}
if (!Utils.isNullOrUndefined(options.textBackgroundColor)
&& !Utils.isValidColor(options.textBackgroundColor)) {
throw new TypeError(
'peaks.sources.' + context + ': textBackgroundColor should be a valid CSS color'
);
}
if (Utils.isNullOrUndefined(options.textPosition)) {
options.textPosition = 'bottom';
}
else if (!Utils.isString(options.textPosition)) {
throw new TypeError('peaks.sources.' + context + ': textPosition must be a string');
}
if (Utils.isNullOrUndefined(options.textAutoScroll)) {
options.textAutoScroll = false;
}
if (Utils.isNullOrUndefined(options.borderWidth)) {
options.borderWidth = 0;
}
if (Utils.isNullOrUndefined(options.wrapped)) {
options.wrapped = false;
}
else if (!Utils.isBoolean(options.wrapped)) {
throw new TypeError('peaks.sources.' + context + ': wrapped must be a boolean');
}
if (Utils.isNullOrUndefined(options.draggable)) {
options.draggable = true;
}
else if (!Utils.isBoolean(options.draggable)) {
throw new TypeError('peaks.sources.' + context + ': draggable must be a boolean');
}
if (Utils.isNullOrUndefined(options.orderable)) {
options.orderable = true;
}
else if (!Utils.isBoolean(options.orderable)) {
throw new TypeError('peaks.sources.' + context + ': orderable must be a boolean');
}
if (Utils.isNullOrUndefined(options.resizable)) {
options.resizable = true;
}
else if (!Utils.isBoolean(options.resizable)) {
throw new TypeError('peaks.sources.' + context + ': resizable must be a boolean');
}
if (Utils.isNullOrUndefined(options.cuttable)) {
options.cuttable = true;
}
else if (!Utils.isBoolean(options.cuttable)) {
throw new TypeError('peaks.sources.' + context + ': cuttable must be a boolean');
}
if (Utils.isNullOrUndefined(options.deletable)) {
options.deletable = true;
}
else if (!Utils.isBoolean(options.deletable)) {
throw new TypeError('peaks.sources.' + context + ': deletable must be a boolean');
}
if (Utils.isNullOrUndefined(options.wrapping)) {
options.wrapping = 'both';
}
else if (!Utils.isString(options.wrapping)) {
throw new TypeError('peaks.sources.' + context + ': wrapping must be a string');
}
if (Utils.isNullOrUndefined(options.previewHeight)) {
options.previewHeight = 0;
}
else if (!Utils.isNumber(options.previewHeight)) {
throw new TypeError('peaks.sources.' + context + ': previewHeight must be a number');
}
if (Utils.isNullOrUndefined(options.binaryHeight)) {
options.binaryHeight = 0;
}
else if (!Utils.isNumber(options.binaryHeight)) {
throw new TypeError('peaks.sources.' + context + ': binaryHeight must be a number');
}
// Treat waveformData as a waveform source, similar to binaryUrl.
var hasWaveformData = !Utils.isNullOrUndefined(options.waveformData);
var hasWaveformArea = Boolean(options.binaryUrl) || hasWaveformData;
if (options.previewUrl && !options.previewHeight) {
if (hasWaveformArea) {
if (options.binaryHeight) {
options.previewHeight = Math.max(peaks.options.lineHeight - options.binaryHeight, 0);
}
else {
options.previewHeight = peaks.options.lineHeight / 2;
}
}
else {
// If only a preview is shown, default it to the full available height.
options.previewHeight = peaks.options.lineHeight;
}
}
if (hasWaveformArea && !options.binaryHeight) {
options.binaryHeight = Math.max(peaks.options.lineHeight - options.previewHeight, 0);
}
if (options.wrapping === 'reduced') {
options.wrapped = true;
}
else if (options.wrapping === 'complete') {
options.wrapped = false;
}
if (Utils.isNullOrUndefined(options.indicators)) {
options.indicators = [];
}
if (Utils.isNullOrUndefined(options.markers)) {
options.markers = [];
}
if (Utils.isNullOrUndefined(options.buttons)) {
options.buttons = [];
}
else if (!Array.isArray(options.buttons)) {
throw new TypeError('peaks.sources.' + context + ': buttons must be an array');
}
if (Utils.isNullOrUndefined(options.markerColor)
|| !Utils.isValidColor(options.markerColor)) {
options.markerColor = options.color;
}
if (Utils.isNullOrUndefined(options.markerWidth)) {
options.markerWidth = 2;
}
if (!Utils.isNullOrUndefined(options.volumeRange)) {
if (!Array.isArray(options.volumeRange)
|| options.volumeRange.length !== 2
|| !options.volumeRange.every(Utils.isNumber)) {
throw new TypeError('peaks.sources.' + context + ': volumeRange must be an array of two numbers');
}
else if (options.volumeRange[0] > options.volumeRange[1]) {
throw new RangeError('peaks.sources.' + context + ': volumeRange[0] should be less than volumeRange[1]');
}
}
if (!Utils.isNullOrUndefined(options.volume)) {
if (!Utils.isNumber(options.volume)) {
throw new TypeError('peaks.sources.' + context + ': volume must be a number');
}
else {
options.volume = Utils.clamp(options.volume, options.volumeRange[0], options.volumeRange[1]);
}
}
if (Utils.isNullOrUndefined(options.loading)) {
options.loading = false;
}
else if (!Utils.isBoolean(options.loading)) {
throw new TypeError('peaks.sources.' + context + ': loading must be a boolean');
}
if (Utils.isNullOrUndefined(options.targetSpeed)) {
options.targetSpeed = 1.0;
}
else if (!Utils.isNumber(options.targetSpeed) || options.targetSpeed <= 0) {
throw new TypeError('peaks.sources.' + context + ': targetSpeed must be a positive number');
}
}
/**
* A source is an external media resource, represented on the timeline.
*
* @class
* @alias Source
*
* @param {Peaks} peaks A reference to the Peaks instance.
* @param {String} id A unique identifier for the source.
* @param {String} lineId The identifier of the line this source belongs to.
* @param {String} originId The original identifier of the source before any cuts.
* @param {String} elementId The HTML element identifier associated with this source.
* @param {String} title Name of the source.
* @param {Array<Object>} titleAlignments Array of objects with structure:
* [{text: String, start: Number, end: Number}, ...]
* @param {String} url Reference to the media element this source is representing.
* @param {String} previewUrl URL for preview media content.
* @param {String} binaryUrl URL for binary data associated with the source.
* @param {String} kind Type/category of the source.
* @param {String} subkind Sub-category of the source.
* @param {Number} duration Total duration of the source media, in seconds.
* @param {Number} startTime Source start time on the timeline, in seconds.
* @param {Number} endTime Source end time on the timeline, in seconds.
* @param {Number} mediaStartTime Start time within the source media, in seconds.
* @param {Number} mediaEndTime End time within the source media, in seconds.
* @param {String} color Primary color of the source representation.
* @param {String} backgroundColor Background color of the source.
* @param {String} borderColor Border color of the source.
* @param {String} selectedBorderColor Color when the source is selected.
* @param {String} warningColor Color used for warning states.
* @param {String} volumeSliderColor Color of the volume slider.
* @param {Number} volumeSliderWidth Width of the volume slider.
* @param {Number} volumeSliderDraggingWidth Width of the volume slider when dragging.
* @param {String} textFont Font family for text display.
* @param {Number} textFontSize Font size for text display.
* @param {String} textColor Color of the text.
* @param {String} textBackgroundColor Background color of the text.
* @param {String} textPosition Position of text relative to the source.
* @param {Boolean} textAutoScroll If <code>true</code> text will auto-scroll.
* @param {Number} borderWidth Width of the source border.
* @param {Number} borderRadius Radius for rounded corners.
* @param {Boolean} wrapped If <code>true</code> the source representation will be smaller.
* @param {Boolean} draggable If <code>true</code> the source can be dragged.
* @param {Boolean} orderable If <code>true</code> the source can be reordered.
* @param {Boolean} resizable If <code>true</code> the source can be resized.
* @param {Boolean} cuttable If <code>true</code> the source can be cut.
* @param {Boolean} deletable If <code>true</code> the source can be deleted.
* @param {String} wrapping Wrapping mode for the source display.
* @param {Number} previewHeight Height of the preview area.
* @param {Number} binaryHeight Height of the binary data visualization.
* @param {Array} indicators Array containing indicator data for the source.
* @param {Array} markers Array containing marker data for the source.
* @param {Array} buttons Array containing button data for the source.
* @param {String} markerColor Color of the markers.
* @param {Number} markerWidth Width of the markers.
* @param {Number} volume Current volume level of the source.
* @param {Array<Number>} volumeRange Array containing min and max volume values.
* @param {Boolean} loading If <code>true</code> the source is currently loading.
* @param {Number} targetSpeed The playback speed multiplier for the source (default 1.0).
* Values > 1.0 speed up playback (compress waveform), values < 1.0 slow down (expand waveform).
*/
function Source(peaks, id, lineId, originId, elementId, title, titleAlignments, url, previewUrl, binaryUrl, kind,
subkind, duration, startTime, endTime, mediaStartTime, mediaEndTime, color, backgroundColor, hoverBackgroundColor,
selectedBackgroundColor, borderColor, selectedBorderColor, warningColor, warningWidth, volumeSliderColor,
volumeSliderWidth, volumeSliderDraggingWidth, textFont, textFontSize, textColor, textBackgroundColor, textPosition,
textAutoScroll, borderWidth, borderRadius, wrapped, draggable, orderable, resizable,
cuttable, deletable, wrapping, previewHeight, binaryHeight, indicators, markers, buttons, markerColor,
markerWidth, volume, volumeRange, loading, targetSpeed, waveformData, ...customParams) {
var opts = {
title: title,
titleAlignments: titleAlignments,
url: url,
previewUrl: previewUrl,
binaryUrl: binaryUrl,
kind: kind,
subkind: subkind,
duration: duration,
startTime: startTime,
endTime: endTime,
mediaStartTime: mediaStartTime,
mediaEndTime: mediaEndTime,
color: color,
backgroundColor: backgroundColor,
hoverBackgroundColor: hoverBackgroundColor,
selectedBackgroundColor: selectedBackgroundColor,
borderColor: borderColor,
selectedBorderColor: selectedBorderColor,
warningColor: warningColor,
warningWidth: warningWidth,
textFont: textFont,
textFontSize: textFontSize,
textColor: textColor,
textBackgroundColor: textBackgroundColor,
volumeSliderColor: volumeSliderColor,
volumeSliderWidth: volumeSliderWidth,
volumeSliderDraggingWidth: volumeSliderDraggingWidth,
textPosition: textPosition,
textAutoScroll: textAutoScroll,
borderWidth: borderWidth,
borderRadius: borderRadius,
wrapped: wrapped,
draggable: draggable,
orderable: orderable,
resizable: resizable,
cuttable: cuttable,
deletable: deletable,
wrapping: wrapping,
previewHeight: previewHeight,
binaryHeight: binaryHeight,
indicators: indicators,
markers: markers,
buttons: buttons,
markerColor: markerColor,
markerWidth: markerWidth,
volume: volume,
volumeRange: volumeRange,
loading: loading,
targetSpeed: targetSpeed,
waveformData: waveformData
};
validateSource(peaks, opts, 'add()');
this._peaks = peaks;
this._id = id;
this._lineId = lineId;
this._originId = originId || id;
this._elementId = elementId;
this._title = opts.title;
this._titleAlignments = opts.titleAlignments;
this._url = opts.url;
this._previewUrl = opts.previewUrl;
this._binaryUrl = opts.binaryUrl;
this._kind = opts.kind;
this._subkind = opts.subkind;
this._duration = opts.duration;
this._startTime = opts.startTime;
this._endTime = opts.endTime;
this._mediaStartTime = opts.mediaStartTime;
this._mediaEndTime = opts.mediaEndTime;
this._color = opts.color;
this._backgroundColor = opts.backgroundColor;
this._hoverBackgroundColor = opts.hoverBackgroundColor;
this._selectedBackgroundColor = opts.selectedBackgroundColor;
this._borderColor = opts.borderColor;
this._selectedBorderColor = opts.selectedBorderColor;
this._warningColor = opts.warningColor;
this._warningWidth = opts.warningWidth;
this._volumeSliderColor = opts.volumeSliderColor;
this._volumeSliderWidth = opts.volumeSliderWidth;
this._volumeSliderDraggingWidth = opts.volumeSliderDraggingWidth;
this._textFont = opts.textFont;
this._textFontSize = opts.textFontSize;
this._textColor = opts.textColor;
this._textBackgroundColor = opts.textBackgroundColor;
this._textPosition = opts.textPosition;
this._textAutoScroll = opts.textAutoScroll;
this._borderWidth = opts.borderWidth;
this._borderRadius = opts.borderRadius;
this._wrapped = opts.wrapped;
this._draggable = opts.draggable;
this._orderable = opts.orderable;
this._resizable = opts.resizable;
this._cuttable = opts.cuttable;
this._deletable = opts.deletable;
this._wrapping = opts.wrapping;
this._previewHeight = opts.previewHeight;
this._binaryHeight = opts.binaryHeight;
this._indicators = opts.indicators;
this._markers = opts.markers;
this._buttons = opts.buttons;
this._markerColor = opts.markerColor;
this._markerWidth = opts.markerWidth;
this._volume = opts.volume;
this._volumeRange = opts.volumeRange;
this._loading = opts.loading;
this._targetSpeed = opts.targetSpeed;
this._waveformData = opts.waveformData;
this._minSize = peaks.options.minSourceSize;
this._selected = false;
for (var i = 0; i < customParams.length; i += 2) {
var key = customParams[i];
var value = customParams[i + 1];
if (key && typeof key === 'string' && !key.startsWith('_') && !RESERVED_SOURCE_KEYS.has(key)) {
this[key] = value;
}
}
}
Object.defineProperties(Source.prototype, {
id: {
enumerable: true,
get: function() {
return this._id;
}
},
lineId: {
enumerable: true,
get: function() {
return this._lineId;
},
set: function(lineId) {
this._lineId = lineId;
}
},
originId: {
enumerable: true,
get: function() {
return this._originId;
}
},
elementId: {
enumerable: true,
get: function() {
return this._elementId;
}
},
title: {
enumerable: true,
get: function() {
return this._title;
},
set: function(title) {
this._title = title;
}
},
titleAlignments: {
enumerable: true,
get: function() {
return this._titleAlignments;
}
},
url: {
enumerable: true,
get: function() {
return this._url;
}
},
previewUrl: {
enumerable: true,
get: function() {
return this._previewUrl;
}
},
binaryUrl: {
enumerable: true,
get: function() {
return this._binaryUrl;
}
},
waveformData: {
enumerable: true,
get: function() {
return this._waveformData;
},
set: function(waveformData) {
this._waveformData = waveformData;
}
},
kind: {
enumerable: true,
get: function() {
return this._kind;
},
set: function(kind) {
this._kind = kind;
}
},
subkind: {
enumerable: true,
get: function() {
return this._subkind;
},
set: function(subkind) {
this._subkind = subkind;
}
},
duration: {
enumerable: true,
get: function() {
return this._duration;
}
},
startTime: {
enumerable: true,
get: function() {
return this._startTime;
}
},
endTime: {
enumerable: true,
get: function() {
return this._endTime;
}
},
mediaStartTime: {
enumerable: true,
get: function() {
return this._mediaStartTime;
},
set: function(mediaStartTime) {
this._mediaStartTime = mediaStartTime;
}
},
mediaEndTime: {
enumerable: true,
get: function() {
return this._mediaEndTime;
},
set: function(mediaEndTime) {
this._mediaEndTime = mediaEndTime;
}
},
color: {
enumerable: true,
get: function() {
return this._color;
},
set: function(color) {
this._color = color;
}
},
backgroundColor: {
enumerable: true,
get: function() {
return this._backgroundColor;
},
set: function(backgroundColor) {
this._backgroundColor = backgroundColor;
}
},
hoverBackgroundColor: {
enumerable: true,
get: function() {
return this._hoverBackgroundColor;
},
set: function(hoverBackgroundColor) {
this._hoverBackgroundColor = hoverBackgroundColor;
}
},
selectedBackgroundColor: {
enumerable: true,
get: function() {
return this._selectedBackgroundColor;
},
set: function(selectedBackgroundColor) {
this._selectedBackgroundColor = selectedBackgroundColor;
}
},
borderColor: {
enumerable: true,
get: function() {
return this._borderColor;
},
set: function(borderColor) {
this._borderColor = borderColor;
}
},
selectedBorderColor: {
enumerable: true,
get: function() {
return this._selectedBorderColor;
},
set: function(selectedBorderColor) {
this._selectedBorderColor = selectedBorderColor;
}
},
warningColor: {
enumerable: true,
get: function() {
return this._warningColor;
},
set: function(warningColor) {
this._warningColor = warningColor;
}
},
warningWidth: {
enumerable: true,
get: function() {
return this._warningWidth;
},
set: function(warningWidth) {
this._warningWidth = warningWidth;
}
},
volumeSliderColor: {
enumerable: true,
get: function() {
return this._volumeSliderColor;
}
},
volumeSliderWidth: {
enumerable: true,
get: function() {
return this._volumeSliderWidth;
}
},
volumeSliderDraggingWidth: {
enumerable: true,
get: function() {
return this._volumeSliderDraggingWidth;
}
},
textFont: {
enumerable: true,
get: function() {
return this._textFont;
},
set: function(textFont) {
this._textFont = textFont;
}
},
textFontSize: {
enumerable: true,
get: function() {
return this._textFontSize;
},
set: function(textFontSize) {
this._textFontSize = textFontSize;
}
},
textColor: {
enumerable: true,
get: function() {
return this._textColor;
},
set: function(textColor) {
this._textColor = textColor;
}
},
textBackgroundColor: {
enumerable: true,
get: function() {
return this._textBackgroundColor;
},
set: function(textBackgroundColor) {
this._textBackgroundColor = textBackgroundColor;
}
},
textPosition: {
enumerable: true,
get: function() {
return this._textPosition;
},
set: function(textPosition) {
this._textPosition = textPosition;
}
},
textAutoScroll: {
enumerable: true,
get: function() {
return this._textAutoScroll;
},
set: function(textAutoScroll) {
this._textAutoScroll = textAutoScroll;
}
},
borderWidth: {
enumerable: true,
get: function() {
return this._borderWidth;
},
set: function(borderWidth) {
this._borderWidth = borderWidth;
}
},
borderRadius: {
enumerable: true,
get: function() {
return this._borderRadius;
},
set: function(borderRadius) {
this._borderRadius = borderRadius;
}
},
wrapped: {
enumerable: true,
get: function() {
return this._wrapped;
},
set: function(wrapped) {
this._wrapped = wrapped;
}
},
segments: {
enumerable: true,
get: function() {
return this._segments;
}
},
draggable: {
enumerable: true,
get: function() {
return this._draggable;
}
},
orderable: {
enumerable: true,
get: function() {
return this._orderable;
}
},
resizable: {
enumerable: true,
get: function() {
return this._resizable;
}
},
cuttable: {
enumerable: true,
get: function() {
return this._cuttable;
}
},
deletable: {
enumerable: true,
get: function() {
return this._deletable;
}
},
wrapping: {
enumerable: true,
get: function() {
return this._wrapping;
},
set: function(wrapping) {
this._wrapping = wrapping;
}
},
previewHeight: {
enumerable: true,
get: function() {
return this._previewHeight;
},
set: function(previewHeight) {
this._previewHeight = previewHeight;
}
},
binaryHeight: {
enumerable: true,
get: function() {
return this._binaryHeight;
},
set: function(binaryHeight) {
this._binaryHeight = binaryHeight;
}
},
indicators: {
enumerable: true,
get: function() {
return this._indicators;
}
},
markers: {
enumerable: true,
get: function() {
return this._markers;
}
},
buttons: {
enumerable: true,
get: function() {
return this._buttons;
}
},
markerColor: {
enumerable: true,
get: function() {
return this._markerColor;
}
},
markerWidth: {
enumerable: true,
get: function() {
return this._markerWidth;
}
},
volume: {
enumerable: true,
get: function() {
return this._volume;
},
set: function(volume) {
this._volume = volume;
}
},
volumeRange: {
enumerable: true,
get: function() {
return this._volumeRange;
}
},
loading: {
enumerable: true,
get: function() {
return this._loading;
}
},
minSize: {
enumerable: true,
get: function() {
return this._minSize;
}
},
selected: {
enumerable: true,
get: function() {
return this._selected;
},
set: function(selected) {
this._selected = selected;
}
},
targetSpeed: {
enumerable: true,
get: function() {
return this._targetSpeed;
}
}
});
Source.prototype.updateTimes = function(newStartTime, newEndTime) {
if (!Utils.isNullOrUndefined(newStartTime)) {
if (this._duration && Utils.isNullOrUndefined(newEndTime)) {
newStartTime = Utils.roundTime(Math.max(this._endTime - this._duration, newStartTime));
}
else {
newStartTime = Utils.roundTime(newStartTime);
}
}
if (!Utils.isNullOrUndefined(newEndTime)) {
if (this._duration && Utils.isNullOrUndefined(newStartTime)) {
newEndTime = Utils.roundTime(Math.min(this._startTime + this._duration, newEndTime));
}
else {
newEndTime = Utils.roundTime(newEndTime);
}
}
if ((Utils.isNullOrUndefined(newStartTime) && !Utils.isNullOrUndefined(newEndTime))
|| (!Utils.isNullOrUndefined(newStartTime) && Utils.isNullOrUndefined(newEndTime))) {
this._updateMediaRange(this._startTime, newStartTime, this._endTime, newEndTime);
}
if (!Utils.isNullOrUndefined(newStartTime)) {
this._startTime = newStartTime;
}
if (!Utils.isNullOrUndefined(newEndTime)) {
this._endTime = newEndTime;
}
};
Source.prototype._updateMediaRange = function(oldStartTime, newStartTime, oldEndTime,
newEndTime) {
var startDiff = 0;
var endDiff = 0;
var upperLimit;
if (this._duration) {
upperLimit = this._duration;
}
else {
upperLimit = Number.POSITIVE_INFINITY;
}
if (!Utils.isNullOrUndefined(newStartTime) && !Utils.isNullOrUndefined(oldStartTime)) {
startDiff = newStartTime - oldStartTime;
}
if (!Utils.isNullOrUndefined(newEndTime) && !Utils.isNullOrUndefined(oldEndTime)) {
endDiff = newEndTime - oldEndTime;
}
var newMediaStartTime = this._mediaStartTime;
var newMediaEndTime = this._mediaEndTime;
if (startDiff) {
if (startDiff < 0) {
// Try reducing mediaStartTime
if (newMediaStartTime > 0) {
var minStartTime = newMediaStartTime + startDiff;
newMediaStartTime = Math.max(0, minStartTime);
if (minStartTime < 0) {
// Try increasing mediaEndTime
newMediaEndTime = Math.min(upperLimit, newMediaEndTime - minStartTime);
}
}
else {
// Try increasing mediaEndTime
newMediaEndTime = Math.min(upperLimit, newMediaEndTime - startDiff);
}
}
else {
// Try increasing mediaStartTime
if (newMediaStartTime < upperLimit) {
newMediaStartTime = Math.min(upperLimit, newMediaStartTime + startDiff);
}
}
}
if (endDiff) {
if (endDiff > 0) {
// Try increasing mediaEndTime
if (newMediaEndTime < upperLimit) {
var maxEndTime = newMediaEndTime + endDiff;
newMediaEndTime = Math.min(upperLimit, maxEndTime);
if (maxEndTime > upperLimit) {
// Try reducing mediaStartTime
newMediaStartTime = Math.max(0, newMediaStartTime - (maxEndTime - upperLimit));
}
}
else {
// Try reducing mediaStartTime
newMediaStartTime = Math.max(0, newMediaStartTime - endDiff);
}
}
else {
if (newEndTime - oldStartTime < upperLimit) {
if (oldEndTime - oldStartTime > upperLimit) {
endDiff += (oldEndTime - oldStartTime) - upperLimit;
}
// Try reducing mediaEndTime
if (newMediaEndTime > 0) {
newMediaEndTime = Math.max(0, newMediaEndTime + endDiff);
}
}
}
}
this._mediaStartTime = Utils.roundTime(newMediaStartTime);
this._mediaEndTime = Utils.roundTime(newMediaEndTime);
};
Source.prototype.update = function(options) {
var opts = {
title: this.title,
titleAlignments: this.titleAlignments,
url: this.url,
previewUrl: this.previewUrl,
binaryUrl: this.binaryUrl,
kind: this.kind,
subkind: this.subkind,
duration: this.duration,
startTime: this.startTime,
endTime: this.endTime,
mediaStartTime: this.mediaStartTime,
mediaEndTime: this.mediaEndTime,
color: this.color,
backgroundColor: this.backgroundColor,
hoverBackgroundColor: this.hoverBackgroundColor,
selectedBackgroundColor: this.selectedBackgroundColor,
borderColor: this.borderColor,
selectedBorderColor: this.selectedBorderColor,
warningColor: this.warningColor,
warningWidth: this.warningWidth,
volumeSliderColor: this.volumeSliderColor,
volumeSliderWidth: this.volumeSliderWidth,
volumeSliderDraggingWidth: this.volumeSliderDraggingWidth,
textFont: this.textFont,
textFontSize: this.textFontSize,
textColor: this.textColor,
textBackgroundColor: this.textBackgroundColor,
textPosition: this.textPosition,
textAutoScroll: this.textAutoScroll,
borderWidth: this.borderWidth,
borderRadius: this.borderRadius,
wrapped: this.wrapped,
draggable: this.draggable,
orderable: this.orderable,
resizable: this.resizable,
cuttable: this.cuttable,
deletable: this.deletable,
wrapping: this.wrapping,
previewHeight: this.previewHeight,
binaryHeight: this.binaryHeight,
indicators: this.indicators,
markers: this.markers,
buttons: this.buttons,
markerColor: this.markerColor,
markerWidth: this.markerWidth,
volume: this.volume,
volumeRange: this.volumeRange,
loading: this.loading,
targetSpeed: this.targetSpeed
};
Utils.extend(opts, options);
validateSource(this._peaks, opts, 'update()');
this._title = opts.title;
this._titleAlignments = opts.titleAlignments;
this._url = opts.url;
this._previewUrl = opts.previewUrl;
this._binaryUrl = opts.binaryUrl;
this._kind = opts.kind;
this._subkind = opts.subkind;
this._duration = opts.duration;
this._startTime = opts.startTime;
this._endTime = opts.endTime;
this._mediaStartTime = opts.mediaStartTime;
this._mediaEndTime = opts.mediaEndTime;
this._color = opts.color;
this._backgroundColor = opts.backgroundColor;
this._borderColor = opts.borderColor;
this._selectedBorderColor = opts.selectedBorderColor;
this._warningColor = opts.warningColor;
this._warningWidth = opts.warningWidth;
this._volumeSliderColor = opts.volumeSliderColor;
this._volumeSliderWidth = opts.volumeSliderWidth;
this._volumeSliderDraggingWidth = opts.volumeSliderDraggingWidth;
this._textFont = opts.textFont;
this._textFontSize = opts.textFontSize;
this._textColor = opts.textColor;
this._textBackgroundColor = opts.textBackgroundColor;
this._textPosition = opts.textPosition;
this._textAutoScroll = opts.textAutoScroll;
this._borderWidth = opts.borderWidth;
this._borderRadius = opts.borderRadius;
this._wrapped = opts.wrapped;
this._draggable = opts.draggable;
this._orderable = opts.orderable;
this._resizable = opts.resizable;
this._cuttable = opts.cuttable;
this._deletable = opts.deletable;
this._wrapping = opts.wrapping;
this._previewHeight = opts.previewHeight;
this._binaryHeight = opts.binaryHeight;
this._indicators = opts.indicators;
this._markers = opts.markers;
this._buttons = opts.buttons;
this._markerColor = opts.markerColor;
this._markerWidth = opts.markerWidth;
this._volume = opts.volume;
this._volumeRange = opts.volumeRange;
this._loading = opts.loading;
this._targetSpeed = opts.targetSpeed;
this._waveformData = opts.waveformData;
if (options && typeof options === 'object') {
for (var key in options) {
if (key && typeof key === 'string'
&& Object.prototype.hasOwnProperty.call(options, key)
&& !key.startsWith('_')
&& !RESERVED_SOURCE_KEYS.has(key)) {
this[key] = options[key];
}
}
}
var updatedKeys = [];
if (options && typeof options === 'object') {
updatedKeys = Object.keys(options);
}
this._peaks.emit('model.source.update', this, {
updatedKeys: updatedKeys,
onlyWaveformData: updatedKeys.length === 1 && updatedKeys[0] === 'waveformData'
});
};
/**
* Returns <code>true</code> if the source overlaps a given time region.
*
* @param {Number} startTime The start of the time region, in seconds.
* @param {Number} endTime The end of the time region, in seconds.
* @returns {Boolean}
*
* @see http://wiki.c2.com/?TestIfDateRangesOverlap
*/
Source.prototype.isVisible = function(startTime, endTime) {
return this._startTime < endTime && startTime < this._endTime;
};
/**
* Update the indicators of this source.
*
* @param {Array<String>} newIndicators The new indicators.
*/
Source.prototype.setIndicators = function(newIndicators) {
this._indicators = newIndicators;
this._peaks.emit('model.source.setIndicators', this);
};
/**
* Returns <code>true</code> if a warning should be shown
*/
Source.prototype.shouldShowWarning = function() {
return this._warningColor && this._duration > Utils.roundTime(this._endTime - this._startTime);
};
Source.prototype.getVisibleTitle = function() {
if (this._titleAlignments.length === 0) {
return this._title;
}
return this._titleAlignments.reduce(function(visibleTitle, alignment) {
if (this._mediaStartTime < alignment.end && alignment.start < this._mediaEndTime) {
visibleTitle.push(alignment.text);
}
return visibleTitle;
}.bind(this), []).join(' ');
};
/**
* Returns a serializable object containing only the properties defined with Object.defineProperties.
* This includes all enumerable properties that can be safely serialized.
*
* @returns {Object} A plain object containing the serializable properties of the source.
*/
Source.prototype.toSerializable = function() {
var serializable = {};
// Get all user-defined metadata properties
for (var key in this) {
if (key && typeof key === 'string'
&& Object.prototype.hasOwnProperty.call(this, key)
&& !key.startsWith('_')
&& !RESERVED_SOURCE_KEYS.has(key)) {
serializable[key] = this[key];
}
}
// Add all the enumerable properties from the prototype
var proto = Object.getPrototypeOf(this);
var descriptors = Object.getOwnPropertyDescriptors(proto);
for (var prop in descriptors) {
if (Object.prototype.hasOwnProperty.call(descriptors, prop)) {
var descriptor = descriptors[prop];
if (descriptor.enumerable && descriptor.get && typeof descriptor.get === 'function') {
serializable[prop] = this[prop];
}
}
}
return serializable;
};
return Source;
});