2014-07-01 60 views
9

我正在尋找一種基於瀏覽器的方式錄製,直到發生沉默HTML錄音直到沉默?

HTML從麥克風錄音,可以在Firefox和Chrome - 使用 Recordmp3js看到: http://nusofthq.com/blog/recording-mp3-using-only-html5-and-javascript-recordmp3-js/ 並在GitHub上的代碼:http://github.com/nusofthq/Recordmp3js

我看不到的方式來改變這種代碼記錄,直到安靜。看到這裏 -

紀錄直到沉默可以使用Java的原生Android應用程序來完成(和調整): Android audio capture silence detection

Google Voice Search演示了一個瀏覽器就可以DOIT - 但我怎麼能使用Javascript? 任何想法?

+0

我敢肯定,你可以從間距檢測中使用的代碼看着辦吧:https://github.com/cwilso/pitchdetect – Ian

+0

你想要真正的數字靜音,或低於閾值的聲音級別? – Brad

+0

一個簡單的閾值會對我有用。 – GavinBrelstaff

回答

9

如果您使用Web Audio API,請通過調用:navigator.getUserMedia打開一個實時麥克風音頻捕獲,然後使用createScriptProcessor創建一個節點,然後爲該節點分配一個針對其事件的回調函數:onaudioprocess 。在你的回調函數中(在下面我使用script_processor_analysis_node),你可以訪問實時音頻緩衝區,然後你可以解析它尋找靜音(幅度低[保持接近於零]的某個時間長度)。

正常時域音頻曲線看:array_time_domain 其中填充新鮮在每次調用回調script_processor_analysis_node ......同樣,對於頻域看array_freq_domain

調低揚聲器音量或者使用耳機,以避免麥克風反饋 - >音箱 - >麥克風...

<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

聽起來很有希望我會看看 - 並儘快找回 – GavinBrelstaff

+1

嘿斯科特和@GavinBrelstaff 這是如何告訴我什麼時候它是沉默的。我想要實現類似的功能,並且在靜音和用戶完成語音輸入時要觸發某個功能 – Adeel

0

這是一個老的文章,但我相信很多人都會有同樣的問題,所以我在這裏發佈我的解決方案。 使用hark.js

下面是示例演示代碼,我用我的電子應用

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