Привет, друзья! В этом небольшом "туториале" я хочу показать вам, как разработать приложение для записи и воспроизведения аудио-файлов. Функционал нашего приложения будет следующим: Основная технология, которую мы будем использовать, это MediaDevices. Данная технология входит в состав глобального объекта Navigator. Основным методом, предоставляемым указанным интерфейсом является getUserMedia(). Запись данных (в простых случаях вроде нашего) выполняется с помощью интерфейса MediaRecorder. Интерфейс MediaDevices на сегодняшний день поддерживается всеми современными браузерами. Для небольшой стилизации нашего приложения мы будем использовать Sass. Выглядеть приложение примерно так: 
 Исходный код приложения. Основным источником вдохновения для меня послужила эта замечательная статья. Обратите внимание: данная статья рассчитана, преимущественно, на начинающих разработчиков, хотя, смею надеяться, что и опытные найдут в ней что-нибудь интересное. Вы готовы? Тогда вперед! Начнем с разработки сервера. Создаем директорию для проекта, переходим в нее, инициализируем проект и устанавливаем необходимые зависимости: Зависимости: Определяем команды для запуска сервера для разработки в package.json: Команды: В коде сервера мы будем использовать ES6-модули (import/export), поэтому определим в package.json тип основного файла сервера как модуль: В качестве альтернативы для кода сервера можно использовать файл с расширением .mjs. Давайте определимся со структурой проекта: Изображения, которые мы будем использовать при разработке приложения, можно скачать здесь. Приступаем к реализации. Что должен уметь наш сервер? Многого от него не требуется: все, что он должен уметь — это обслуживать статические файлы из директорий public и uploads, а также сохранять и извлекать аудио-файлы. Импортируем необходимые модули: Определяем абсолютный путь к текущей (рабочей) директории: Настраиваем multer: Создаем приложение express и определяем директории со статическими файлами: Определяем маршрут для сохранения аудио с помощью multer, используемого в качестве посредника (middleware). Аудио будет отправляться методом POST в формате multipart/form-data по адресу /save: Определяем "роут" для извлечения сохраненных аудио и их отправки клиенту (метод — GET, адрес — /records): Наконец, определяем порт (по умолчанию 3000) и запускаем сервер: На этом с сервером мы закончили. Переходим к клиенту. Весь код клиента будет находиться в директории public. Начнем с разметки (index.html). Обратите внимание на идентификаторы. Поскольку DOM-элементы с идентификаторами становятся свойствами глобального объекта window, мы сможем получать к ним доступ напрямую, т.е. без предварительного получения ссылки на элемент путем вызова таких методов как querySelector(). Сделаем приложение красивым (style.scss): Наконец, переходим к тому, ради чего мы, собственно, здесь собрались. Я, конечно же, имею ввиду клиентский скрипт. Но сначала кратко поговорим об интерфейсе MediaDevices и его методе getUserMedia(). Интерфейс MediaDevices предоставляет доступ к медиа-устройствам пользователя, таким как камера, микрофон, а также к совместному использованию экрана. Разумеется, пользователь должен явно предоставить разрешение на такой доступ. Спецификация Media Capture and Streams определяет довольно жесткие правила на этот счет. Метод getUserMedia() запрашивает разрешение пользователя на использование медиа устройства (камера, микрофон). Результат возвращает промис, содержащий поток (объект MediaStream), который состоит из треков (дорожек), содержащих требуемые данные. Данный метод принимает ограничения (объект MediaStreamConstraints), определяющий, какие типы медиа запрашиваются, а также требования для каждого типа. В общем виде это выглядит так: MediaRecorder — это интерфейс MediaStream Recording API представляющий функциональность для простой записи медиа. Нас интересуют такие методы указанного интерфейса, как start() и stop(), свойство state, определяющее состояние записи, а также событие dataavailable, возникающее по окончанию записи. Определяем глобальные переменные и забавы ради добавляем в подвал текущий год: Определяем утилиты для создания DOM-элементов и смены CSS-классов: Определяем функцию для начала записи: Определяем функцию обработки окончания записи: Определяем функцию для отправки новой записи на сервер для сохранения: Определяем функции сброса и удаления новой записи: Для формирования списка записей, полученных от сервера, нам потребуется функция для создания относительно сложного DOM-элемента: Готовый элемент будет выглядеть примерно так: Определяем функцию для получения записей от сервера и формирования соответствующего списка: Определяем функцию для запуска воспроизведения: Наконец, добавляем кнопкам соответствующие обработчики и вызываем функцию для получения записей от сервера: Для того чтобы убедиться в работоспособности нашего приложения, выполняем команду yarn start или npm start. В директории public появляется файл style.css, сгенерированный на основе style.scss, запускается сервер для разработки (🚀) и в браузере открывается новая вкладка по адресу http://localhost:3000. 
 Нажатие кнопки приводит к запросу пользователя о выдаче разрешения на использование микрофона. Предоставляем программе такое разрешение. После этого начинается запись (об этом, в частности, свидетельствует красный индикатор рядом с кнопкой для закрытия вкладки и значок видеокамеры в адресной строке). 
 Говорим что-нибудь в микрофон и нажимаем "Стоп". Появляется блок с новой записью и возможностью ее прослушивания, сохранения или удаления. 
 Нажимаем "Save" и вводим название записи. В директории uploads появляется новый файл в формате .mp3, в консоли появляется сообщение "Saved" и список записей обновляется. 
 Согласитесь, что запись аудио (и видео) с помощью технологий, предоставляемых браузером, никогда не была такой простой и доступной. Пожалуй, это все, чем я хотел поделиться с вами в данной статье. Благодарю за внимание и хорошего дня!  JavaScript Developer