3

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

  1. 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)

Community
  • 1
  • 1
Nikolaus
  • 253
  • 2
  • 15
  • var run = parseInt(getAttribute('data-run')); you try to get the attribute data-run, on NOTHING.... this is the problem... you have to get the attribute from the button, like you're doing below in your code... – Julo0sS Apr 23 '15 at 09:40
  • 1
    var run = parseInt(button.getAttribute('data-run')); .............. – Julo0sS Apr 23 '15 at 09:42
  • @Julo0sS question was updated. I tried it with "button" element, but it work in the same way and also the same error message is shown. – Nikolaus Apr 23 '15 at 10:32

3 Answers3

0

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.

kemicofa ghost
  • 16,349
  • 8
  • 82
  • 131
  • I modified it to: function toggleRecording(button), { var run = parseInt(button.getAttribute('data-run')); button.setAttribute('data-run', 0); } but the same error is shown :( – Nikolaus Apr 23 '15 at 10:14
  • no it works in the same way as it was without "button", so it doesnt work correctly. – Nikolaus Apr 23 '15 at 10:21
  • Where do you initialize your button variable? Is it correctly initialized? If you do console.log(button) what does it show? – kemicofa ghost Apr 23 '15 at 10:34
0

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 || ''));
};

DEMO

code-jaff
  • 9,230
  • 4
  • 35
  • 56
  • BTW, you should be accepting answers for previous questions, if they've actually answered your questions. – code-jaff Apr 23 '15 at 11:53
0

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);
}
Rony Macfly
  • 210
  • 2
  • 4
  • 10