← все проекты

Диджейский пульт для стрима

Пульт для алко-стрима: драм-машина, эффекты голоса живьём, дискотека в кадре. Всё считает браузер, платных вызовов нет. Растёт из движка «Песня из чата»: зрители, песни по заказу и кабацкие механики докручиваются сверху.

repo: E:\Проекты для Гитхаба\pesnya-streamserver: Пока только локально, localhost:3010. На сервер не разворачивался: зрители появятся в спринте 2, тогда и понадобится домен.docs: docs/ (ACCEPTANCE.md, DECISIONS.md, SCOPE-CUTS-LOG.md) + CLAUDE.md в корнепамять: dj-pult-stream
готовS1 · Пульт и дискотека13/13

Цель: Вести эфир можно на одном этом: бит играет, голос ломается, картинка пляшет. Без интернета и без денег.

Синтез восьми ударных без единого семпла
Бочка, снейр, хэт, открытый, хлопок, бас, ковбелл, взрыв. Каждый собран из осцилляторов и шума. Проверено рендером в буфер: все звучат, все различаются по яркости и длине хвоста.
feature
Секвенсор на 16 шагов с точным планировщиком
Забегание вперёд на 80 мс по часам звуковой карты. Проверено рендером: расхождение удара с сеткой 0 мс. Восемь готовых ритмов, клетки нажимаются мышкой, темп 60-180, свинг.
feature
Семь эффектов голоса в реальном времени
Свой, бурундук, дьявол, робот, мегафон, телефон, зал. Сдвиг высоты написан своим обработчиком на AudioWorklet, готового узла в браузере нет. Цепочки висят параллельно и переключаются громкостями, чтобы не щёлкало.
feature
Мастер: фильтр, дробилка, остановка пластинки
Крутилка фильтра в обе стороны, дробилка, торможение винила с падением тона, качание под бочку, ограничитель. Проверено: со 150 ударов темп падает до 24 и возвращается.
feature
Дискотека на canvas и сцена для OBS
Лучи сверху, спектр кольцом, шар с зеркальцами, сетчатый пол, стробоскоп, вспышка на бочке. Сцена отдельным адресом с прозрачным фоном, повторяет пульт по телеметрии через вебсокет.
feature
Вывод звука в виртуальный кабель
Мастер кладётся в поток, поток в элемент, элементу говорится setSinkId. Список устройств в пульте, выбор запоминается. В наушниках остаётся мониторинг.
feature
Проверка настоящим браузером
node scripts/proof.mjs при поднятом сервере. Снимки экранов лягут в proof/.
20 проверок, все зелёные: ритм по миллисекундам, восемь звуков, микрофон, эффекты, телеметрия до сцены, ручки мастера, снимки экранов.
feature
🔴 Починка исходного движка: hidden против display
В базовом css не было правила для hidden, и класс с display его перебивал. Из-за этого тейковер с текстом песни висел поверх оверлея весь эфир: в OBS вместо картинки была тёмная плашка на весь кадр.
feature
Починка исходного движка: npm start не читал .env
Ни --env-file, ни библиотеки, при этом README обещал обратное: ключ от админки молча оставался change-me. Поставлен --env-file-if-exists.
feature
Замечания с первого эфира: микрофон, двойной голос, эффекты
Микрофон не выключался (кнопка только включала). Голос слышался дважды: дорожка вывода играла, даже когда устройство не выбрано, и складывалась с мониторингом. Бурундук и дьявол пропадали без обработчика высоты, теперь та же математика считается запасным способом. Добавлен микшер (бит, голос, песня), эхо бросает весь эфир, стоп пластинки тормозит и песню.
feature
Пятнадцать голосов вместо семи
Брутальный (голос из трейлера), диктор, малыш, дед с дрожанием, хор из трёх копий разной высоты, пришелец, стадион, под водой. Всё считается в браузере из тех же примитивов, без сервисов и без денег.
feature
Голос звучал только в левом ухе
Микрофон приходит двухканальным, сигнал только слева, и так уезжало в эфир. Вход сводится в один канал принудительно, дальше расходится на оба.
feature
Тестовые песни уехали на боевой
data/songs.json лежал под контролем версий: на проде висели карточки «Пробный трек» со ссылками на подставной сервис, не проигрывались, счётчик показывал выдуманные 30 рублей. Файл исключён, прод очищен.
feature
планS2 · Зрители в кадре0/5

Цель: Зритель заходит с телефона за один снимок камеры и попадает в кадр реакциями.

