На днях я наткнулся на этот пример записи аудио Javascript:Спросите микрофона на OnClick событие
http://webaudiodemos.appspot.com/AudioRecorder/index.html
который я в конечном итоге, используя для реализации моих собственных. Проблема у меня в том, что в этом файле:
var audioContext = new webkitAudioContext();
var audioInput = null,
realAudioInput = null,
inputPoint = null,
audioRecorder = null;
var rafID = null;
var analyserContext = null;
var canvasWidth, canvasHeight;
var recIndex = 0;
/* TODO:
- offer mono option
- "Monitor input" switch
*/
function saveAudio() {
audioRecorder.exportWAV(doneEncoding);
}
function drawWave(buffers) {
var canvas = document.getElementById("wavedisplay");
drawBuffer(canvas.width, canvas.height, canvas.getContext('2d'), buffers[0]);
}
function doneEncoding(blob) {
Recorder.forceDownload(blob, "myRecording" + ((recIndex<10)?"0":"") + recIndex + ".wav");
recIndex++;
}
function toggleRecording(e) {
if (e.classList.contains("recording")) {
// stop recording
audioRecorder.stop();
e.classList.remove("recording");
audioRecorder.getBuffers(drawWave);
} else {
// start recording
if (!audioRecorder)
return;
e.classList.add("recording");
audioRecorder.clear();
audioRecorder.record();
}
}
// this is a helper function to force mono for some interfaces that return a stereo channel for a mono source.
// it's not currently used, but probably will be in the future.
function convertToMono(input) {
var splitter = audioContext.createChannelSplitter(2);
var merger = audioContext.createChannelMerger(2);
input.connect(splitter);
splitter.connect(merger, 0, 0);
splitter.connect(merger, 0, 1);
return merger;
}
function toggleMono() {
if (audioInput != realAudioInput) {
audioInput.disconnect();
realAudioInput.disconnect();
audioInput = realAudioInput;
} else {
realAudioInput.disconnect();
audioInput = convertToMono(realAudioInput);
}
audioInput.connect(inputPoint);
}
function cancelAnalyserUpdates() {
window.webkitCancelAnimationFrame(rafID);
rafID = null;
}
function updateAnalysers(time) {
if (!analyserContext) {
var canvas = document.getElementById("analyser");
canvasWidth = canvas.width;
canvasHeight = canvas.height;
analyserContext = canvas.getContext('2d');
}
// analyzer draw code here
{
var SPACING = 3;
var BAR_WIDTH = 1;
var numBars = Math.round(canvasWidth/SPACING);
var freqByteData = new Uint8Array(analyserNode.frequencyBinCount);
analyserNode.getByteFrequencyData(freqByteData);
analyserContext.clearRect(0, 0, canvasWidth, canvasHeight);
analyserContext.fillStyle = '#F6D565';
analyserContext.lineCap = 'round';
var multiplier = analyserNode.frequencyBinCount/numBars;
// Draw rectangle for each frequency bin.
for (var i = 0; i < numBars; ++i) {
var magnitude = 0;
var offset = Math.floor(i * multiplier);
// gotta sum/average the block, or we miss narrow-bandwidth spikes
for (var j = 0; j< multiplier; j++)
magnitude += freqByteData[offset + j];
magnitude = magnitude/multiplier;
var magnitude2 = freqByteData[i * multiplier];
analyserContext.fillStyle = "hsl(" + Math.round((i*360)/numBars) + ", 100%, 50%)";
analyserContext.fillRect(i * SPACING, canvasHeight, BAR_WIDTH, -magnitude);
}
}
rafID = window.webkitRequestAnimationFrame(updateAnalysers);
}
function gotStream(stream) {
// "inputPoint" is the node to connect your output recording to.
inputPoint = audioContext.createGainNode();
// Create an AudioNode from the stream.
realAudioInput = audioContext.createMediaStreamSource(stream);
audioInput = realAudioInput;
audioInput.connect(inputPoint);
// audioInput = convertToMono(input);
analyserNode = audioContext.createAnalyser();
analyserNode.fftSize = 2048;
inputPoint.connect(analyserNode);
audioRecorder = new Recorder(inputPoint);
zeroGain = audioContext.createGainNode();
zeroGain.gain.value = 0.0;
inputPoint.connect(zeroGain);
zeroGain.connect(audioContext.destination);
updateAnalysers();
}
function initAudio() {
if (!navigator.webkitGetUserMedia)
return(alert("Error: getUserMedia not supported!"));
navigator.webkitGetUserMedia({audio:true}, gotStream, function(e) {
alert('Error getting audio');
console.log(e);
});
}
window.addEventListener('load', initAudio);
Как вы могли бы видеть, initAudio() функция (тот которым запрашивает у пользователя разрешение на использование его/ее микрофон) называется inmediately, когда страница загружается (прочитать последнюю строку) с помощью этого метода:
window.addEventListener('load', initAudio);
Теперь у меня есть этот код в HTML:
<script type="text/javascript" >
$(function() {
$("#recbutton").on("click", function() {
$("#entrance").hide();
$("#live").fadeIn("slow");
toggleRecording(this);
$(this).toggle();
return $("#stopbutton").toggle();
});
return $("#stopbutton").on("click", function() {
audioRecorder.stop();
$(this).toggle();
$("#recbutton").toggle();
$("#live").hide();
return $("#entrance").fadeIn("slow");
});
});
</script>
И как вы можете видеть, я вызываю функцию toggleRecording (this) (тот, который начинает процесс записи) только после нажатия кнопки #recbutton. Теперь все работает отлично с этим кодом. НО, пользователь получает запрос на разрешение микрофона, как только загружается страница, и я хочу попросить у них разрешения использовать микрофон ТОЛЬКО ПОСЛЕ того, как они нажали кнопку #recbutton. Вы меня поняли? Я учил, что если удалить последнюю строку первого файла:
window.addEventListener('load', initAudio);
и изменить свой встроенный скрипт так:
<script type="text/javascript" >
$(function() {
$("#recbutton").on("click", function() {
$("#entrance").hide();
$("#live").fadeIn("slow");
initAudio();
toggleRecording(this);
$(this).toggle();
return $("#stopbutton").toggle();
});
return $("#stopbutton").on("click", function() {
audioRecorder.stop();
$(this).toggle();
$("#recbutton").toggle();
$("#live").hide();
return $("#entrance").fadeIn("slow");
});
});
</script>
я мог бы добиться того, чего я хотел, и на самом деле я , пользователь не получает запрос на его/ее микрофон, пока не нажмет кнопку #recbutton. Проблема заключается в том, что звук никогда не записывается, когда вы пытаетесь его загрузить, в результате WAV он пуст.
Как это исправить?
код моего проекта по адресу: https://github.com/Jmlevick/html-recorder
какой браузер вы используете? – basilikum
Chrome, пример работает только в последних версиях Chrome. – Jmlevick
Попробуйте пойти на chrome: // flags/и посмотреть, есть ли параметр, который вы можете изменить. И даже если нет. Попробуйте снова запустить свой пример после посещения этого сайта. Это звучит глупо, но у меня была такая же проблема с записью звука и по какой-то странной причине, просто посетив этот сайт, заработали записи. Было бы интересно узнать, если вы испытаете то же самое. – basilikum