Skip to content

Instantly share code, notes, and snippets.

@yoamomonstruos
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yoamomonstruos/2c322e8e7284358bb17c to your computer and use it in GitHub Desktop.
Save yoamomonstruos/2c322e8e7284358bb17c to your computer and use it in GitHub Desktop.
Recorder Directive
/* this is just the basic formatting */
.recorder:after,
.recorder__btn-group:after {
content: "";
display: table;
clear: both;
}
.recorder__btn-group,
.recorder__timer {
display: block;
float: left;
position: relative;
}
.recorder__btn-group__btn {
display: block;
float: left;
width: 40px;
height: 40px;
margin: 0;
color: #333;
background: #FFF;
outline: 0;
border: 1px solid #CCC;
border-right: 0;
}
.recorder__btn-group__btn.is-active { color: #EEE; }
.recorder__btn-group__btn:first-child {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
.recorder__btn-group__btn:last-child {
border-right: 1px solid #CCC;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
.recorder__timer {
margin: 0 15px;
height: 40px;
line-height: 40px;
}
.recorder__submit {
display: none;
clear: left;
}
.recorder__submit.is-active {
display: block;
}
'use strict';
/* Directives */
angular.module('myApp.directives', []).
directive('recorder', ['$interval', '$window', function($interval, $window) {
return {
restrict: "E",
link: function($scope, element, attributes) {
$scope.recorder = null;
$scope.audioContext = null;
$scope.isPlaying = false;
$scope.isRecording = false;
$scope.hasRecorded = false;
$scope.currentRecordingLength = 0;
$scope.currentRecordingIntervalId = null;
function setupRecorder (stream) {
var audioInput, audioGain;
audioInput = $scope.audioContext.createMediaStreamSource(stream);
audioGain = $scope.audioContext.createGain();
audioGain.gain.value = 0;
audioInput.connect(audioGain);
audioGain.connect($scope.audioContext.destination);
$scope.recorder = new Recorder(audioInput);
}
try {
$window.AudioContext = $window.AudioContext || $window.webkitAudioContext;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia
$scope.audioContext = new AudioContext();
navigator.getUserMedia({ audio: true }, setupRecorder, function(err) {});
}
catch (error) {
return false;
}
$scope.formatSeconds = function (seconds) {
var minutes = parseInt( seconds / 60 ) % 60;
var seconds = seconds % 60;
var result = (minutes < 10 ? "0" + minutes : minutes) + ":"
+ (seconds < 10 ? "0" + seconds : seconds);
return result;
}
$scope.toggleRecording = function() {
if (!this.recorder) { return false; }
if (this.isRecording === false) {
this.hasRecorded = true;
this.recorder.record();
this.currentRecordingIntervalId = $interval(function() {
$scope.currentRecordingLength++;
}, 1000);
}
else {
this.recorder.stop();
$interval.cancel(this.currentRecordingIntervalId);
}
this.isRecording = !this.isRecording;
}
$scope.playbackRecording = function() {
if (this.hasRecorded) {
this.recorder.getBuffer(function(buffers) {
var newSource, newBuffer;
newSource = $scope.audioContext.createBufferSource();
newBuffer = $scope.audioContext.createBuffer(2, buffers[0].length, $scope.audioContext.sampleRate);
newBuffer.getChannelData(0).set(buffers[0]);
newBuffer.getChannelData(1).set(buffers[1]);
newSource.buffer = newBuffer;
newSource.connect($scope.audioContext.destination);
newSource.start(0);
});
}
}
$scope.submitRecording = function() {
this.recorder.exportWAV(function(wav) {
var url = URL.createObjectURL(wav);
var win = $window.open(url, '_blank');
win.focus();
});
}
$scope.clearRecording = function() {
$scope.hasRecorded = false;
$scope.currentRecordingLength = 0;
$scope.recorder.clear();
}
},
templateUrl: "partials/recorder.html",
replace: true,
}
}]);
<div class="recorder">
<div class="recorder__btn-group">
<button class="recorder__btn-group__btn" ng-click="toggleRecording()">
{{ isRecording ? 'stop' : 'record' }}
</button>
<button class="recorder__btn-group__btn" ng-click="playbackRecording()" ng-class="{ 'is-active': hasRecorded && !isRecording }">
&#9654;
</button>
</div>
<div class="recorder__timer">
{{ formatSeconds(currentRecordingLength) }}
</div>
<div class="recorder__btn-group">
<button class="recorder__btn-group__btn" ng-click="clearRecording()">Clear</button>
</div>
<div class="recorder__submit" ng-class="{ 'is-active': hasRecorded && !isRecording }">
<button ng-click="submitRecording()">Done</button>
</div>
</div>
bower install --save Recorderjs

Then change line 3 in recorder.js

  var WORKER_PATH = 'bower_components/Recorderjs/recorderWorker.js';
<!-- To show a recorder element just show -->
<recorder></recorder>
<!-- /end -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment