Javascript 在onclick活动中请求麦克风
前几天,我偶然发现了一个Javascript录音机的示例: 我最终用它来实现我自己的。我遇到的问题是,在此文件中:Javascript 在onclick活动中请求麦克风,javascript,recording,web-audio-api,Javascript,Recording,Web Audio Api,前几天,我偶然发现了一个Javascript录音机的示例: 我最终用它来实现我自己的。我遇到的问题是,在此文件中: var audioContext = new webkitAudioContext(); var audioInput = null, realAudioInput = null, inputPoint = null, audioRecorder = null; var rafID = null; var analyserContext = null; v
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 );
现在,我在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>
并修改我的嵌入式脚本,如下所示:
<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>
$(函数(){
$(“#录制按钮”)。在(“单击”,函数()上){
$(“#入口”).hide();
$(#live”).fadeIn(“slow”);
initAudio();
切换记录(本);
$(this.toggle();
返回$(“#停止按钮”).toggle();
});
返回$(“#停止按钮”)。在(“单击”,函数()上){
录音机。停止();
$(this.toggle();
$(“#recbutton”).toggle();
$(“#live”).hide();
返回美元(“#入口”).fadeIn(“慢”);
});
});
我可能能够实现我想要的,事实上,我是,用户在单击#Rec按钮之前不会得到提示输入他/她的麦克风。问题是,音频从未录制过,当您尝试下载它时,生成的WAV it是空的
我怎样才能解决这个问题
我的项目代码位于:否,您的问题是getUserMedia()有一个异步回调(gotMedia());您需要将startbutton调用中的其余代码逻辑(特别是toggleRecording位)放在该回调中,因为现在它在getUserMedia返回(并设置音频节点)之前执行。我找到了一个优雅而简单的解决方案(或者至少我是这样认为的): 我所做的是在getScript调用中抛出“main.js”和“recorder.js”,该调用仅在用户单击某个按钮(#button1)时执行。。。在按下按钮之前,这些脚本不会加载网页本身,但我们需要一些更巧妙的技巧,以使其按照我上面描述和想要的方式工作: 在main.js中,我更改了:
window.addEventListener('load', initAudio );
用于:
因此,当使用getScript将脚本加载到页面中时,“main.js”文件现在会侦听网页中的单击事件,请求用户提供麦克风。接下来,我必须在页面上创建一个隐藏按钮(#button2),jQuery会在脚本加载到页面上后立即单击该按钮,因此它会触发“ask for Mirror permisson”事件,然后在代码行下方生成我添加的假单击:
window.removeEventListener("click", initAudio, false);
因此,此技巧的“工作流程”如下所示:
基本上这就是所有的人!:)现在,当用户进入页面时,他/她从未被要求获得麦克风许可证,直到他们按我的要求单击页面上的“Rec”按钮。只要用户点击一下,我们就可以在jQuery中做3件事,但对于用户来说,似乎什么都没有发生,只是在他们点击“Rec”按钮后,屏幕上立即出现了“麦克风许可信息”。您使用的浏览器是什么?Chrome,该示例仅适用于最新版本的色度测量chrome://flags/ 看看是否有可以更改的设置。即使没有。访问此站点后,请尝试再次运行示例。这听起来很愚蠢,但我在录音方面也遇到了同样的问题,出于某种奇怪的原因,我只是访问了这个网站,让录音工作正常。我很想知道,如果你也有同样的体验。嗯,但是录音效果很好,问题是,“索要麦克风”活动不能绑定到onclick并获取音频。但是如果你按照原样运行这个例子,它就可以正常工作了,所以它甚至不询问用户?那么我误解了你的问题。我以为你还能录音,但wav文件是空的。
window.addEventListener('load', initAudio );
window.addEventListener('click', initAudio );
window.removeEventListener("click", initAudio, false);