2014-07-01 34 views
9

Poszukuję trybu opartego na przeglądarce , dopóki nie nastąpi cisza.HTML Nagrywanie dźwięku do momentu ciszy?

HTML nagrywanie dźwięku z mikrofonu jest możliwe w Firefoksie i Chrome - używając Recordmp3js patrz: http://nusofthq.com/blog/recording-mp3-using-only-html5-and-javascript-recordmp3-js/ a kod na github: http://github.com/nusofthq/Recordmp3js

nie widzę sposobu, aby zmienić ten kod do chwili cisza.

Record aż ciszy można zrobić (i dostrojony) przy użyciu języka Java dla natywnej aplikacji dla Androida - patrz tutaj: Android audio capture silence detection

Google Voice Search pokazuje przeglądarka może Doit - ale w jaki sposób można za pomocą JavaScript? Jakieś pomysły?

+0

Jestem pewien, że można ustalić to z kodu stosowanego w wykrywaniu tonu: https://github.com/cwilso/pitchdetect – Ian

+0

Czy chcesz mieć prawdziwą cyfrową ciszę lub poziom dźwięku poniżej progu? – Brad

+0

zrobi mi prosty próg. – GavinBrelstaff

Odpowiedz

9

Jeśli korzystasz z interfejsu Web Audio API, otwórz przechwytywanie dźwięku na żywo z mikrofonu, wykonując wywołanie: navigator.getUserMedia, a następnie utwórz węzeł za pomocą: createScriptProcessor, a następnie przypisz do tego węzła wywołanie zwrotne dla jego zdarzenia: onaudioprocess . Wewnątrz funkcji zwrotnej (poniżej używam script_processor_analysis_node) masz dostęp do bufora audio na żywo w czasie rzeczywistym, do którego możesz następnie przeanalizować szukanie ciszy (trochę czasu, gdy amplituda jest niska [pozostaje blisko zera]).

za normalny czas krzywa dźwięku domeny patrz: array_time_domain która jest wypełniona świeże po każdym wywołaniu callback script_processor_analysis_node ... podobnie do dziedziny częstotliwości zobaczyć array_freq_domain

Turn down swojej objętości głośników lub używać słuchawek, aby uniknąć zwrotne od mikrofonu -> głośniki -> mic ...

<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<title>capture microphone then show time & frequency domain output</title> 

<script type="text/javascript"> 

var webaudio_tooling_obj = function() { 

    var audioContext = new AudioContext(); 

    console.log("audio is starting up ..."); 

    var BUFF_SIZE_RENDERER = 16384; 

    var audioInput = null, 
    microphone_stream = null, 
    gain_node = null, 
    script_processor_node = null, 
    script_processor_analysis_node = null, 
    analyser_node = null; 

    if (!navigator.getUserMedia) 
     navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || 
    navigator.mozGetUserMedia || navigator.msGetUserMedia; 

    if (navigator.getUserMedia){ 

     navigator.getUserMedia({audio:true}, 
      function(stream) { 
       start_microphone(stream); 
      }, 
      function(e) { 
       alert('Error capturing audio.'); 
      } 
      ); 

    } else { alert('getUserMedia not supported in this browser.'); } 

    // --- 

    function show_some_data(given_typed_array, num_row_to_display, label) { 

     var size_buffer = given_typed_array.length; 
     var index = 0; 

     console.log("__________ " + label); 

     if (label === "time") { 

      for (; index < num_row_to_display && index < size_buffer; index += 1) { 

       var curr_value_time = (given_typed_array[index]/128) - 1.0; 

       console.log(curr_value_time); 
      } 

     } else if (label === "frequency") { 

      for (; index < num_row_to_display && index < size_buffer; index += 1) { 

       console.log(given_typed_array[index]); 
      } 

     } else { 

      throw new Error("ERROR - must pass time or frequency"); 
     } 
    } 

    function process_microphone_buffer(event) { 

     var i, N, inp, microphone_output_buffer; 

     microphone_output_buffer = event.inputBuffer.getChannelData(0); // just mono - 1 channel for now 
    } 

    function start_microphone(stream){ 

     gain_node = audioContext.createGain(); 
     gain_node.connect(audioContext.destination); 

     microphone_stream = audioContext.createMediaStreamSource(stream); 
     microphone_stream.connect(gain_node); 

     script_processor_node = audioContext.createScriptProcessor(BUFF_SIZE_RENDERER, 1, 1); 
     script_processor_node.onaudioprocess = process_microphone_buffer; 

     microphone_stream.connect(script_processor_node); 

     // --- enable volume control for output speakers 

     document.getElementById('volume').addEventListener('change', function() { 

      var curr_volume = this.value; 
      gain_node.gain.value = curr_volume; 

      console.log("curr_volume ", curr_volume); 
     }); 

     // --- setup FFT 

     script_processor_analysis_node = audioContext.createScriptProcessor(2048, 1, 1); 
     script_processor_analysis_node.connect(gain_node); 

     analyser_node = audioContext.createAnalyser(); 
     analyser_node.smoothingTimeConstant = 0; 
     analyser_node.fftSize = 2048; 

     microphone_stream.connect(analyser_node); 

     analyser_node.connect(script_processor_analysis_node); 

     var buffer_length = analyser_node.frequencyBinCount; 

     var array_freq_domain = new Uint8Array(buffer_length); 
     var array_time_domain = new Uint8Array(buffer_length); 

     console.log("buffer_length " + buffer_length); 

     script_processor_analysis_node.onaudioprocess = function() { 

      // get the average for the first channel 
      analyser_node.getByteFrequencyData(array_freq_domain); 
      analyser_node.getByteTimeDomainData(array_time_domain); 

      // draw the spectrogram 
      if (microphone_stream.playbackState == microphone_stream.PLAYING_STATE) { 

       show_some_data(array_freq_domain, 5, "frequency"); 
       show_some_data(array_time_domain, 5, "time"); // store this to record to aggregate buffer/file 

// examine array_time_domain for near zero values over some time period 

      } 
     }; 
    } 

}(); // webaudio_tooling_obj = function() 

</script> 

</head> 
<body> 

    <p>Volume</p> 
    <input id="volume" type="range" min="0" max="1" step="0.1" value="0.5"/> 

</body> 
</html> 
+0

to brzmi obiecująco, że przyjrzę się - i wrócę jak najszybciej. – GavinBrelstaff

+1

Hej Scott i @GavinBrelstaff Jak to mi powie, kiedy jest cicho. Chcę osiągnąć coś podobnego i chcę wywołać funkcję, gdy jest cicho, a użytkownik zakończy wprowadzanie głosowe – Adeel

0

jest to stary post, ale jestem pewien, że wielu będzie miał ten sam problem, więc jestem delegowania moje rozwiązanie tutaj. Zastosowanie hark.js

Poniżej przykładowy kod demo użyłem do mojego app elektronów

hark = require('./node_modules/hark/hark.bundle.js') 

    navigator.getUserMedia({ audio : true}, onMediaSuccess, function(){}); 

    function onMediaSuccess(blog) { 

    var options = {}; 
    var speechEvents = hark(blog, options); 

    speechEvents.on('speaking', function() { 
     console.log('speaking'); 
    }); 

    speechEvents.on('stopped_speaking', function() { 
     console.log('stopped_speaking'); 
    }); 
    };