waveform-playlist-nartj
Version:
Multiple track web audio editor and player with waveform preview
1,402 lines (1,187 loc) • 41.9 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _lodash = _interopRequireDefault(require("lodash.defaults"));
var _h = _interopRequireDefault(require("virtual-dom/h"));
var _diff = _interopRequireDefault(require("virtual-dom/diff"));
var _patch = _interopRequireDefault(require("virtual-dom/patch"));
var _inlineWorker = _interopRequireDefault(require("inline-worker"));
var _fileSaver = _interopRequireDefault(require("file-saver"));
var _conversions = require("./utils/conversions");
var _LoaderFactory = _interopRequireDefault(require("./track/loader/LoaderFactory"));
var _ScrollHook = _interopRequireDefault(require("./render/ScrollHook"));
var _TimeScale = _interopRequireDefault(require("./TimeScale"));
var _Track = _interopRequireDefault(require("./Track"));
var _Playout = _interopRequireDefault(require("./Playout"));
var _AnnotationList = _interopRequireDefault(require("./annotation/AnnotationList"));
var _exportoggWorker = _interopRequireDefault(require("worker-loader!./utils/exportogg.worker.js"));
var _exportWavWorker = _interopRequireDefault(require("./utils/exportWavWorker"));
var _Undoer = _interopRequireDefault(require("./Undoer"));
var _default = /*#__PURE__*/function () {
function _default() {
(0, _classCallCheck2["default"])(this, _default);
this.tracks = [];
this.soloedTracks = [];
this.mutedTracks = [];
this.playoutPromises = [];
this.cursor = 0;
this.playbackSeconds = 0;
this.duration = 0;
this.scrollLeft = 0;
this.scrollTimer = undefined;
this.showTimescale = false; // whether a user is scrolling the waveform
this.isScrolling = false;
this.fadeType = 'logarithmic';
this.masterGain = 1;
this.annotations = [];
this.durationFormat = 'hh:mm:ss.uuu';
this.isAutomaticScroll = false;
this.resetDrawTimer = undefined;
this.undoer = new _Undoer["default"]();
} // TODO extract into a plugin
(0, _createClass2["default"])(_default, [{
key: "initExporter",
value: function initExporter() {
this.wavExportWorker = new _inlineWorker["default"](_exportWavWorker["default"]);
this.oggExportWorker = new _exportoggWorker["default"]();
} // TODO extract into a plugin
}, {
key: "initRecorder",
value: function initRecorder(stream) {
var _this = this;
this.mediaRecorder = new window.MediaRecorder(stream);
this.mediaRecorder.onstart = function () {
var track = new _Track["default"]();
track.setName('Recording');
track.setEnabledStates();
track.setEventEmitter(_this.ee);
_this.recordingTrack = track;
_this.tracks.push(track);
_this.chunks = [];
_this.working = false;
};
this.mediaRecorder.ondataavailable = function (e) {
_this.chunks.push(e.data); // throttle peaks calculation
if (!_this.working) {
var recording = new Blob(_this.chunks, {
type: 'audio/ogg; codecs=opus'
});
var loader = _LoaderFactory["default"].createLoader(recording, _this.ac);
loader.load().then(function (audioBuffer) {
// ask web worker for peaks.
_this.recorderWorker.postMessage({
samples: audioBuffer.getChannelData(0),
samplesPerPixel: _this.samplesPerPixel
});
_this.recordingTrack.setCues(0, audioBuffer.duration);
_this.recordingTrack.setBuffer(audioBuffer);
_this.recordingTrack.setPlayout(new _Playout["default"](_this.ac, audioBuffer));
_this.adjustDuration();
})["catch"](function () {
_this.working = false;
});
_this.working = true;
}
};
this.mediaRecorder.onstop = function () {
_this.chunks = [];
_this.working = false;
};
this.recorderWorker = new _inlineWorker["default"](RecorderWorkerFunction); // use a worker for calculating recording peaks.
this.recorderWorker.onmessage = function (e) {
_this.recordingTrack.setPeaks(e.data);
_this.working = false;
_this.drawRequest();
};
}
}, {
key: "setShowTimeScale",
value: function setShowTimeScale(show) {
this.showTimescale = show;
}
}, {
key: "setMono",
value: function setMono(mono) {
this.mono = mono;
}
}, {
key: "setExclSolo",
value: function setExclSolo(exclSolo) {
this.exclSolo = exclSolo;
}
}, {
key: "setSeekStyle",
value: function setSeekStyle(style) {
this.seekStyle = style;
}
}, {
key: "getSeekStyle",
value: function getSeekStyle() {
return this.seekStyle;
}
}, {
key: "setSampleRate",
value: function setSampleRate(sampleRate) {
this.sampleRate = sampleRate;
}
}, {
key: "setSamplesPerPixel",
value: function setSamplesPerPixel(samplesPerPixel) {
this.samplesPerPixel = samplesPerPixel;
}
}, {
key: "setAudioContext",
value: function setAudioContext(ac) {
this.ac = ac;
}
}, {
key: "setControlOptions",
value: function setControlOptions(controlOptions) {
this.controls = controlOptions;
}
}, {
key: "setWaveHeight",
value: function setWaveHeight(height) {
this.waveHeight = height;
}
}, {
key: "setColors",
value: function setColors(colors) {
this.colors = colors;
}
}, {
key: "setAnnotations",
value: function setAnnotations(config) {
this.annotationList = new _AnnotationList["default"](this, config.annotations, config.controls, config.editable, config.linkEndpoints, config.isContinuousPlay);
}
}, {
key: "setEventEmitter",
value: function setEventEmitter(ee) {
this.ee = ee;
}
}, {
key: "getEventEmitter",
value: function getEventEmitter() {
return this.ee;
}
}, {
key: "setUpEventEmitter",
value: function setUpEventEmitter() {
var _this2 = this;
var ee = this.ee;
function arrayMove(arr, fromIndex, toIndex) {
var element = arr[fromIndex];
arr.splice(fromIndex, 1);
arr.splice(toIndex, 0, element);
}
ee.on('moveUp', function (track) {
var idx = _this2.tracks.indexOf(track);
if (idx > 0) {
arrayMove(_this2.tracks, idx, idx - 1);
_this2.drawRequest();
}
});
ee.on('moveDown', function (track) {
var idx = _this2.tracks.indexOf(track);
if (idx < _this2.tracks.length - 1) {
arrayMove(_this2.tracks, idx, idx + 1);
_this2.drawRequest();
}
});
ee.on('undo', function (val) {
_this2.undoer.pop();
console.log('undo');
});
ee.on('redo', function (val) {
console.log('redo'); // todo
});
ee.on('load', function (val) {
_this2.undoer.clear();
console.log('load'); // todo
});
ee.on('save', /*#__PURE__*/function () {
var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(val) {
var blob;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
console.log('save');
blob = new Blob([JSON.stringify(_this2.tracks, null)], {
type: "text/plain;charset=utf-8"
});
_fileSaver["default"].saveAs(blob, "playlist.json"); // todo
case 3:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function (_x) {
return _ref.apply(this, arguments);
};
}());
ee.on('draw', function (val) {
_this2.drawRequest();
});
ee.on('duplicate', /*#__PURE__*/function () {
var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(track) {
var self, dupTrack, undo;
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
self = _this2; // todo it does not duplicate ease in and out, should it do it?
_context2.next = 3;
return track.duplicateTrack(track, track.startTime, track.cueIn, track.cueOut, 1);
case 3:
dupTrack = _context2.sent;
undo = function undo() {
self.removeTrack(dupTrack);
};
_this2.undoer.push(undo);
case 6:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
return function (_x2) {
return _ref2.apply(this, arguments);
};
}());
ee.on('delete', /*#__PURE__*/function () {
var _ref3 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3(track) {
var self, undo;
return _regenerator["default"].wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
self = _this2;
_this2.removeTrack(track);
undo = function undo() {//const dupTrack = await track.duplicateTrack(track, track.startTime, track.cueIn, track.cueOut, 1);
// todo
};
_this2.undoer.push(undo); // todo we should also receive the duration of the audio, the audio duration might be shorter we removed the track
_this2.drawRequest();
case 5:
case "end":
return _context3.stop();
}
}
}, _callee3);
}));
return function (_x3) {
return _ref3.apply(this, arguments);
};
}());
ee.on('add', /*#__PURE__*/function () {
var _ref4 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4(file) {
var track, self, undo;
return _regenerator["default"].wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
_context4.next = 2;
return _this2.load([{
src: file,
name: file.name
}]);
case 2:
track = _context4.sent[0];
self = _this2;
undo = function undo() {
self.removeTrack(track);
self.drawRequest();
};
_this2.undoer.push(undo);
case 6:
case "end":
return _context4.stop();
}
}
}, _callee4);
}));
return function (_x4) {
return _ref4.apply(this, arguments);
};
}());
ee.on('automaticscroll', function (val) {
_this2.isAutomaticScroll = val;
});
ee.on('durationformat', function (format) {
_this2.durationFormat = format;
_this2.drawRequest();
});
ee.on('select', function (start, end, track) {
if (_this2.isPlaying()) {
_this2.lastSeeked = start;
_this2.pausedAt = undefined;
_this2.restartPlayFrom(start);
} else {
// reset if it was paused.
_this2.seek(start, end, track);
_this2.ee.emit('timeupdate', start);
_this2.drawRequest();
}
});
ee.on('startaudiorendering', function (type) {
_this2.startOfflineRender(type);
});
ee.on('statechange', function (state) {
_this2.setState(state);
_this2.drawRequest();
});
ee.on('shift', function (deltaTime, track) {
track.setStartTime(track.getStartTime() + deltaTime);
_this2.adjustDuration();
_this2.drawRequest();
});
ee.on('shiftbegin', function (deltaTime, track) {});
ee.on('shiftend', function (deltaTime, track, undo) {
var startTime = track.getStartTime();
_this2.undoer.push(function () {
undo();
track.setStartTime(startTime - deltaTime);
_this2.adjustDuration();
_this2.drawRequest();
});
});
ee.on('record', function () {
_this2.record();
});
ee.on('play', function (start, end) {
_this2.play(start, end);
});
ee.on('pause', function () {
_this2.pause();
});
ee.on('stop', function () {
_this2.stop();
});
ee.on('rewind', function () {
_this2.rewind();
});
ee.on('fastforward', function () {
_this2.fastForward();
});
ee.on('clear', function () {
_this2.clear().then(function () {
_this2.drawRequest();
});
});
ee.on('solo', function (track) {
_this2.soloTrack(track);
_this2.adjustTrackPlayout();
_this2.drawRequest();
});
ee.on('mute', function (track) {
_this2.muteTrack(track);
_this2.adjustTrackPlayout();
_this2.drawRequest();
});
ee.on('volumechange', function (volume, track) {
track.setGainLevel(volume / 100);
});
ee.on('mastervolumechange', function (volume) {
_this2.masterGain = volume / 100;
_this2.tracks.forEach(function (track) {
track.setMasterGainLevel(_this2.masterGain);
});
});
ee.on('fadein', function (duration, track) {
var fadeEnd = 0;
if (track.fades && track.fadeIn && track.fades[track.fadeIn]) {
fadeEnd = track.fades[track.fadeIn].end;
}
var fadeType = _this2.fadeType;
var undo = function undo() {
track.setFadeIn(fadeEnd, fadeType);
_this2.drawRequest();
};
_this2.undoer.push(undo);
track.setFadeIn(duration, _this2.fadeType);
_this2.drawRequest();
});
ee.on('fadeout', function (duration, track) {
var fadeBegin = 0;
if (track.fades && track.fadeIn && track.fades[track.fadeIn]) {
fadeBegin = track.fades[track.fadeIn].end;
}
var fadeType = _this2.fadeType;
var undo = function undo() {
track.setFadeOut(fadeBegin, fadeType);
_this2.drawRequest();
};
_this2.undoer.push(undo);
track.setFadeOut(duration, _this2.fadeType);
_this2.drawRequest();
});
ee.on('stereopan', function (panvalue, track) {
track.setStereoPanValue(panvalue);
});
ee.on('fadetype', function (type) {
_this2.fadeType = type;
});
ee.on('duplicateTrack', function (track, start, cueIn, cueOut, trackOffset) {
track.duplicateTrack(track, start, cueIn, cueOut, trackOffset);
});
ee.on('trim', /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5() {
var track, timeSelection, undo;
return _regenerator["default"].wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
track = _this2.getActiveTrack();
timeSelection = _this2.getTimeSelection();
_context5.next = 4;
return track.trim(timeSelection.start, timeSelection.end);
case 4:
undo = _context5.sent;
track.calculatePeaks(_this2.samplesPerPixel, _this2.sampleRate);
_this2.setTimeSelection(0, 0);
_this2.drawRequest();
_this2.undoer.push(undo);
case 9:
case "end":
return _context5.stop();
}
}
}, _callee5);
})));
ee.on('zoomin', function () {
var zoomIndex = Math.max(0, _this2.zoomIndex - 1);
var zoom = _this2.zoomLevels[zoomIndex];
if (zoom !== _this2.samplesPerPixel) {
_this2.setZoom(zoom);
_this2.drawRequest();
}
});
ee.on('zoomout', function () {
var zoomIndex = Math.min(_this2.zoomLevels.length - 1, _this2.zoomIndex + 1);
var zoom = _this2.zoomLevels[zoomIndex];
if (zoom !== _this2.samplesPerPixel) {
_this2.setZoom(zoom);
_this2.drawRequest();
}
});
ee.on('scroll', function () {
_this2.isScrolling = true;
_this2.drawRequest();
clearTimeout(_this2.scrollTimer);
_this2.scrollTimer = setTimeout(function () {
_this2.isScrolling = false;
}, 200);
});
}
}, {
key: "removeTrack",
value: function removeTrack(track) {
this.tracks = this.tracks.filter(function (t) {
return t !== track;
});
}
}, {
key: "load",
value: function load(trackList) {
var _this3 = this;
var loadPromises = trackList.map(function (trackInfo) {
var loader = _LoaderFactory["default"].createLoader(trackInfo.src, _this3.ac, _this3.ee);
return loader.load();
});
var newTrack;
var trackOffset;
var isTrackDuplication = false;
return Promise.all(loadPromises).then(function (audioBuffers) {
_this3.ee.emit('audiosourcesloaded');
var tracks = audioBuffers.map(function (audioBuffer, index) {
var info = trackList[index];
var trck = info.track || undefined;
isTrackDuplication = trck !== undefined;
var name = info.name || 'Untitled';
var start = info.start || 0;
var states = info.states || {};
var fadeIn = info.fadeIn;
var fadeOut = info.fadeOut;
var cueIn = info.cueIn || 0;
var cueOut = info.cueOut || audioBuffer.duration;
var gain = info.gain || 1;
var muted = info.muted || false;
var soloed = info.soloed || false;
var selection = info.selected;
var peaks = info.peaks || {
type: 'WebAudio',
mono: _this3.mono
};
var customClass = info.customClass || undefined;
var waveOutlineColor = info.waveOutlineColor || undefined;
var stereoPan = info.stereoPan || 0;
var duplicationNumber = info.duplicationNumber || 0;
trackOffset = info.trackOffset || 0; // webaudio specific playout for now.
var playout = new _Playout["default"](_this3.ac, audioBuffer);
var track = new _Track["default"]();
track.setSrc(info.src);
track.setBuffer(audioBuffer);
track.setSrcTrack(trck);
track.setDuplicationNumber(trck === undefined ? duplicationNumber : trck.srcTrack === undefined ? trck.duplicationNumber + 1 : trck.srcTrack.duplicationNumber + 1);
track.setName(name);
track.setEventEmitter(_this3.ee);
track.setEnabledStates(states);
track.setCues(cueIn, cueOut);
track.setCustomClass(customClass);
track.setWaveOutlineColor(waveOutlineColor);
if (fadeIn !== undefined) {
track.setFadeIn(fadeIn.duration, fadeIn.shape);
}
if (fadeOut !== undefined) {
track.setFadeOut(fadeOut.duration, fadeOut.shape);
}
if (selection !== undefined) {
_this3.setActiveTrack(track);
_this3.setTimeSelection(selection.start, selection.end);
}
if (peaks !== undefined) {
track.setPeakData(peaks);
}
track.setState(_this3.getState());
track.setStartTime(start);
track.setPlayout(playout);
track.setGainLevel(gain);
track.setStereoPanValue(stereoPan);
if (muted) {
_this3.muteTrack(track);
}
if (soloed) {
_this3.soloTrack(track);
} // extract peaks with AudioContext for now.
track.calculatePeaks(_this3.samplesPerPixel, _this3.sampleRate);
newTrack = track;
return track;
});
if (tracks.length > 1) {
_this3.tracks = _this3.tracks.concat(tracks);
} else if (isTrackDuplication) {
_this3.tracks.splice(_this3.tracks.indexOf(_this3.getActiveTrack()) + _this3.getActiveTrack().duplicationNumber - newTrack.duplicationNumber + trackOffset, 0, newTrack);
} else {
_this3.tracks.push(tracks[0]);
}
_this3.adjustDuration();
_this3.draw(_this3.render());
_this3.ee.emit('audiosourcesrendered');
return tracks;
})["catch"](function (e) {
_this3.ee.emit('audiosourceserror', e);
return [];
});
}
}, {
key: "virtualLoad",
value: function virtualLoad(trackList) {
var _this4 = this;
var loadPromises = trackList.map(function (trackInfo) {
var loader = _LoaderFactory["default"].createLoader(trackInfo.src, _this4.ac, _this4.ee);
return loader.load();
});
var newTrack = undefined;
var trackOffset = undefined;
var isTrackDuplication = false;
return Promise.all(loadPromises).then(function (audioBuffers) {
_this4.ee.emit('audiosourcesloaded');
var tracks = audioBuffers.map(function (audioBuffer, index) {
var info = trackList[index];
var trck = info.track || undefined;
isTrackDuplication = trck !== undefined;
var name = info.name || 'Untitled';
var start = info.start || 0;
var states = info.states || {};
var fadeIn = info.fadeIn;
var fadeOut = info.fadeOut;
var cueIn = info.cueIn || 0;
var cueOut = info.cueOut || audioBuffer.duration;
var gain = info.gain || 1;
var muted = info.muted || false;
var soloed = info.soloed || false;
var selection = info.selected;
var peaks = info.peaks || {
type: 'WebAudio',
mono: _this4.mono
};
var customClass = info.customClass || undefined;
var waveOutlineColor = info.waveOutlineColor || undefined;
var stereoPan = info.stereoPan || 0;
var duplicationNumber = info.duplicationNumber || 0;
trackOffset = info.trackOffset || 0; // webaudio specific playout for now.
var playout = new _Playout["default"](_this4.ac, audioBuffer);
var track = new _Track["default"]();
track.setSrc(info.src);
track.setBuffer(audioBuffer);
track.setSrcTrack(trck);
track.setDuplicationNumber(trck === undefined ? duplicationNumber : trck.srcTrack === undefined ? trck.duplicationNumber + 1 : trck.srcTrack.duplicationNumber + 1);
track.setName(name);
track.setEventEmitter(_this4.ee);
track.setEnabledStates(states);
track.setCues(cueIn, cueOut);
track.setCustomClass(customClass);
track.setWaveOutlineColor(waveOutlineColor);
if (fadeIn !== undefined) {
track.setFadeIn(fadeIn.duration, fadeIn.shape);
}
if (fadeOut !== undefined) {
track.setFadeOut(fadeOut.duration, fadeOut.shape);
}
if (selection !== undefined) {
_this4.setActiveTrack(track);
_this4.setTimeSelection(selection.start, selection.end);
}
if (peaks !== undefined) {
track.setPeakData(peaks);
}
track.setState(_this4.getState());
track.setStartTime(start);
track.setPlayout(playout);
track.setGainLevel(gain);
track.setStereoPanValue(stereoPan);
if (muted) {
_this4.muteTrack(track);
}
if (soloed) {
_this4.soloTrack(track);
} // extract peaks with AudioContext for now.
track.calculatePeaks(_this4.samplesPerPixel, _this4.sampleRate);
newTrack = track;
return track;
});
if (tracks.length > 1) {
_this4.tracks = _this4.tracks.concat(tracks);
} else if (isTrackDuplication) {
_this4.tracks.splice(_this4.tracks.indexOf(_this4.getActiveTrack()) + _this4.getActiveTrack().duplicationNumber - newTrack.duplicationNumber + trackOffset, 0, newTrack);
}
_this4.adjustDuration();
_this4.draw(_this4.render());
_this4.ee.emit('audiosourcesrendered');
})["catch"](function (e) {
_this4.ee.emit('audiosourceserror', e);
});
}
/*
track instance of Track.
*/
}, {
key: "setActiveTrack",
value: function setActiveTrack(track) {
this.activeTrack = track;
}
}, {
key: "getActiveTrack",
value: function getActiveTrack() {
return this.activeTrack;
}
}, {
key: "isSegmentSelection",
value: function isSegmentSelection() {
return this.timeSelection.start !== this.timeSelection.end;
}
/*
start, end in seconds.
*/
}, {
key: "setTimeSelection",
value: function setTimeSelection() {
var start = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var end = arguments.length > 1 ? arguments[1] : undefined;
this.timeSelection = {
start: start,
end: end === undefined ? start : end
};
this.cursor = start;
}
}, {
key: "startOfflineRender",
value: function startOfflineRender(type) {
var _this5 = this;
if (this.isRendering) {
return;
}
this.isRendering = true;
this.offlineAudioContext = new OfflineAudioContext(2, 44100 * this.duration, 44100);
var currentTime = this.offlineAudioContext.currentTime;
this.tracks.forEach(function (track) {
track.setOfflinePlayout(new _Playout["default"](_this5.offlineAudioContext, track.buffer));
track.schedulePlay(currentTime, 0, 0, {
shouldPlay: _this5.shouldTrackPlay(track),
masterGain: 1,
isOffline: true
});
});
/*
TODO cleanup of different audio playouts handling.
*/
this.offlineAudioContext.startRendering().then(function (audioBuffer) {
if (type === 'buffer') {
_this5.ee.emit('audiorenderingfinished', type, audioBuffer);
_this5.isRendering = false;
} else if (type === 'ogg') {
// callback for `encodeOGG`
_this5.oggExportWorker.onmessage = function (e) {
_this5.ee.emit('audiorenderingfinished', type, e.data);
_this5.isRendering = false;
}; // ask the worker for a OGG
_this5.oggExportWorker.postMessage({
command: 'encodeOGG',
buffer: [// todo check if mono or stereo
audioBuffer.getChannelData(0), audioBuffer.getChannelData(1)],
sampleRate: audioBuffer.sampleRate,
numberOfChannels: audioBuffer.numberOfChannels,
quality: 0.5,
tags: {}
});
} else if (type === 'wav') {
_this5.wavExportWorker.postMessage({
command: 'init',
config: {
sampleRate: 44100
}
}); // callback for `exportWAV`
_this5.wavExportWorker.onmessage = function (e) {
_this5.ee.emit('audiorenderingfinished', type, e.data);
_this5.isRendering = false; // clear out the buffer for next renderings.
_this5.wavExportWorker.postMessage({
command: 'clear'
});
}; // send the channel data from our buffer to the worker
_this5.wavExportWorker.postMessage({
command: 'record',
buffer: [audioBuffer.getChannelData(0), audioBuffer.getChannelData(1)]
}); // ask the worker for a WAV
_this5.wavExportWorker.postMessage({
command: 'exportWAV',
type: 'audio/wav'
});
}
})["catch"](function (e) {
throw e;
});
}
}, {
key: "getTimeSelection",
value: function getTimeSelection() {
return this.timeSelection;
}
}, {
key: "setState",
value: function setState(state) {
this.state = state;
this.tracks.forEach(function (track) {
track.setState(state);
});
}
}, {
key: "getState",
value: function getState() {
return this.state;
}
}, {
key: "setZoomIndex",
value: function setZoomIndex(index) {
this.zoomIndex = index;
}
}, {
key: "setZoomLevels",
value: function setZoomLevels(levels) {
this.zoomLevels = levels;
}
}, {
key: "setZoom",
value: function setZoom(zoom) {
var _this6 = this;
this.samplesPerPixel = zoom;
this.zoomIndex = this.zoomLevels.indexOf(zoom);
this.tracks.forEach(function (track) {
track.calculatePeaks(zoom, _this6.sampleRate);
});
}
}, {
key: "muteTrack",
value: function muteTrack(track) {
var index = this.mutedTracks.indexOf(track);
if (index > -1) {
this.mutedTracks.splice(index, 1);
} else {
this.mutedTracks.push(track);
}
}
}, {
key: "soloTrack",
value: function soloTrack(track) {
var index = this.soloedTracks.indexOf(track);
if (index > -1) {
this.soloedTracks.splice(index, 1);
} else if (this.exclSolo) {
this.soloedTracks = [track];
} else {
this.soloedTracks.push(track);
}
}
}, {
key: "adjustTrackPlayout",
value: function adjustTrackPlayout() {
var _this7 = this;
this.tracks.forEach(function (track) {
track.setShouldPlay(_this7.shouldTrackPlay(track));
});
}
}, {
key: "adjustDuration",
value: function adjustDuration() {
this.duration = this.tracks.reduce(function (duration, track) {
return Math.max(duration, track.getEndTime());
}, 0);
}
}, {
key: "shouldTrackPlay",
value: function shouldTrackPlay(track) {
var shouldPlay; // if there are solo tracks, only they should play.
if (this.soloedTracks.length > 0) {
shouldPlay = false;
if (this.soloedTracks.indexOf(track) > -1) {
shouldPlay = true;
}
} else {
// play all tracks except any muted tracks.
shouldPlay = true;
if (this.mutedTracks.indexOf(track) > -1) {
shouldPlay = false;
}
}
return shouldPlay;
}
}, {
key: "isPlaying",
value: function isPlaying() {
return this.tracks.reduce(function (isPlaying, track) {
return isPlaying || track.isPlaying();
}, false);
}
/*
* returns the current point of time in the playlist in seconds.
*/
}, {
key: "getCurrentTime",
value: function getCurrentTime() {
var cursorPos = this.lastSeeked || this.pausedAt || this.cursor;
return cursorPos + this.getElapsedTime();
}
}, {
key: "getElapsedTime",
value: function getElapsedTime() {
return this.ac.currentTime - this.lastPlay;
}
}, {
key: "setMasterGain",
value: function setMasterGain(gain) {
this.ee.emit('mastervolumechange', gain);
}
}, {
key: "restartPlayFrom",
value: function restartPlayFrom(start, end) {
this.stopAnimation();
this.tracks.forEach(function (editor) {
editor.scheduleStop();
});
return Promise.all(this.playoutPromises).then(this.play.bind(this, start, end));
}
}, {
key: "play",
value: function play(startTime, endTime) {
var _this8 = this;
clearTimeout(this.resetDrawTimer);
var currentTime = this.ac.currentTime;
var selected = this.getTimeSelection();
var playoutPromises = [];
var start = startTime || this.pausedAt || this.cursor;
var end = endTime;
if (!end && selected.end !== selected.start && selected.end > start) {
end = selected.end;
}
if (this.isPlaying()) {
return this.restartPlayFrom(start, end);
}
this.tracks.forEach(function (track) {
track.setState('cursor');
playoutPromises.push(track.schedulePlay(currentTime, start, end, {
shouldPlay: _this8.shouldTrackPlay(track),
masterGain: _this8.masterGain
}));
});
this.lastPlay = currentTime; // use these to track when the playlist has fully stopped.
this.playoutPromises = playoutPromises;
this.startAnimation(start);
return Promise.all(this.playoutPromises);
}
}, {
key: "pause",
value: function pause() {
if (!this.isPlaying()) {
return Promise.all(this.playoutPromises);
}
this.pausedAt = this.getCurrentTime();
return this.playbackReset();
}
}, {
key: "stop",
value: function stop() {
if (this.mediaRecorder && this.mediaRecorder.state === 'recording') {
this.mediaRecorder.stop();
}
this.pausedAt = undefined;
this.playbackSeconds = 0;
return this.playbackReset();
}
}, {
key: "playbackReset",
value: function playbackReset() {
var _this9 = this;
this.lastSeeked = undefined;
this.stopAnimation();
this.tracks.forEach(function (track) {
track.scheduleStop();
track.setState(_this9.getState());
});
this.drawRequest();
return Promise.all(this.playoutPromises);
}
}, {
key: "rewind",
value: function rewind() {
var _this10 = this;
return this.stop().then(function () {
_this10.scrollLeft = 0;
_this10.ee.emit('select', 0, 0);
});
}
}, {
key: "fastForward",
value: function fastForward() {
var _this11 = this;
return this.stop().then(function () {
if (_this11.viewDuration < _this11.duration) {
_this11.scrollLeft = _this11.duration - _this11.viewDuration;
} else {
_this11.scrollLeft = 0;
}
_this11.ee.emit('select', _this11.duration, _this11.duration);
});
}
}, {
key: "clear",
value: function clear() {
var _this12 = this;
return this.stop().then(function () {
_this12.tracks = [];
_this12.soloedTracks = [];
_this12.mutedTracks = [];
_this12.playoutPromises = [];
_this12.cursor = 0;
_this12.playbackSeconds = 0;
_this12.duration = 0;
_this12.scrollLeft = 0;
_this12.seek(0, 0, undefined);
});
}
}, {
key: "record",
value: function record() {
var _this13 = this;
var playoutPromises = [];
this.mediaRecorder.start(300);
this.tracks.forEach(function (track) {
track.setState('none');
playoutPromises.push(track.schedulePlay(_this13.ac.currentTime, 0, undefined, {
shouldPlay: _this13.shouldTrackPlay(track)
}));
});
this.playoutPromises = playoutPromises;
}
}, {
key: "startAnimation",
value: function startAnimation(startTime) {
var _this14 = this;
this.lastDraw = this.ac.currentTime;
this.animationRequest = window.requestAnimationFrame(function () {
_this14.updateEditor(startTime);
});
}
}, {
key: "stopAnimation",
value: function stopAnimation() {
window.cancelAnimationFrame(this.animationRequest);
this.lastDraw = undefined;
}
}, {
key: "seek",
value: function seek(start, end, track) {
if (this.isPlaying()) {
this.lastSeeked = start;
this.pausedAt = undefined;
this.restartPlayFrom(start);
} else {
// reset if it was paused.
this.setActiveTrack(track || this.tracks[0]);
this.pausedAt = start;
this.setTimeSelection(start, end);
if (this.getSeekStyle() === 'fill') {
this.playbackSeconds = start;
}
}
}
/*
* Animation function for the playlist.
* Keep under 16.7 milliseconds based on a typical screen refresh rate of 60fps.
*/
}, {
key: "updateEditor",
value: function updateEditor(cursor) {
var _this15 = this;
var currentTime = this.ac.currentTime;
var selection = this.getTimeSelection();
var cursorPos = cursor || this.cursor;
var elapsed = currentTime - this.lastDraw;
if (this.isPlaying()) {
var playbackSeconds = cursorPos + elapsed;
this.ee.emit('timeupdate', playbackSeconds);
this.animationRequest = window.requestAnimationFrame(function () {
_this15.updateEditor(playbackSeconds);
});
this.playbackSeconds = playbackSeconds;
this.draw(this.render());
this.lastDraw = currentTime;
} else {
if (cursorPos + elapsed >= (this.isSegmentSelection() ? selection.end : this.duration)) {
this.ee.emit('finished');
}
this.stopAnimation();
this.resetDrawTimer = setTimeout(function () {
_this15.pausedAt = undefined;
_this15.lastSeeked = undefined;
_this15.setState(_this15.getState());
_this15.playbackSeconds = 0;
_this15.draw(_this15.render());
}, 0);
}
}
}, {
key: "drawRequest",
value: function drawRequest() {
var _this16 = this;
window.requestAnimationFrame(function () {
_this16.draw(_this16.render());
});
}
}, {
key: "draw",
value: function draw(newTree) {
var patches = (0, _diff["default"])(this.tree, newTree);
this.rootNode = (0, _patch["default"])(this.rootNode, patches);
this.tree = newTree; // use for fast forwarding.
this.viewDuration = (0, _conversions.pixelsToSeconds)(this.rootNode.clientWidth - this.controls.width, this.samplesPerPixel, this.sampleRate);
}
}, {
key: "getTrackRenderData",
value: function getTrackRenderData() {
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var defaults = {
height: this.waveHeight,
resolution: this.samplesPerPixel,
sampleRate: this.sampleRate,
controls: this.controls,
isActive: false,
timeSelection: this.getTimeSelection(),
playlistLength: this.duration,
playbackSeconds: this.playbackSeconds,
colors: this.colors
};
return (0, _lodash["default"])(data, defaults);
}
}, {
key: "isActiveTrack",
value: function isActiveTrack(track) {
var activeTrack = this.getActiveTrack();
if (this.isSegmentSelection()) {
return activeTrack === track;
}
return true;
}
}, {
key: "renderAnnotations",
value: function renderAnnotations() {
return this.annotationList.render();
}
}, {
key: "renderTimeScale",
value: function renderTimeScale() {
var controlWidth = this.controls.show ? this.controls.width : 0;
var timeScale = new _TimeScale["default"](this.duration, this.scrollLeft, this.samplesPerPixel, this.sampleRate, controlWidth, this.colors);
return timeScale.render();
}
}, {
key: "renderTrackSection",
value: function renderTrackSection() {
var _this17 = this;
var trackElements = this.tracks.map(function (track) {
return track.render(_this17.getTrackRenderData({
isActive: _this17.isActiveTrack(track),
shouldPlay: _this17.shouldTrackPlay(track),
soloed: _this17.soloedTracks.indexOf(track) > -1,
muted: _this17.mutedTracks.indexOf(track) > -1
}));
});
return (0, _h["default"])('div.playlist-tracks', {
attributes: {
style: 'overflow: auto;'
},
onscroll: function onscroll(e) {
_this17.scrollLeft = (0, _conversions.pixelsToSeconds)(e.target.scrollLeft, _this17.samplesPerPixel, _this17.sampleRate);
_this17.ee.emit('scroll', _this17.scrollLeft);
},
hook: new _ScrollHook["default"](this)
}, trackElements);
}
}, {
key: "render",
value: function render() {
var containerChildren = [];
if (this.showTimescale) {
containerChildren.push(this.renderTimeScale());
}
containerChildren.push(this.renderTrackSection());
if (this.annotationList.length) {
containerChildren.push(this.renderAnnotations());
}
return (0, _h["default"])('div.playlist', {
attributes: {
style: 'overflow: hidden; position: relative;'
}
}, containerChildren);
}
}, {
key: "getInfo",
value: function getInfo() {
var info = [];
this.tracks.forEach(function (track) {
info.push(track.getTrackDetails());
});
return info;
}
}]);
return _default;
}();
exports["default"] = _default;