QR на сцене вместо текстовой ссылки
feature
Реакции с телефона: летят по сцене и звучат
feature
Градус вечера растёт от активности и разгоняет картинку
feature
Бегущая строка с никами пришедших
feature
Табло вечера
feature
В РАБОТЕS3 · Песни по заказу8/13
Очередь заказов песен от зрителей
Зритель пишет заказ, ведущий одобряет, только после одобрения уходит в генерацию.
feature
Генерация трека и автоплей на сцене
Suno через Kie, Generate Music 0.06 доллара за запрос, около 6 рублей за трек. Расход показать до запуска, спросить подтверждение.
Панель песни в пульте: тема, жанр, тумблер «без слов». Ловим потоковую ссылку Suno, поэтому петь можно примерно через минуту, а не через три. Настоящая генерация на живом ключе владельцем ещё не запускалась.
feature
Караоке: текст бежит в такт
Suno TimeStamped Lyrics, 0.0025 доллара за запрос.
feature
Кавер на спетое в микрофон
Suno upload-and-cover-audio, 0.06 доллара. Спел пьяным голосом, вернулось нормальным треком в жанре. Тут же появится запись микрофона в буфер, она же нужна луп-машине.
feature
Минусовка из любого трека для живого пения
Suno Vocal Separate, 0.05 доллара.
feature
Луп-машина: напел фразу, она закольцевалась под бит
Срезано в спринте 1: петля должна ложиться ровно на такт, иначе уползает через два круга.
feature
Трек идёт через мастер вместе с битом
Песня отдаётся со своего адреса /song/:id.mp3, иначе браузер не пускает чужой звук в Web Audio. Слышна в том же фильтре, уходит в тот же кабель, дискотека пляшет под неё, название видно на сцене.
feature
Расход на песни считается и виден в пульте
Считается в момент создания задачи, а не при удачном исходе: деньги списываются в любом случае. Внизу панели «За вечер песен: N, потрачено около M рублей».
feature
Проверка заказа песни без трат
scripts/proof-song.mjs поднимает подставной Suno и гоняет весь путь: заказ, ожидание, потоковая ссылка, проигрывание через наш прокси, отказ по фильтру, счётчик расхода. 11 проверок, все зелёные, ноль копеек.
feature
Помощник пишет текст песни и описание стиля
Модель через OpenRouter отдаёт название, стиль и текст с метками куплетов, человек правит перед запуском. Заказ уходит в полном режиме Suno со style и title. Разбор переживает и пробельные строки провайдера, и ответ простым текстом вместо разбора по полям.
feature
Нарезка: один текст, каждый кусок в своём жанре
Текст режется по 2-4 строки, стили раздаются по кругу, длительность куска задаётся (duration работает только в полном режиме и только у V5_5). Раскладка и цена всей пачки показываются до запуска, отправка отдельным нажатием, куски уходят по очереди с паузой против 429.
feature
Обратный адрес в заказе
В описании метода callBackUrl помечен обязательным. Тело не разбираем: свой опрос надёжнее, вызов используем как повод спросить сразу. Адрес https://myvisionagency.ru/pult/song/callback, отвечает 200.
feature
Караоке на ходу: строки от модели под бит
Тема и имя ведущего, модель пишет дюжину строк, они едут в темпе бита (такты на строку настраиваются), следующая видна заранее, на исходе пачки допрашивается новая. Музыка своя, генерация не нужна, стоит около рубля за дюжину.
feature
планS4 · Кабацкие механики0/3

Цель: Колесо фантов, челленджи, золотой микрофон вечера.

Колесо фантов: кому пить, кому петь
feature
Челленджи от зрителей
feature
Золотой микрофон вечера
feature
В РАБОТЕS5 · Twitch и домен1/3
Ники из чата Twitch без ввода
feature
Команды в чате наравне с кнопками
feature
Домен и постоянный адрес для зрителей
Обработчик высоты голоса и выбор устройства требуют защищённого соединения, значит сразу с сертификатом.
https://myvisionagency.ru/pult/dj, /stage, /play. cfru /opt/pult, pm2 pult, порт 3180, префикс через BASE_PATH и тег base. Поддомена нет: записи в DNS не существует, поэтому подпуть. Проверка браузером пройдена по боевому адресу: 20 из 20.
feature
В РАБОТЕS9 · Проверки по сроку0/1

Цель: Отложенные проверки, чтобы не выяснять через месяц, что не работает.

Песня: первая настоящая генерация на живом ключе
20.08 · просрочено 11 дн.
Владелец решил пробовать сам, поэтому путь до настоящего Suno не проверен ни разу: подставной сервер покрыл только нашу часть. Проверка: открыть https://myvisionagency.ru/pult/dj, ключ в /opt/pult/.env, клавиша G, заказать песню. Ждать до минуты появления кнопки «Играть». Если молчит: ssh cfru 'pm2 logs pult --lines 100 | grep -i suno'. Баланс: curl -s https://api.kie.ai/api/v1/chat/credit -H "Authorization: Bearer $KIE_AI_API_KEY". Одна песня около 6 рублей.
check

Ворклог (места остановки)

15.08.2026, 18:33:44 · S1+S3 · claude

