Задача
Получать поток данных с микрофона, конвертировать на лету в mp3 формат и передавать на сервер. Цифровой аналог рации.
Используется
- ElectronJS (ver. 6.0.10);
- fluent-ffmpeg (ver. 2.1.2)
- ffmpeg (ver. 4.2-static)
Комментарий
Сейчас используется следующий алгоритм: В renderer процессе через navigator.getUserMedia инициализируется микрофон и получаем поток. Поток скармливается MediaRecorder. Когда приходит команда начать запись, данные собираются в blob, blob скармливается FileReader, чтобы получить base64 строку. Полученный результат передаётся через IPC из renderer процесса в main. В main процессе данные сохраняются во временный файл. Временный файл скармливается ffmpeg, который в виде выходного файла некий url адрес конечного файла, куда производится запись/передача. Это одинаково работает, и в Windows системе, и в Linux системах.
Сейчас требуется real-time реализация, чтобы данные конвертировались в mp3 и передавались в процессе записи.
Что пробовал:
-
Скармливать данные из MediaRecorder в ffmpeg через Stream API. Мысль такова: Пока «активен» поток, ffmpeg конвертирует и передаёт данные в real-time режиме. Поток закрываем, конвертирование останавливается, в файл записывается окончание. Через remote.require подключил ffmpeg в renderer процессе. Создал сквозной Transform поток, который входящие данные трансформировал в Blob’ы. Поток скармливался ffmpeg. Аналогично действующему решению, только данные передаются сразу в ffmpeg. ffmpeg ругается на входные данные, это странно, потому что такие же данные записываются во временный файл. Ещё не разобрался в причинах такого поведения.
-
Передавать в ffmpeg адрес микрофона. Мысль такова: ffmpeg всеяден и может самостоятельно брать поток данных с микрофона. ElectronJS будет только управлять командами «старт», «стоп» и предоставлять конечный url. Здесь всплывает пласт проблем, связанных с поиском и объявлением аудио устройств.
Вопросы
Какие ещё можно рассмотреть доступные варианты, что мог упустить из виду или сделать неправильно?