JSFiddle - React, Tailwind, and code Playground
by Maksim Shamihulau
HTML
<body>
<div>
<h2>Audio record and playback</h2>
<p>
<label for="audioSource">Audio input source: </label>
<select id="audioSource"></select>
</p>
<p>
<button id=startRecord>start</button>
<button id=stopRecord disabled>stop</button>
</p>
<p>
<audio id=recordedAudio></audio>
<a id=audioDownload></a>
</p>
</div>
</body>
JavaScript
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 gotStream(stream) {
window.stream = stream; // make stream available to console
rec = new MediaRecorder(stream);
rec.ondataavailable = e => {
audioChunks.push(e.data);
if (rec.state == "inactive"){
let blob = new Blob(audioChunks,{type:'audio/x-mpeg-3'});
recordedAudio.src = URL.createObjectURL(blob);
recordedAudio.controls=true;
recordedAudio.autoplay=true;
audioDownload.href = recordedAudio.src;
audioDownload.download = 'mp3';
audioDownload.innerHTML = 'download';
}
}
}
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} :...