Комментарий пользователя
Приветствую! Подключил MediaRecorder, он стартует, но не приходит ни одного dataavailable и в результате получается пустой файл. В чем может быть дело?
Ответ специалиста
Здравствуйте! Проверьте последовательно — обычно причина в одном из трех: разрешениях, неверный mime/time-slice или в том, что поток пустой/трек неактивен. Делайте так.
Сначала проверим разрешения и secure context:
Если MediaRecorder уже стартует — разрешение, скорее всего, уже есть, но эта проверка поможет при отладке на чужих машинах/браузерах.
// проверяем разрешение
await navigator.permissions.query({ name: 'microphone' }).then(console.log)
// MediaRecorder работает только в защищенном контексте: HTTPS или localhost
Если permission denied — запросите заново через getUserMedia и обработайте отказ.
Теперь, проверим поддерживаемый mime и состояние recorder:
const mime = 'audio/webm;codecs=opus'
console.log('isSupported', MediaRecorder.isTypeSupported ? MediaRecorder.isTypeSupported(mime) : 'unknown')
const recorder = new MediaRecorder(stream, MediaRecorder.isTypeSupported(mime) ? { mimeType: mime } : undefined)
console.log('recorder.state', recorder.state)
Если isTypeSupported возвращает false, MediaRecorder может не выдавать data или выдавать пустые чанки — попробуйте без mime или другой формат.
Важно учитывать, что разные браузеры поддерживают разные mime-типы: например, Chrome чаще работает с ‘audio/webm;codecs=opus’, а Safari предпочитает ‘audio/mp4’.
Далее убедимся, что у потока есть активные треки:
stream.getTracks().forEach(t => console.log(t.kind, t.enabled, t.readyState))
В обычных условиях tracks не пустые, а readyState равен 'live'. Случай, когда треки отсутствуют или readyState !== 'live', встречается крайне редко. Например, если устройство занято другой программой или поток сразу остановлен.
Правильная обработка событий и timeslice:
const chunks = []
recorder.addEventListener('dataavailable', e => {
console.log('dataavailable', e.data && e.data.size)
if (e.data && e.data.size) chunks.push(e.data)
})
recorder.start(timesliceMs) // timeslice — длительность каждого чанка
Без параметра timeslice, событие dataavailable произойдет только после события stop(). А внутри ответа будет один общий медиа-файл. Если хотите получать частые куски (чанки) во время записи — передайте timeslice в recorder.start(timeslice) в миллисекундах.
После откройте DevTools → Console и смотрите ошибки (SecurityError, NotAllowedError и т.д.). Если есть ошибки — исправьте (например https, permission).
После этих шагов должно быть ясно, где проблема: права, поддержка формата, пустой поток или неверный обработчик.
Больше полезных материалов и новости из мира IT — в рассылке Академии Selectel.