Аудио-рекордер¶
В данном примере представлена реализация веб-приложения для записи аудио с микрофона вашего устройства. Полный цикл работы приложения описан ниже.
- Пользователь нажимает кнопку 🎤 → запускается запись
- Во время записи:
- Кнопка становится красной с анимацией
- Работает таймер
- Собираются аудиоданные
- При остановке:
- Формируется аудиофайл
- Появляется плеер и кнопка скачивания
- Скачивание создает файл "recording-{дата}.wav"
Подробный разбор кода аудио-рекордера представлен ниже. Код начинается с базовой HTML-структуры и CSS-стилей для красивого интерфейса:
<div class="container">
<div class="title">Audio Recorder</div>
<div class="timer" id="timer">00:00</div>
<button id="recordBtn">🎤</button>
<button class="download-btn hidden" id="downloadBtn" title="Download recording">↓</button>
<div id="status">Press 🎤 to start recording</div>
<div class="audio-container" id="audioContainer">
<audio id="audioPlayer" controls></audio>
</div>
</div>
Ключевые элементы:
recordBtn
– круглая кнопка записи,downloadBtn
– кнопка скачивания (изначально скрыта),timer
– отображает время записи,audioPlayer
– элемент для воспроизведения записанного аудио.
Далее идёт инициализация переменных
let mediaRecorder;
let audioChunks = [];
let audioBlob;
let audioUrl;
let startTime;
let timerInterval;
let stream;
let isRecording = false;
Переменные хранят состояние приложения:
mediaRecorder
– объект для записи медиа,audioChunks
– массив для хранения записанных данных,audioBlob
/audioUrl
– итоговое аудио,timerInterval
– для обновления таймера,stream
– поток данных с микрофона.
После этого объявляются вспомогательные функции
function formatTime(seconds) {
const mins = Math.floor(seconds / 60).toString().padStart(2, '0');
const secs = Math.floor(seconds % 60).toString().padStart(2, '0');
return `${mins}:${secs}`;
}
function updateTimer() {
const elapsed = Math.floor((Date.now() - startTime) / 1000);
timerElement.textContent = formatTime(elapsed);
}
formatTime
преобразует секунды в формат "MM:SS", а updateTimer
обновляет отображение таймера.
Далее идёт функция запуска записи
function startRecording() {
navigator.mediaDevices.getUserMedia({ audio: true })
.then(function(s) {
stream = s;
mediaRecorder = new MediaRecorder(stream);
audioChunks = [];
mediaRecorder.ondataavailable = function(e) {
if (e.data.size > 0) {
audioChunks.push(e.data);
}
};
mediaRecorder.onstop = function() {
audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
audioUrl = URL.createObjectURL(audioBlob);
audioPlayer.src = audioUrl;
downloadBtn.classList.remove('hidden');
statusElement.textContent = "Recording saved! Click 🎤 to record again";
};
mediaRecorder.start(100);
startTime = Date.now();
timerInterval = setInterval(updateTimer, 1000);
updateTimer();
isRecording = true;
recordBtn.classList.add('recording');
recordBtn.textContent = "⏹️";
statusElement.textContent = "Recording... Click ⏹️ to stop";
})
.catch(function(err) {
console.error('Error accessing microphone:', err);
statusElement.textContent = "Error accessing microphone";
});
}
Логика работы описана далее.
- Запрашиваем доступ к микрофону через
getUserMedia
- Создаем
MediaRecorder
для записи потока - Настраиваем обработчики:
ondataavailable
– собирает кусочки аудио,onstop
– создает итоговый файл и показывает кнопку скачивания.
- Запускаем таймер и меняем интерфейс
После чего реализована остановка записи
function stopRecording() {
if (mediaRecorder && mediaRecorder.state !== 'inactive') {
mediaRecorder.stop();
clearInterval(timerInterval);
stream.getTracks().forEach(track => track.stop());
isRecording = false;
recordBtn.classList.remove('recording');
recordBtn.textContent = "🎤";
}
}
Останавливает запись, таймер и освобождает ресурсы микрофона.
И скачивание записи:
function downloadRecording() {
if (audioUrl) {
const a = document.createElement('a');
a.href = audioUrl;
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
a.download = `recording-${timestamp}.wav`;
a.click();
statusElement.textContent = "Download started...";
}
}
Создает временную ссылку для скачивания файла с уникальным именем.
Также имеется один обработчик событий, который позволяет кнопки записи работать как переключатель старт/стоп, и ещё дает возможность привязать весь интерфейс и его обновление к событию записи аудио файла.
recordBtn.addEventListener('click', function() {
if (isRecording) {
stopRecording();
} else {
startRecording();
}
});
downloadBtn.addEventListener('click', downloadRecording);
Теперь запустим само приложение и посмотрим, как оно работает.
display("text/html", read("audio_recorder.html", String))
Вывод¶
Этот пример и сам инструмент может быть полезен для генерации тестовых выборок данных для ЦОС.