Второй заход по замечаниям с живого пульта. Найдено и починено: на боевой уехали песни из проверки (data/songs.json был под контролем версий), из-за чего карточки не проигрывались и счётчик врал — владелец решил, что не работает Suno; микрофон приходил двухканальным с сигналом только слева, и голос так и уходил в эфир из одного уха. Добавлено: пятнадцать голосов вместо семи, включая брутальный, диктора, хор и деда; караоке на ходу, где строки пишет модель, а бегут они в темпе бита с показом следующей. Проверки: 24 из 24 на пульте по боевому адресу, 21 из 21 на песнях и караоке.

Suno живьём по-прежнему ни разу не запускался: проверка на 20.08 в силе, теперь на чистом списке. Просьба владельца про голоса «как у актёров» требует отдельного разговора: живая подмена голоса моделью это GPU-сервер и задержка в доли секунды, на cfru видеокарты нет. Дальше по выбору: заказы песен от зрителей, караоке с таймкодами под готовый трек, кавер на спетое.

15.08.2026, 18:05:39 · S1+S3 · claude

Разбор замечаний владельца после первого включения пульта и большой шаг по песням. Починено: микрофон не выключался; голос слышался дважды (дорожка вывода играла без выбранного устройства и складывалась с мониторингом); бурундук и дьявол пропадали, если браузер не дал обработчик высоты, теперь есть запасной способ и настоящая причина в консоли вместо догадки про Chrome; эхо бросает в повтор весь эфир, а не только голос; стоп пластинки тормозит и играющую песню. Добавлен микшер на три громкости. По песням: помощник пишет текст и описание стиля (два ключевых поля Suno), заказ уходит в полном режиме, появилась нарезка одного текста по кускам с разными жанрами и ценой пачки до запуска, добавлен callBackUrl и свой обработчик. Проверкой пойман баг, который в эфире выглядел бы как «полный режим не работает»: поле lyrics объявлялось дважды и пустое затирало присланный текст. Проверки: 24 из 24 на пульте по боевому адресу, 18 из 18 на песнях.

Настоящая генерация Suno по-прежнему ни разу не запускалась: владелец пробует сам, проверка по сроку на 20.08 в силе. Путь до текстовой модели проверен через прокси на бесплатной модели (транспорт, разбор ответа, сборка полей) — платная не гонялась. Дальше: заказы песен от зрителей с телефона, караоке с таймкодами, кавер на спетое в микрофон, либо спринт 2 (QR и реакции в кадре).

12.08.2026, 19:33:25 · S3+S5 · claude

Песня по заказу и выкат на боевой адрес. В пульте появилась панель песни: тема, жанр, без слов; заказ виден в списке с честным состоянием. Ловим потоковую ссылку Suno, поэтому петь можно примерно через минуту, а не через три. Трек идёт через мастер вместе с битом и отдаётся со своего адреса, поэтому дискотека пляшет под него, а название видно на сцене. Расход считается на каждый заказ. Выкачено на https://myvisionagency.ru/pult (cfru /opt/pult, pm2, порт 3180, префикс через BASE_PATH). Поддомена нет: записи в DNS не существует. В nginx обязательный ^~, иначе regex-location для js и css перехватывает скрипты пульта. Попутно вынесены бэкапы конфигов из sites-enabled: nginx подключал их как второй серверный блок на тот же домен. Проверки: 20 из 20 по боевому адресу, 11 из 11 на подставном Suno.

Владелец пробует первую настоящую песню сам, гейт на трату он не снял: путь до живого Suno ни разу не прогнан, заведена проверка на 20.08. Дальше по выбору: заказы песен от зрителей с телефона, караоке с таймкодами, кавер на спетое в микрофон, либо спринт 2 (QR и реакции в кадре).

12.08.2026, 18:54:35 · S1 · claude

Заведён проект из присланного архива pesnya-stream. Спринт 1 закрыт: пульт /dj и сцена /stage поверх существующего движка песни. Драм-машина из восьми синтезированных ударных, секвенсор с забеганием вперёд, семь эффектов голоса живьём со своим питч-шифтером, мастер-секция, дискотека на canvas, вывод звука в выбранное устройство. Написана проверка настоящим браузером: 20 проверок, все зелёные, ритм сверяется по миллисекундам через рендер в буфер. Попутно починены два бага исходного движка: атрибут hidden проигрывал классу с display (тейковер висел поверх оверлея весь эфир), и npm start не читал .env (ключ админки оставался change-me).

Владельцу: поставить VB-CABLE, открыть /dj, погонять руками и сказать, чего не хватает в живом эфире. Дальше спринт 2 (зрители в кадре: QR, реакции, градус вечера) либо сразу спринт 3 (песни по заказу через Suno) — что окажется важнее после первой примерки. Перед первой генерацией показать расход и спросить подтверждение.