Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #5627 : Stop recording should stop microphone and angular-recorder should be replaced. #6708

Merged
merged 34 commits into from
Jun 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
6bc598c
added base functional recording service to replace angular-recorder. …
mzaman07 May 7, 2019
e7210a0
Something wrong with rootScope loadingMessage when you change state t…
mzaman07 May 7, 2019
c85f282
lint fixed
mzaman07 May 7, 2019
3cf277c
webworker compilation in ts set
mzaman07 May 7, 2019
69881bc
reverted tsconfig.json and added karma framework thread loading check…
mzaman07 May 7, 2019
d7f0848
lint fixes
mzaman07 May 7, 2019
c086c4f
updated branch and fixed merge conflicts.
mzaman07 May 17, 2019
874ca92
Changed mp3Conveter to a ts-compiler friendly version.
mzaman07 May 17, 2019
d4f638c
lint fixes
mzaman07 May 17, 2019
5dd9f42
Merge remote-tracking branch 'upstream/develop' into mp3-recorder
mzaman07 May 18, 2019
722938e
used in library realtime worker and changed time duration so that the…
mzaman07 May 19, 2019
30955ba
Merge remote-tracking branch 'upstream/develop' into mp3-recorder
mzaman07 May 19, 2019
394585e
lint and extra fixes
mzaman07 May 19, 2019
0dd2a5f
Added web audio api typedefs and using webworker typedefs for FileRea…
mzaman07 May 21, 2019
434e5b8
readded audio recording preview for unsaved recording.
mzaman07 May 21, 2019
19ee5e7
Merge remote-tracking branch 'upstream/develop' into mp3-recorder
mzaman07 May 21, 2019
d643d3d
Added wave-surfer back into recording. Changed from FileReader Api ba…
mzaman07 May 21, 2019
8f8527d
lint fixes
mzaman07 May 21, 2019
dc20ba3
more lint fixes is final now.
mzaman07 May 21, 2019
b5b1bcc
Merge remote-tracking branch 'upstream/develop' into mp3-recorder
mzaman07 May 21, 2019
879ab52
fixed typescript based issue
mzaman07 May 22, 2019
858ce62
removed references to angular-recorder/angular-audio-recorder
mzaman07 May 22, 2019
0541cf3
fixed duplication of canvas on multiple re-records
mzaman07 May 22, 2019
ce59d5c
fixed based on review
mzaman07 May 27, 2019
d67f435
fixed missed error.
mzaman07 May 27, 2019
22affb6
fixed audioContext referencing and VoiceoverRecorderService to be set…
mzaman07 May 27, 2019
acadf01
lint checks
mzaman07 May 27, 2019
37f06b9
lint fix
mzaman07 May 27, 2019
61c47f6
Sorted require() alphabetically in ascending order and removed @types…
mzaman07 May 27, 2019
cf8566f
Merge remote-tracking branch 'upstream/develop' into mp3-recorder
mzaman07 May 30, 2019
1b269cd
changed AppInit.ts for improved readability.
mzaman07 May 30, 2019
2ff1664
Merge remote-tracking branch 'upstream/develop' into mp3-recorder
mzaman07 Jun 1, 2019
a5ebd6c
Changed comments to be a full sentence and switched variable to prope…
mzaman07 Jun 1, 2019
49bf1b7
Corrected comment because action is singular as opposed to plural.
mzaman07 Jun 1, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions core/templates/dev/head/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,13 +257,6 @@ oppia.config(['toastrConfig', function(toastrConfig) {
});
}]);

oppia.config(['recorderServiceProvider', function(recorderServiceProvider) {
recorderServiceProvider.forceSwf(false);
recorderServiceProvider.withMp3Conversion(true, {
bitRate: 128
});
}]);

