Reputation: 253
I use this HTML and JS code, which I downloaded from the web to record audio, but there is a problem because after the page is loaded on the screen immediatelly appears message to allow microphone. It is because of window.onload = function init()
in source code record.js. But I want to show the message after clicking on button.
For this reason I tried to call two functions with this button - toggleRecording(button)
and init()
but there was a problem with "button" element, so it didn't work, but I think it could work if it will be written in good form. Can you show me example how to modify this two functions init
and toggleRecording
to be called by this button? I am new in JS and I don't know how it works exactly.
index.html
<button type="submit" onclick="toggleRecording()" data-run="0"></button>
record.js
//starts by click on button
function toggleRecording() {
var run = parseInt(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('Systém 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);
});
};
UPDATE:
Now this system works in this steps:
1. function init()
runs immediatelly when page is loaded and after user allows microphone then startusermedia
function runs
2.after clicking on button runs toggleRecording(button)
function which starts recording
3.second click on button runs toggleRecording
function which stop recording
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
Upvotes: 3
Views: 2451
Reputation: 32175
In your case the init
function is directly attached to the window.onload
event and can't be called with the button, to ensure its call in the two events declare it as a global function and then attach it to the onload event like this:
JavaScript:
//function declaration
init = 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);
});
};
//Call
window.onload = init();
HTML:
<button type="submit" onclick="init();toggleRecording()" data-run="0"></button>
That should do it.
In order to achieve what you want, you have to attach the init()
function to the window.onload
event and the toggleRecording()
function to the onclick event of the run button
, like this:
//Call
window.onload = init();
document.getElementById("run").onclick = toggleRecording();
And give your button the id="run"
:
<button type="submit" id="run" onclick="init();toggleRecording()" data-run="0"></button>
Upvotes: 0
Reputation: 5379
It's not working because init()
is actually a variable attached to window.onload
. Try removing window.onload=function init()
and replacing it with just function init()
(so it no longer runs when the page loads), then call:
<button type="submit" onclick="init();toggleRecording()" data-run="0"></button>
When you're setting up event handlers like that, you don't even need to give the function a name. Something like window.onload = function() { ... }
is perfectly valid - they're called anonymous functions.
I also noticed some implementation troubles with toggleRecording()
, so I've done my best to fix those too. getAttribute()
needs an element, of course, so we can pass the button using this
, and receive it in toggleRecording()
as the button
variable.
Your full code is now:
//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) {
//TODO: Uncomment this, I have it commented so there are no errors in the StackSnippet
//showInfo("\n" + e + " " + (data || ''));
console.log(e.data);
}
var audio_context;
var recorder;
function startUserMedia(stream) {
var input = audio_context.createMediaStreamSource(stream);
recorder = new Recorder(input);
__log('Systém for recording is available.');
}
function startRecording(button) {
recorder && recorder.clear();
recorder && recorder.record();
button.nextElementSibling.disabled = false;
__log('Talk...');
}
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);
});
};
<button onclick="init(); toggleRecording(this)">Click me</button>
Upvotes: 2
Reputation: 2559
If you want to make the code work after the Button is pressed, you should remove the onload
event, because this will make the code work after the page is loaded.
You can create a second function and place it in there, Example:
function secondFunction(){
// Put Code inside here
}
In the toggleRecording(button)
function you can call like:
function toggleRecording(button) {
// .. the existing code
secondFunction();
}
If you want the second called first, place it over your existing code.
You also could to following:
<button type="submit" onclick="toggleRecording();init();" data-run="0"></button>
But you still need to remove the onload
event and wrap it around a function like above.
You also could do following (recommended):
<button id="record" type="submit" onclick="toggleRecording()" data-run="0"</button>
Code:
var button = document.getElementById( 'record' );
var button.onclick = function(e){
toggleRecording(e);
secondFunction();
}
Also again.. remove the onload
event if you don't want to do it when the page has loaded.
The last example selects the button element with the ID record
(I added it to your button
-Tag) and adds an onclick
-Event on it with onclick = function(){}
which will be called when "onclick" of course.
Last but least: Don't just copy code, try to understand it so you can solve your problems easily by yourself :)
Upvotes: 0
Reputation: 1816
You can attach multiple actions to a button programmatically using addEventListener
if you wanted to.
So you may have:
<button id="test" type="submit" onclick="toggleRecording()" data-run="0"></button>
<script>
var btn = document.getElementById("test");
btn.addEventListener("click", init);
btn.addEventListener("click", toggleRecording);
// More if wanted.
</script>
Upvotes: 0