how to export last 3s data of a web audio stream

孤街浪徒 提交于 2020-01-17 01:30:10

问题


Question: I am using web audio API. I need to buffer a non-stop audio stream, like a radio stream. and when I get a notification, I need to get the past 3s audio data and send it to server. How can I do achieve that? nodejs has a built in buffer, but it seems not a circular buffer, if I write a non-stop stream into it, it seems to be overflowed.

Background to help u understand my question: I am implementing an ambient audio based web authentication method. Briefly, I need to compare two pieces of audio signal (one from the client, and one from the anchor device, they are all time synced with server), if they are similar enough, the authentication request will be approved by the server. The audio recording is implemented on both the client and the anchor device using web Audio API.

I need to manage a buffer on the anchor device to stream the ambient audio. The anchor device is supposed to be running all the time, so the stream is not going to be ended.


回答1:


You can capture the audio from a stream using the ScriptProcessorNode. Whilst this is deprecated no browser as of now actually implements the new AudioWorker.

var N = 1024;
var time = 3; // Desired time of capture;
var frame_holder = [];
var time_per_frame = N / context.sampleRate;
var num_frames = Math.ceil(time / time_per_frame); // Minimum number to meet time
var script = context.createScriptProcessor(N,1,1);
script.connect(context.destination);

script.onaudioprocess = function(e) {
  var input = e.inputBuffer.getChannelData(0);
  var output = e.outputBuffer.getChannelData(0);
  var copy = new Float32Array(input.length);
  for (var n=0; n<input.length; n++) {
    output[n] = 0.0; // Null this as I guess you are capturing microphone
    copy[n] = input[n];
  }
  // Now we need to see if we have more than 3s worth of frames
  if (frame_holder.length > num_frames) {
    frame_holder = frame_holder.slice(frame_holder.length-num_frames);
  }
  // Add in the current frame
  var temp = frame_holder.slice(1); // Cut off first frame;
  frame_holder = temp.concat([copy]); // Add the latest frame
}

Then for actual transmission, you just need to string the copied frames together. It is easier than trying to keep one long array though of course that is also possible.



来源:https://stackoverflow.com/questions/37728518/how-to-export-last-3s-data-of-a-web-audio-stream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!