// Overwrite the built-in exceptionHandler service to log errors to the backend
// (so that they can be fixed).
oppia.factory('$exceptionHandler', ['$log', function($log) {
Expand Down
8 changes: 4 additions & 4 deletions core/templates/dev/head/AppInit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@

var oppia = angular.module(
'oppia', [
'angularAudioRecorder', 'dndLists', 'headroom', 'infinite-scroll',
'ngAnimate', 'ngAudio', 'ngCookies', 'ngImgCrop', 'ngJoyRide', 'ngMaterial',
'ngResource', 'ngSanitize', 'ngTouch', 'pascalprecht.translate', 'toastr',
'ui.bootstrap', 'ui.sortable', 'ui.tree', 'ui.validate'
'dndLists', 'headroom', 'infinite-scroll', 'ngAnimate',
'ngAudio', 'ngCookies', 'ngImgCrop', 'ngJoyRide', 'ngMaterial',
'ngResource', 'ngSanitize', 'ngTouch', 'pascalprecht.translate',
'toastr', 'ui.bootstrap', 'ui.sortable', 'ui.tree', 'ui.validate'
].concat(
window.GLOBALS ? (window.GLOBALS.ADDITIONAL_ANGULAR_MODULES || []) : []));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ require(
require(
'pages/exploration_editor/translation_tab/' +
'TranslationTabActiveContentIdService.ts');
require(
'pages/exploration_editor/translation_tab/VoiceoverRecordingService.ts');
require('pages/state_editor/state_properties/StateEditorService.ts');
require('pages/state_editor/state_properties/StatePropertyService.ts');
require(
Expand All @@ -45,7 +47,7 @@ oppia.directive('audioTranslationBar', [
isTranslationTabBusy: '='
},
link: function(scope: ICustomScope, elm) {
scope.getRecorderController();
scope.getVoiceoverRecorder();

$('.oppia-translation-tab').on('dragover', function(evt) {
evt.preventDefault();
Expand Down Expand Up @@ -81,25 +83,24 @@ oppia.directive('audioTranslationBar', [
'/pages/exploration_editor/translation_tab/' +
'audio_translation_bar_directive.html'),
controller: [
'$filter', '$rootScope', '$scope', '$timeout', '$uibModal',
'$filter', '$interval', '$rootScope', '$scope', '$uibModal', '$window',
'AlertsService', 'AssetsBackendApiService', 'AudioPlayerService',
'ContextService', 'EditabilityService', 'ExplorationStatesService',
'IdGenerationService', 'SiteAnalyticsService',
'StateEditorService', 'StateRecordedVoiceoversService',
'TranslationLanguageService', 'recorderService',
'TranslationTabActiveContentIdService', 'RECORDING_TIME_LIMIT',
'TranslationLanguageService', 'TranslationTabActiveContentIdService',
'RECORDING_TIME_LIMIT', 'VoiceoverRecordingService',
function(
$filter, $rootScope, $scope, $timeout, $uibModal,
$filter, $interval, $rootScope, $scope, $uibModal, $window,
AlertsService, AssetsBackendApiService, AudioPlayerService,
ContextService, EditabilityService, ExplorationStatesService,
IdGenerationService, SiteAnalyticsService,
StateEditorService, StateRecordedVoiceoversService,
TranslationLanguageService, recorderService,
TranslationTabActiveContentIdService, RECORDING_TIME_LIMIT) {
$scope.RECORDER_ID = 'recorderId';
TranslationLanguageService, TranslationTabActiveContentIdService,
RECORDING_TIME_LIMIT, VoiceoverRecordingService) {
$scope.recordingTimeLimit = RECORDING_TIME_LIMIT;
$scope.audioBlob = null;
$scope.recorder = null;
$scope.voiceoverRecorder = null;
$scope.unsupportedBrowser = false;
$scope.selectedRecording = false;
$scope.isAudioAvailable = false;
Expand All @@ -113,6 +114,10 @@ oppia.directive('audioTranslationBar', [
$scope.checkingMicrophonePermission = false;
$scope.audioTimerIsShown = true;
$scope.audioIsCurrentlyBeingSaved = false;
$scope.elapsedTime = 0;
$scope.timerInterval = null;
$scope.unsavedAudioIsPlaying = false;
$scope.waveSurfer = null;
mzaman07 marked this conversation as resolved.
Show resolved Hide resolved
document.body.onkeyup = function(e) {
if (e.keyCode === 82 && !$scope.isAudioAvailable) {
// 82 belongs to the keycode for 'R'
Expand All @@ -136,30 +141,23 @@ oppia.directive('audioTranslationBar', [
}
};

var cancelTimer = function() {
if ($scope.timerInterval) {
$interval.cancel($scope.timerInterval);
}
};

var generateNewFilename = function() {
return $scope.contentId + '-' +
$scope.languageCode + '-' +
IdGenerationService.generateNewId() + '.mp3';
};

$scope.onRecordStart = function() {
$scope.showRecorderWarning = true;
$scope.isTranslationTabBusy = true;
};

$scope.onConversionComplete = function() {
$rootScope.loadingMessage = '';
};

var getTranslationTabBusyMessage = function() {
var message = '';
if ($scope.recorder.status.isRecording) {
if ($scope.isRecording) {
message = 'You haven\'t finished recording. Please stop ' +
'recording and either save or cancel the recording.';
} else if ($scope.recorder.status.isConverting) {
message = 'It seems like recorded audio is still getting ' +
'converted into mp3. Please wait until the audio has finished' +
' processing.';
} else if ($scope.showRecorderWarning) {
message = 'You haven\'t saved your recording. Please save or ' +
'cancel the recording.';
Expand All @@ -168,29 +166,38 @@ oppia.directive('audioTranslationBar', [
};
var showPermissionAndStartRecording = function() {
$scope.checkingMicrophonePermission = true;
recorderService.showPermission({
onDenied: function() {
$scope.recordingPermissionDenied = true;
$scope.cannotRecord = true;
$scope.checkingMicrophonePermission = false;
},
onAllowed: function() {
$scope.recordingPermissionDenied = false;
$scope.cannotRecord = false;
$scope.recorder.startRecord();
$scope.selectedRecording = true;
$scope.checkingMicrophonePermission = false;
},
onClosed: function() {
$scope.recordingPermissionDenied = true;
$scope.cannotRecord = true;
$scope.checkingMicrophonePermission = false;
},
$scope.voiceoverRecorder.startRecording().then(function() {
// When the user accepts the microphone access.
$scope.showRecorderWarning = true;
$scope.isTranslationTabBusy = true;

$scope.recordingPermissionDenied = false;
$scope.cannotRecord = false;
$scope.selectedRecording = true;
$scope.checkingMicrophonePermission = false;

$scope.elapsedTime = 0;
$scope.timerInterval = $interval(function() {
$scope.elapsedTime++;
// $scope.recordingTimeLimit is decremented to
// compensate for the audio recording timing inconsistency,
// so it allows the server to accept the recording.
if ($scope.elapsedTime === $scope.recordingTimeLimit - 1) {
$scope.stopRecording();
}
}, 1000);
}, function() {
// When the user denies microphone access.
$scope.recordingPermissionDenied = true;
$scope.cannotRecord = true;
$scope.checkingMicrophonePermission = false;
$scope.$apply();
});
};

$scope.checkAndStartRecording = function() {
if (!$scope.recorder.isAvailable) {
$scope.voiceoverRecorder.initRecorder();
if (!$scope.voiceoverRecorder.status().isAvailable) {
$scope.unsupportedBrowser = true;
$scope.cannotRecord = true;
} else {
Expand All @@ -207,14 +214,15 @@ oppia.directive('audioTranslationBar', [
$scope.audioNeedsUpdate = !$scope.audioNeedsUpdate;
};

$scope.getRecorderController = function() {
$scope.recorder = recorderService.controller($scope.RECORDER_ID);

$scope.getVoiceoverRecorder = function() {
$scope.voiceoverRecorder = VoiceoverRecordingService;
};

$scope.reRecord = function() {
$scope.initAudioBar();
$scope.selectedRecording = false;
showPermissionAndStartRecording();
$scope.checkAndStartRecording();
};

$scope.cancelRecording = function() {
Expand All @@ -225,13 +233,49 @@ oppia.directive('audioTranslationBar', [
$scope.showRecorderWarning = false;
};

$scope.stopRecording = function() {
$scope.voiceoverRecorder.stopRecord();
$scope.recordingComplete = true;
cancelTimer();
$scope.voiceoverRecorder.getMp3Data().then(function(audio) {
var fileType = 'audio/mp3';
$scope.audioBlob = new Blob(audio, {type: fileType});
// Free the browser from web worker.
$scope.voiceoverRecorder.closeRecorder();
// Create audio play and pause for unsaved recording.
var url = $window.URL.createObjectURL($scope.audioBlob);
// Create visualizer for playing unsaved audio.
$scope.waveSurfer = $window.WaveSurfer.create({
container: '#visualized',
waveColor: '#009688',
progressColor: '#cccccc',
height: 38
});
$scope.waveSurfer.load(url);
});
};

// Play and pause for unsaved recording.
$scope.playAndPauseUnsavedAudio = function() {
$scope.unsavedAudioIsPlaying = !$scope.unsavedAudioIsPlaying;
if ($scope.unsavedAudioIsPlaying) {
$scope.waveSurfer.play();
$scope.waveSurfer.on('finish', function() {
$scope.unsavedAudioIsPlaying = false;
$scope.$apply();
});
} else {
$scope.waveSurfer.pause();
}
};

$scope.updateAudio = function() {
AudioPlayerService.stop();
AudioPlayerService.clear();
$scope.audioBlob = null;
$scope.audioIsUpdating = true;
$scope.selectedRecording = false;
showPermissionAndStartRecording();
$scope.checkAndStartRecording();
};

$scope.saveRecordedAudio = function() {
Expand Down Expand Up @@ -270,19 +314,17 @@ oppia.directive('audioTranslationBar', [
return;
}

if (!$scope.recorder.status.isRecording && !$scope.audioBlob) {
if (!$scope.isRecording && !$scope.audioBlob) {
$scope.checkAndStartRecording();
} else {
$scope.recorder.stopRecord();
$scope.stopRecording();
}
};

$scope.$on('externalSave', function() {
if ($scope.recorder && $scope.recorder.status.isPlaying) {
$scope.recorder.playbackPause();
}
if (recorderService.getHandler()) {
recorderService.getHandler().clear();
if ($scope.voiceoverRecorder.status().isRecording) {
$scope.voiceoverRecorder.stopRecord();
$scope.voiceoverRecorder.closeRecorder();
}
AudioPlayerService.stop();
AudioPlayerService.clear();
Expand Down Expand Up @@ -375,28 +417,23 @@ oppia.directive('audioTranslationBar', [
};

$scope.initAudioBar = function() {
// This stops angular-recorder when user navigate while recording.
if ($scope.recorder) {
if ($scope.recorder.status.isPlaying) {
$scope.recorder.playbackPause();
}
if ($scope.recorder.status.isRecording &&
// This stops the voiceoverRecorder when user navigates
// while recording.
if ($scope.voiceoverRecorder) {
if ($scope.voiceoverRecorder.status().isRecording &&
$scope.showRecorderWarning) {
$scope.recorder.stopRecord();
$rootScope.loadingMessage = 'loading';
}
if ($scope.recorder.status.isConverting) {
$rootScope.loadingMessage = 'loading';
}
if (recorderService && recorderService.getHandler()) {
recorderService.getHandler().stop();
recorderService.getHandler().clear();
$scope.voiceoverRecorder.stopRecord();
cancelTimer();
$scope.voiceoverRecorder.closeRecorder();
}
}
$scope.isTranslationTabBusy = false;
AudioPlayerService.stop();
AudioPlayerService.clear();
$scope.showRecorderWarning = false;
// re-initialize for unsaved recording
$scope.unsavedAudioIsPlaying = false;
$scope.waveSurfer = null;
$scope.languageCode = TranslationLanguageService
.getActiveLanguageCode();
$scope.canTranslate = EditabilityService.isTranslatable();
Expand Down
Loading