나중에 AudioElement에 사용할 마이크 입력을 저장해야합니다. 나는이 얻을 수있는 마이크 입력을 수행마이크 오디오 입력을 저장하는 방법은 무엇입니까?
window.navigator.getUserMedia(audio: true).then((MediaStream stream) {
# what should go here?
});
나는 오디오를 저장하려면 어떻게해야합니까?
나중에 AudioElement에 사용할 마이크 입력을 저장해야합니다. 나는이 얻을 수있는 마이크 입력을 수행마이크 오디오 입력을 저장하는 방법은 무엇입니까?
window.navigator.getUserMedia(audio: true).then((MediaStream stream) {
# what should go here?
});
나는 오디오를 저장하려면 어떻게해야합니까?
현재 브라우저 창에서 현재 오디오 녹음을 재생할 수있는 수많은 끔찍한 예제가 있습니다. 이것을위한 유스 케이스가 존재 하는가? 비디오의 나는 ... 하나는 응용 프로그램과 같은 Skype를 구축하고 미리보기 당신이 비디오에 바보 보면 볼 수있는 창,하지만 오디오를 갖고 싶어 이미징 할 수
나는 하나 개의 좋은 포스트하지만 발견 : From microphone to .WAV with: getUserMedia and Web Audio데이터를 가져 오는 방법을 보여주는 링크 된 기사의 코드 일부를 이식했습니다.
import 'dart:html';
import 'dart:async';
import 'dart:web_audio';
void main() {
window.navigator.getUserMedia(video: true, audio: true).then((MediaStream stream) {
var context = new AudioContext();
GainNode volume = context.createGain();
MediaStreamAudioSourceNode audioInput = context.createMediaStreamSource(stream);
audioInput.connectNode(volume);
int bufferSize = 2048;
ScriptProcessorNode recorder = context.createJavaScriptNode(bufferSize, 2, 2);
recorder.onAudioProcess.listen((AudioProcessingEvent e) {
print('recording');
var left = e.inputBuffer.getChannelData(0);
var right = e.inputBuffer.getChannelData(1);
print(left);
// process Data
});
volume.connectNode(recorder);
recorder.connectNode(context.destination);
/**
* [How to get a file or blob from an object URL?](http://stackoverflow.com/questions/11876175)
* [Convert blob URL to normal URL](http://stackoverflow.com/questions/14952052/convert-blob-url-to-normal-url)
* Doesn't work as it seems blob urls are not supported in Dart
*/
// String url = Url.createObjectUrlFromStream(stream);
// var xhr = new HttpRequest();
// xhr.responseType = 'blob';
// xhr.onLoad.listen((ProgressEvent e) {
// print(xhr.response);
// var recoveredBlog = xhr.response;
// var reader = new FileReader();
//
// reader.onLoad.listen((e) {
// var blobAsDataUrl = reader.result;
// reader.readAsDataUrl(blobAsDataUrl);
// });
// });
// xhr.open('GET', url);
// xhr.send();
/**
* only for testing purposes
**/
// var audio = document.querySelector('audio') as AudioElement;
// audio.controls = true;
// audio.src = url;
});
}
this JS solution을 가리키는 Günter Zöchbauer에게 감사드립니다. 나는 Dart에서 코드를 다시 작성했고 작동한다.
import 'dart:html';
import 'dart:async';
import 'dart:web_audio';
import 'dart:typed_data';
bool recording;
List leftchannel;
List rightchannel;
int recordingLength;
int sampleRate;
void main() {
leftchannel = [];
rightchannel = [];
recordingLength = 0;
sampleRate = 44100;
recording = true;
// add stop button
ButtonElement stopBtn = new ButtonElement()
..text = 'Stop'
..onClick.listen((_) {
// stop recording
recording = false;
// we flat the left and right channels down
var leftBuffer = mergeBuffers (leftchannel, recordingLength);
var rightBuffer = mergeBuffers (rightchannel, recordingLength);
// we interleave both channels together
var interleaved = interleave(leftBuffer, rightBuffer);
// we create our wav file
var buffer = new Uint8List(44 + interleaved.length * 2);
ByteData view = new ByteData.view(buffer);
// RIFF chunk descriptor
writeUTFBytes(view, 0, 'RIFF');
view.setUint32(4, 44 + interleaved.length * 2, Endianness.LITTLE_ENDIAN);
writeUTFBytes(view, 8, 'WAVE');
// FMT sub-chunk
writeUTFBytes(view, 12, 'fmt ');
view.setUint32(16, 16, Endianness.LITTLE_ENDIAN);
view.setUint16(20, 1, Endianness.LITTLE_ENDIAN);
// stereo (2 channels)
view.setUint16(22, 2, Endianness.LITTLE_ENDIAN);
view.setUint32(24, sampleRate, Endianness.LITTLE_ENDIAN);
view.setUint32(28, sampleRate * 4, Endianness.LITTLE_ENDIAN);
view.setUint16(32, 4, Endianness.LITTLE_ENDIAN);
view.setUint16(34, 16, Endianness.LITTLE_ENDIAN);
// data sub-chunk
writeUTFBytes(view, 36, 'data');
view.setUint32(40, interleaved.length * 2, Endianness.LITTLE_ENDIAN);
// write the PCM samples
var lng = interleaved.length;
var index = 44;
var volume = 1;
for (var i = 0; i < lng; i++){
view.setInt16(index, (interleaved[i] * (0x7FFF * volume)).truncate(), Endianness.LITTLE_ENDIAN);
index += 2;
}
// our final binary blob
var blob = new Blob ([ view ] , 'audio/wav' );
// let's save it locally
String url = Url.createObjectUrlFromBlob(blob);
AnchorElement link = new AnchorElement()
..href = url
..text = 'download'
..download = 'output.wav';
document.body.append(link);
});
document.body.append(stopBtn);
window.navigator.getUserMedia(audio: true).then((MediaStream stream) {
var context = new AudioContext();
GainNode volume = context.createGain();
MediaStreamAudioSourceNode audioInput = context.createMediaStreamSource(stream);
audioInput.connectNode(volume);
int bufferSize = 2048;
ScriptProcessorNode recorder = context.createJavaScriptNode(bufferSize, 2, 2);
recorder.onAudioProcess.listen((AudioProcessingEvent e) {
if (!recording) return;
print('recording');
var left = e.inputBuffer.getChannelData(0);
var right = e.inputBuffer.getChannelData(1);
print(left);
// process Data
leftchannel.add(new Float32List.fromList(left));
rightchannel.add(new Float32List.fromList(right));
recordingLength += bufferSize;
});
volume.connectNode(recorder);
recorder.connectNode(context.destination);
});
}
void writeUTFBytes(ByteData view, offset, String string){
var lng = string.length;
for (var i = 0; i < lng; i++){
view.setUint8(offset + i, string.codeUnitAt(i));
}
}
Float32List interleave(leftChannel, rightChannel){
var length = leftChannel.length + rightChannel.length;
var result = new Float32List(length);
var inputIndex = 0;
for (var index = 0; index < length;){
result[index++] = leftChannel[inputIndex];
result[index++] = rightChannel[inputIndex];
inputIndex++;
}
return result;
}
List mergeBuffers(channelBuffer, recordingLength){
List result = new List();
var offset = 0;
var lng = channelBuffer.length;
for (var i = 0; i < lng; i++){
var buffer = channelBuffer[i];
result.addAll(buffer);
}
return result;
}
당신은 github의 here의 코드를 당겨 수 있습니다.
위의 링크와 솔루션의 일부를 공유해 주셔서 감사합니다. 완벽한 솔루션은 원시 데이터를 처리하고 링크 된 페이지와 유사한 실제 사운드 파일을 생성해야합니다. JS 솔루션을 Dart로 변환하려고합니다. 곧 결과에 대한 업데이트를 게시하겠습니다. –
[This] (https://github.com/nawafnaim/dart_examples/blob/master/save_mic_sound_to_file.dart)는 다트의 JS 솔루션을 다시 작성하는 최선의 시도입니다. 원시 데이터에서 wav 파일을 생성하지만 파일의 시작 부분에 파일을 손상시키는 두 개의 잘못된 라인이 있습니다 (작동하는 wav 파일과 비교하여 알 수있는 한). –
참조한 JS 솔루션을 성공적으로 다시 작성했습니다. 전체 코드에 대한 내 대답을 참조하십시오. 감사. –