'One button for more functions = recording in JavaScript
I have this source code to record audio in browser. Record.js calls another scripts that provides recording audio and save it to the server.
index.html
<button type="submit" onclick="toggleRecording()" data-run="0"></button>
record.js
//starts by click on button
function toggleRecording(button) {
var run = parseInt(button.getAttribute('data-run'));
if(run === 1) {
recorder && recorder.stop();
recorder && recorder.exportWAV(function(blob) {
uploadAudioFromBlob(blob);
});
__log('Recording is stopped');
button.setAttribute('data-run', 0);
}
else {
recorder && recorder.clear();
recorder && recorder.record();
__log('Speak...');
button.setAttribute('data-run', 1);
}
}
function __log(e, data) {
showInfo("\n" + e + " " + (data || ''));
}
var audio_context;
var recorder;
function startUserMedia(stream) {
var input = audio_context.createMediaStreamSource(stream);
recorder = new Recorder(input);
__log('System for recording is available.');
}
function startRecording(button) {
recorder && recorder.clear();
recorder && recorder.record();
button.nextElementSibling.disabled = false;
__log('Talk...');
}
window.onload=function init() {
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
window.URL = window.URL || window.webkitURL;
audio_context = new AudioContext;
} catch (e) {
alert('This browser do not support audio!');
}
navigator.getUserMedia({audio: true}, startUserMedia, function(e) {
__log('No audio was detected: ' + e);
});
};
Now this recording system works in this steps:
1.function init() runs immediatelly when page is loaded and after user allows microphone in message startusermedia function runs
- after clicking on button runs
toggleRecording(button)function which starts recording audio
3.second click on button runs toggleRecording function which stop recording audio.
I want to work this system in this steps if it is possible:
1. first click on button run functions init and startusermedia and togglerecording so recording will starts immediately after clicking
2. second click will call toggleRecording function to stop recording
I tried to modify record.js code, so I added this part to the top of the source code, so by click on button is called function start_KEMT in stead of toggleRecording(). Start_KEMT was created because I want to run functions in correct order.
Added part to the record.js
var recording = false;
var recordButton = document.getElementById('recordButton');
//function which is called by click on button
function start_KEMT() {
if(!recording)
{
init();
toggleRecording(recordButton);
}
toggleRecording(recordButton);
recording = !recording;
}
Also function init() was modified, so I change it from: window.onload = function init() to function init(). So it is called by clicking on button, not automatically by browser. Now it works in this way: After click on button it show message to allow microphone, after allowing message shows that: "'System for recording is available.' (function startUserMedia is called).After that recording doesnt start. After second click web browser message is showed again to allow mic. And this error is shown in console:
Uncaught TypeError: Cannot read property 'getAttribute' of null
Please give me any example how to do it right. I am new in JS. This topic is the same as: One button to run more functions JavaScript (recording audio in browser)
Solution 1:[1]
Well you are calling a method on nothing.
getAttribute('data-run'); should be something like this.getAttribute('data-run'); or button.getAttribute('data-run'); depending on the context.
Solution 2:[2]
May be you are looking for something like this
var audioContext;
var recorder;
var recording = false;
var initialized = false;
var recordButton = document.getElementById('recordBtn');
recordButton.addEventListener('click', start);
//function which is called by click on button
function start(e) {
e.preventDefault();
if (!initialized) {
init();
}
toggleRecording(e.target);
}
function init() {
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
window.URL = window.URL || window.webkitURL;
audioContext = new AudioContext();
} catch (e) {
alert('This browser do not support audio!');
}
navigator.getUserMedia({
audio: true
}, startUserMedia, function (e) {
__log('No audio was detected: ' + e);
});
initialized = true;
};
function startUserMedia(stream) {
var input = audioContext.createMediaStreamSource(stream);
recorder = new Recorder(input);
__log('System for recording is available.');
};
//starts by click on button
function toggleRecording(button) {
if (recording) {
recorder && recorder.stop();
recorder && recorder.exportWAV(function (blob) {
alert(blob.size);
});
__log('Recording is stopped');
recording = false;
button.innerText = "Start";
} else {
recorder && recorder.clear();
recorder && recorder.record();
__log('Speak...');
recording = true;
button.innerText = "Stop";
}
};
function __log(e, data) {
console.log("\n" + e + " " + (data || ''));
};
Solution 3:[3]
I used vanilla JavaScript.
<button id="audioRecordButton">RECORD</button>
Also added feature, if you do not stop recording after 10 seconds, the recording will automatically stop.
function recordAudioFromMicrophone()
{
var audioRecordButton = document.getElementById( "audioRecordButton" );
var isStartRec = true;
var mediaRecorder;
var time;
var run = function(stream)
{
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.addEventListener("dataavailable", getAudio);
audioRecordButton.addEventListener("click", recordHandler);
}
function recordHandler()
{
if(isStartRec)
{
startRec();
time = setTimeout(stopRec, 10000);
}
else
{
stopRec();
clearTimeout(time);
}
}
function startRec()
{
mediaRecorder.start();
isStartRec = false;
}
function stopRec()
{
mediaRecorder.stop();
isStartRec = true;
}
function getAudio(blob){...}
const enableAudio = { audio: true };
navigator.mediaDevices.getUserMedia(enableAudio).then(run);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | kemicofa ghost |
| Solution 2 | code-jaff |
| Solution 3 | Rony Macfly |
