我正在 HTML + JS 中测试我的麦克风。这一切都很好地记录和播放。现在我想添加连接到计算机 / 设备的麦克风设备的下拉列表。这部分变得越来越棘手,因为我不知道我是否必须使用库或是否有更简单的方法来做到这一点?
基本上是一个下拉列表,用于选择输入麦克风设备,然后进一步进行记录。
请随时更改下面的代码,它来自 github。
编辑:跟随用户发布的链接后,我将其集成到我的代码中。现在麦克风设备显示出来。但问题是它没有显示麦克风设备的名称。为什么?
window.addEventListener("DOMContentLoaded", function () {
const record = document.getElementById("record");
const visualizer = document.getElementById("visualizer");
const stop = document.getElementById("stop");
const audio = document.getElementById("audio");
const canvasCtx = visualizer.getContext("2d");
let chunks = [];
navigator.mediaDevices
.getUserMedia({
audio: true
})
.then(function (stream) {
visualize(stream);
const mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = function (e) {
chunks.push(e.data);
};
mediaRecorder.onstop = function (e) {
const blob = new Blob(chunks, {
type: "audio/ogg; codecs=opus"
});
audio.src = window.URL.createObjectURL(blob);
audio.play();
// clear recorded audio
chunks = [];
};
record.onclick = function () {
mediaRecorder.start();
visualizer.style.display = "block";
audio.style.display = "none";
stop.style.display = "block";
record.style.display = "none";
stop.disabled = false;
record.disabled = true;
};
stop.onclick = function () {
mediaRecorder.stop();
visualizer.style.display = "none";
audio.style.display = "block";
stop.style.display = "none";
record.style.display = "block";
stop.disabled = true;
record.disabled = false;
};
})
.catch(function (err) {
console.log(err);
alert("There was a problem accessing your microphone.");
});
function visualize(stream) {
const audioCtx = new AudioContext();
const source = audioCtx.createMediaStreamSource(stream);
const yser = audioCtx.createAnalyser();
yser.fftSize = 2048;
const bufferLength = yser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
source.connect(yser);
draw();
function draw() {
WIDTH = visualizer.width;
HEIGHT = visualizer.height;
requestAnimationFrame(draw);
yser.getByteTimeDomainData(dataArray);
canvasCtx.fillStyle = "#ffffff";
canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);
canvasCtx.lineWidth = 1;
canvasCtx.strokeStyle = "#4287f5";
canvasCtx.beginPath();
let sliceWidth = (WIDTH * 1.0) / bufferLength;
let x = 0;
for (let i = 0; i < bufferLength; i++) {
let v = dataArray[i] / 128.0;
let y = (v * HEIGHT) / 2;
if (i === 0) {
canvasCtx.moveTo(x, y);
} else {
canvasCtx.lineTo(x, y);
}
x += sliceWidth;
}
canvasCtx.lineTo(visualizer.width, visualizer.height / 2);
canvasCtx.stroke();
}
}
});
const audioInputSelect = document.querySelector('select#audioSource');
const selectors = [audioInputSelect];
function gotDevices(deviceInfos) {
// Handles being called several times to update labels. Preserve values.
const values = selectors.map(select => select.value);
selectors.forEach(select => {
while (select.firstChild) {
select.removeChild(select.firstChild);
}
});
for (let i = 0; i !== deviceInfos.length; ++i) {
const deviceInfo = deviceInfos[i];
const option = document.createElement('option');
option.value = deviceInfo.deviceId;
if (deviceInfo.kind === 'audioinput') {
option.text = deviceInfo.label || `microphone ${audioInputSelect.length + 1}`;
audioInputSelect.appendChild(option);
}
}
selectors.forEach((select, selectorIndex) => {
if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) {
select.value = values[selectorIndex];
}
});
}
function handleError(error) {
console.log('navigator.MediaDevices.getUserMedia error: ', error.message, error.name);
}
function start() {
// Second call to getUserMedia() with changed device may cause error, so we need to release stream before changing device
if (window.stream) {
stream.getAudioTracks()[0].stop();
}
const audioSource = audioInputSelect.value;
const constraints = {
audio: { deviceId: audioSource ? { exact: audioSource } : undefined }
};
}
audioInputSelect.onchange = start;
navigator.mediaDevices.enumerateDevices()
.then(gotDevices)
.then(start)
.catch(handleError);
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
color: #606c76;
font-family: "Roboto", "Helvetica Neue", "Helvetica", "Arial",
sans-serif;
width: 100%;
margin: 0 auto;
padding: 10px;
}
h1,
p,
div {
margin: 10px 0;
}
h1 {
font-size: 3.6rem;
}
#record {
background-color: #1b89f0;
color: #ffffff;
border: 0px;
width: 100%;
height: 50px;
font-size: 1rem;
cursor: pointer;
}
#visualizer {
display: none;
margin: 10px 0;
height: 60px;
width: 100%;
}
#stop {
background-color: #e90a0a;
display: none;
border: 0px;
width: 100%;
height: 50px;
font-size: 1rem;
cursor: pointer;
}
#audio {
display: none;
margin: 10px 0;
width: 100%;
}
/* Desktop Styles */
@media only screen and (min-width: 961px) {
body {
max-width: 600px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<main>
<div id="ons">
<on id="record">Record</on>
<on id="stop">Stop</on>
</div>
<p>
<label for="audioSource">Audio input source: </label>
<select id="audioSource"></select>
</p>
<canvas id="visualizer"></canvas>
<audio id="audio" controls="true"></audio>
</main>
本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处
评论列表(86条)