signal-desktop/js/views/recorder_view.js

111 lines
2.9 KiB
JavaScript
Raw Normal View History

/* global Whisper, moment, WebAudioRecorder */
/* eslint-disable more/no-then */
// eslint-disable-next-line func-names
2018-04-27 21:25:04 +00:00
(function() {
'use strict';
2018-04-27 21:25:04 +00:00
window.Whisper = window.Whisper || {};
2016-08-15 22:36:29 +00:00
2018-04-27 21:25:04 +00:00
Whisper.RecorderView = Whisper.View.extend({
className: 'recorder clearfix',
templateName: 'recorder',
initialize() {
2018-04-27 21:25:04 +00:00
this.startTime = Date.now();
this.interval = setInterval(this.updateTime.bind(this), 1000);
this.start();
},
events: {
'click .close': 'close',
'click .finish': 'finish',
close: 'close',
},
updateTime() {
const duration = moment.duration(Date.now() - this.startTime, 'ms');
const minutes = `${Math.trunc(duration.asMinutes())}`;
let seconds = `${duration.seconds()}`;
2018-04-27 21:25:04 +00:00
if (seconds.length < 2) {
seconds = `0${seconds}`;
2018-04-27 21:25:04 +00:00
}
this.$('.time').text(`${minutes}:${seconds}`);
2018-04-27 21:25:04 +00:00
},
close() {
2018-04-27 21:25:04 +00:00
// Note: the 'close' event can be triggered by InboxView, when the user clicks
// anywhere outside the recording pane.
2018-04-27 21:25:04 +00:00
if (this.recorder.isRecording()) {
this.recorder.cancelRecording();
}
this.recorder = null;
2018-04-27 21:25:04 +00:00
if (this.interval) {
clearInterval(this.interval);
}
this.interval = null;
2018-04-27 21:25:04 +00:00
if (this.source) {
this.source.disconnect();
}
this.source = null;
2018-04-27 21:25:04 +00:00
if (this.context) {
this.context.close().then(() => {
2018-04-27 21:25:04 +00:00
console.log('audio context closed');
});
}
this.context = null;
2018-04-27 21:25:04 +00:00
this.remove();
this.trigger('closed');
},
finish() {
2018-04-27 21:25:04 +00:00
this.recorder.finishRecording();
this.close();
},
handleBlob(recorder, blob) {
2018-04-27 21:25:04 +00:00
if (blob) {
this.trigger('send', blob);
}
},
start() {
2018-04-27 21:25:04 +00:00
this.context = new AudioContext();
this.input = this.context.createGain();
this.recorder = new WebAudioRecorder(this.input, {
encoding: 'mp3',
workerDir: 'js/', // must end with slash
});
this.recorder.onComplete = this.handleBlob.bind(this);
this.recorder.onError = this.onError;
navigator.webkitGetUserMedia(
{ audio: true },
stream => {
2018-04-27 21:25:04 +00:00
this.source = this.context.createMediaStreamSource(stream);
this.source.connect(this.input);
},
2018-04-27 21:25:04 +00:00
this.onError.bind(this)
);
this.recorder.startRecording();
},
onError(error) {
// Protect against out-of-band errors, which can happen if the user revokes media
// permissions after successfully accessing the microphone.
if (!this.recorder) {
return;
}
2018-04-27 21:25:04 +00:00
this.close();
if (error && error.name === 'PermissionDeniedError') {
console.log('RecorderView.onError: Microphone access is not allowed!');
window.showPermissionsPopup();
} else {
console.log(
'RecorderView.onError:',
error && error.stack ? error.stack : error
);
}
2018-04-27 21:25:04 +00:00
},
});
2016-08-15 22:36:29 +00:00
})();