Опыт написание музыкального сервиса на React и Tone.js

Доброго времени суток! Хочу поделиться опытом написания музыкального веб-сервиса на React, TypeScript, Tone.js и (внезапно) PHP. Эта статья о проблемах с производительностью, бесконечном рефакторинге и о том, что в конце концов получилось.

Где-то до 2016 года деятельность веб-программиста была довольно унылой и состояла в основном из разработки корпоративных сайтов на различных CMS-системах. Сейчас количество подобных вакансий все еще велико, ведь кто-то же должен поддерживать то, что было написано за многие годы🙃. Однако в 2020 году веб предоставляет намного больше возможностей чем когда-либо. Благодаря появлению удобных JavaScript-фреймворков стало проще создавать сложные интерфейсы и все больше функционала теперь зависит от фронтенд-разработчиков.

Я сам относительно недавно начал писать веб-приложения и использовать React и Vue.js. До этого как и многие другие использовал JQuery, засовывал код размером несколько тысяч строк в файл script.js и подключал его в теге footer.

Какое-то время назад в качестве хобби я начал создавать небольшой браузерный аудио-редактор, в котором можно было бы писать минусовки для песен, биты, записывать вокал и т. д. Конечно, до профессионального секвенсора типа FL Studio этот проект не дотягивает, но с помощью RapMe можно легко записывать демо-композиции, если под рукой нет ничего другого:

Если вы не технический специалист, то дальше вам будет читать очень скучно.

Стэк технологий был выбран следующий:

  • React, Redux, TypeScript и Tone.js — клиентская часть;
  • PHP — серверная часть.

Почему именно React а не Vue.js? Честно говоря, не вижу смысла сравнивать эти фреймворки ведь каждый из них хорош по-своему. Tone.js — это ооп-обертка для работы с Web Audio API. И, хотя библиотека не так уж активно развивается (последний релиз был выпущен более года назад), на данный момент это единственный нормальный инструмент, если вы не хотите напрямую работать с Web Audio API.

Бэкенд был написан на PHP. Он отдает фронту данные (в json) о том, где хранятся звуки разных инструментов. Наверное, лучшим решением было бы использовать на бэкенде Node.js и MongoDB, но эта часть писалась на скорую руку и без особых раздумий, а переделывать нормально в итоге стало просто лень.

Проблема № 1 Загрузка почти 100 МБ звуков в формате *.wav

Основной задачей было обеспечить быстрое взаимодействие пользователя с набором звуков инструментов: синтезаторы, барабаны, бас, и т. д. Загружать все необходимые сэмплы сразу было бы неправильно, так как все они хранятся в формате *.wav и весят почти 100 МБ. Поэтому, при старте приложения подгружается только минимальный набор звуков, необходимый, чтобы начать работу. Остальные запрашиваются с бэкенда по мере того как они понадобятся пользователю. Чтобы структурировать код запросов к серверу и перерисовку компонентов были использованы Redux и Redux Saga.

Проблема № 2 Артефакты на записи

Изначально на записях (особенно со старого ноутбука) были слышны лишние шумы, она постоянно дергалась и прерывалась. Причина была в том, что во время записи с микрофона некоторые компоненты перерисовывались, что оказывало влияние на производительность. В последних обновлениях реакта доступны особые функции, которые помогают оптимизировать приложение. Если не вдаваться в подробности, пришлось почти весь код переписать с использованием функциональных компонентов и постоянно использовать Reac.memo, React.useCallback, React.useMemo, чтобы исключить лишнюю перерисовку и повторное создание переменных.

Проблема № 3 Сохранение песен в *.mp3

На github есть проект под названием Recorderjs. Это библиотека, написанная почти 5 лет назад умеет конвертировать вывод Web Audio API в формат *.mp3. Путем долгих экспериментов удалось выяснить, что пытаться перевести звук из формата *.wav в формат *.mp3 средствами браузера — не самая лучшая идея. Поэтому пришлось конвертировать итоговый трек средствами бэкенда с помощью утилиты LAME.

Это далеко не полный список подводных камней, с которыми я столкнулся работая с Web Audio API в связке с React. Если кому-то интересен данный опыт, пишите в комментариях или на почту.

44 показа
971971 открытие
1 комментарий

Автор, ты молодец, было бы интересно ещё узнать как работать с данным API и во всех нюансах

Ответить