← все проекты

Караоке-чарт для стрима

Локальный сервис на компе владельца: трек из Яндекс Музыки, замер попадания в ноты по сырому микрофону, карточка после песни, оценка стримера 1-10 в панели OBS, топ-чарт песен и исполнителей, голоса зрителей из чата Twitch.

repo: E:/Проекты для Гитхаба/karaoke-chartdocs: docs/память: user-singing-baseline
В РАБОТЕS1 · С1 · Трек, оценка, база6/7

Цель: Песня из Яндекс Музыки и оценка стримера 1-10 сохраняются

С1 · Сервис: сейчас играет + панель оценок в OBS + SQLite + автозапуск
✓ Код + экзамены зелёные, ОТК круг 1 пройден. Коммит 21b4a38.
feature
A1.1 Трек виден в панели и на оверлее за 3 с
✓ Экзамены A1.1 зелёные (трек за <3 с на подставном сеансе). Механизм Windows проверен вживую (читает сеанс Chrome). Ждёт: живой трек из Яндекс Музыки, когда владелец включит.
acceptance
A1.2 Смена трека = новое исполнение, пауза не заводит новое
✓ Экзамены test_s1 A1_2 x3 зелёные + регресс: пауза >60 с завершает, повтор трека = новое исполнение, пропуск <20 с не песня (tests/test_regress.py 9/9).
acceptance
A1.3 Оценка 1-10 ставится последнему исполнению, повтор заменяет
✓ test_s1 A1_3 x5 зелёные (последней, замена, границы 0/11/-1/строка/5.5 -> 400, по id, 404). Цель оценки решает сервер (rate_target, 15 мин).
acceptance
A1.4 Перезапуск не теряет данные
✓ test_s1 A1_4 зелёный. Прерванная на перезапуске запись остаётся с пометкой «не замерено» и не перехватывает оценку (регресс).
acceptance
A1.5 Сервис слушает только 127.0.0.1
✓ test_s1 A1_5 зелёный: порт не открыт на внешних адресах; TCPSite 127.0.0.1.
acceptance
A1.6 Автозапуск при входе в Windows без окна
✓ Задача планировщика «Karaoke Chart» при входе, pythonw без окна; Start-ScheduledTask -> /api/state 200, лог «слушаю http://127.0.0.1:8765».
acceptance
готовS2 · С2 · Замер нот и карточка5/6

Цель: После каждой песни карточка с оценкой за пение

С2 · Замер попадания в ноты по сырому микрофону + карточка на оверлее
✓ Развилка решена владельцем 17.10: оценка по мелодии оригинала в С5. Замер нот остаётся запасным.
⛔ A2.2: цифра пения на записях владельца неотличима от случайной, нужна развилка (мелодия оригинала / составная оценка / оставить).
feature
A2.1 Синтетика: чистые >=90%, разброс ±50c 30-50%, сдвиг строя не влияет
✓ test_s2 A2_1 x4 зелёные. Плюс прогон: вибрато до ±100 центов и скольжения до 200 мс = 100% чистых; случайные ±50 = 37,5%.
acceptance
A2.2 Записи 12.10 в пределах ±10 п.п. от замера
✓ Заменён на A5.7 решением владельца 17.10 (калибровка по мелодии своих песен).
⛔ Честный метод (строй по соседям без самой ноты) даёт записям 12.10 37–45% при случайных нотах 40% (p95 47–49%): коридор 40–68% был под завышенный старый замер. Нужно решение владельца: что меряем.
acceptance
A2.3 Тишина или <8 нот = «не пел»
✓ test_s2 A2_3 x3 зелёные: тишина и 5 нот = не пел, 10 нот = пел.
acceptance
A2.4 Карточка за 5 с: оценка, рекорд, оценка стримера
✓ test_s2 A2_4 зелёный (карточка <5 с, рекорд, оценка стримера). Снимок оверлея 1920x1080 проверен глазами. Карточка живёт 15 мин.
acceptance
A2.5 Сырой микрофон, открыт только при OBS + играющем треке
✓ test_s2 A2_5 x4 зелёные. Живой микрофон USB PnP открылся и записал 2,9 с (WASAPI). Песня на стриме = OBS запущен; ошибка микрофона больше не стирает песню (регресс).
acceptance
готовS3 · С3 · Чарт и «что спеть»5/5

Цель: Сцена топ-чарта и подсказка что спеть

С3 · Топ-чарт песен/исполнителей, «что спеть», статистика
✓ Код + экзамены зелёные, ОТК круг 1 пройден. Коммит 21b4a38.
feature
A3.1 Топ-10 песен и исполнителей с числом исполнений
✓ test_s3 A3_1 x5 зелёные. На сцене у песен «спето N раз».
acceptance
A3.2 «Что спеть»: до 5, оценка >=7, давно не петые, без сегодняшних
✓ test_s3 A3_2 x3 зелёные.
acceptance
A3.3 Статистика: все исполнения и честная доля по датам
✓ test_s3 A3_3 зелёный + снимок /stats; список ограничен 500, дни считаются по всей базе. Масштаб: 3000 исполнений -> /api/stats 40 мс.
acceptance
A3.4 Чарт 1920x1080 без вылезающего текста
✓ Снимок 1920x1080: 20 строк, ниже кадра 0, текст на рамках 0, низ последней строки 931 px.
acceptance
готовS4 · С4 · Голоса зрителей6/6

Цель: !оценка N в чате Twitch = столбец зрителей в чарте

С4 · Чтение чата Twitch, голоса зрителей в чарте
✓ Канал logonchekk в data/config.json (17.10). Сервис: «чат: подключён к logonchekk»; Twitch подтвердил вход (JOIN + 366). Живые голоса зрителей проверяются на первом стриме (проверка 24.10).
feature
A4.1 Голос идёт песне, закончившейся <90 с назад, иначе текущей
✓ test_s4 A4_1 x3 зелёные (после песни <90 с, иначе текущей, окно настраивается).
acceptance
A4.2 Один зритель = один голос, повтор заменяет
✓ test_s4 A4_2 зелёный: ник без учёта регистра, повтор заменяет.
acceptance
A4.3 Мусор и числа вне 1-10 игнорируются
✓ test_s4 A4_3 зелёный; плюс принимаются «!оценка: 7», «7/10», «10!»; дробные отклоняются.
acceptance
A4.4 Столбец «зрители» в чарте
✓ test_s4 A4_4 зелёный; столбец «Зрители» на сцене чарта (снимок).
acceptance
A4.5 Чат без токена, в чат ничего не пишется
✓ test_s4 A4_5 зелёный; критик подтвердил вживую анонимное подключение justinfan, в чат уходят только NICK/JOIN/PONG.
acceptance
планS5 · Проверки по сроку0/1

Цель: Отложенные проверки на живом стриме

Первый стрим с караоке-чартом: всё ли сработало вживую
⏱ 24.10 · просрочено 6 дн.
Проверка: открыть http://127.0.0.1:8765/stats — есть исполнения со стрима, у спетых есть цифра; data/karaoke.log без «ошибка цикла»/«упал»; в OBS есть док «Караоке», оверлей во всех сценах «Большой экран…» 1:1, сцена «Топ-чарт». Яндекс Музыка: /api/state во время трека -> now.artist/title заполнены, app ru.yandex.desktop.music. Если задан канал: в чарте у песен есть голоса.
⛔ Стрим 19.10: оценка по мелодии не сработала. На экране 5-20 из 100, доля совпадений с певцом 0-0,12 при случайном 0,20, сдвиг голоса у края окна 780-800 мс. Похоже, звук трека пишется не с того устройства или тишиной. Голоса зрителей и оценка стримера работали (стример ставил 9-11). Разбирать на живом звуке вместе с владельцем, не перед эфиром: при запущенном OBS и играющем треке смотреть /api/state (music_device, music_error) и уровень loopback.
check
В РАБОТЕS6 · С5 · Мелодия оригинала7/10

Цель: Оценка = попадание в ноты певца; записи 12.10 = 80–85

↑ С5 · Звук трека + отделение голоса певца на видеокарте + сравнение с мелодией + калибровка
Решение владельца 17.10: вариант (а), запасной (б); шкала: записи 12.10 = 80–85, хуже 60–75, криво низко. GPU-скачивание одобрено.
feature
A5.1 Точно по мелодии → 95+
✓ test_s5 A5_1 зелёный (точно по мелодии ≥95). Плюс живая песня: голос певца против своей мелодии = 100.
acceptance
A5.2 Полутон мимо → <60; ±25 центов → >80
✓ test_s5 A5_2 x2 зелёные (полутон мимо <60, ±25 центов >80).
acceptance
A5.3 Задержка 250 мс не штраф
✓ test_s5 A5_3 зелёный: задержка 250 мс найдена, оценка та же ±3.
acceptance
A5.4 Октава ниже не штраф
✓ test_s5 A5_4 зелёный: октава ниже не штраф.
acceptance
A5.5 Тишина/другая мелодия → не пел или <40
✓ test_s5 A5_5 x2 зелёные: тишина = не пел, чужая мелодия <40 (добавлена точка шкалы 0,35A=30 для уровня случайных совпадений).
acceptance
A5.6 Живой трек: голос отделяется на GPU, карточка ≤5 с
✓ Сквозной прогон на настоящей песне (4:19) через сервис: голос отделяется на RTX 3060 по ходу песни, карточка через 3,9 с, идеальный певец 99. Модель грузится при старте сервиса (журнал: «модель голоса готова (cuda)»). Ждёт: живой трек из Яндекс Музыки на стриме.
acceptance
A5.7 Записи 12.10 по мелодии своих песен → 80–85
✓ Инструмент tools/calibrate.py готов (record + fit, поиск сдвига проверен: 30,00 с).
⛔ Нужны названия песен из записей 12.10 (Запись 2/4/5) и один проигрыш каждой в Яндекс Музыке — тогда якорь шкалы ставится по ним (80–85).
acceptance
A5.8 Звук трека только вместе с микрофоном
✓ test_s5 A5_8 зелёный: без OBS звук трека не пишется, с OBS пишется вместе с микрофоном; карточка по мелодии ≤5 с.
acceptance
A5.9 Трек без голоса → запасная оценка
✓ test_s5 A5_9 зелёный: трек без голоса → запасная оценка по нотам.
acceptance

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

23.10.2026, 17:40:06 · шкала под стрим · claude

23.10 (2): разбор цифры 5-20. Не железо: микрофон -23 дБ, звук трека верный. Совпадение владельца с певцом 0-0,14 (на записи 45 с 7,5%, по 12 тональностям максимум 19,5% при случайном 14-17%). Решение владельца: цифра на экране. Шкала под стрим calibration.live_anchor=0,0644 (середина 28 песен от 80 нот), недопетые честно ниже по просьбе владельца. Целиком спетые среднее 80 (55-90), недопетые 61. 55 старых цифр пересчитаны из raw (копия базы). Экзамены 51/51, регресс 36/36. Сервис перезапущен. Рубка закрыта, сторож выключен.

→ 1) Посмотреть цифры после стрима 23.10. 2) A5.5 под шкалой стрима не держится: решение владельца, критерий не правлен. 3) Ресерч мягкой оценки как в караоке-играх (нотами, а не кадрами 10 мс). 4) Закоммитить. 5) Автозапуск Karaoke Chart выключен.

23.10.2026, 16:55:09 · С1 / проверка стрима · claude

23.10: ВК Музыка и YouTube Music. Причина, по которой караоке их не видело: открытая на паузе Яндекс Музыка всегда побеждала играющий плеер. Теперь играющий важнее паузы, при двух играющих первая Яндекс, плеер, игравший последним, держит свою паузу. Регресс ДругиеПлееры 6/6 (на старом коде 3 падают), экзамены 51/51, регресс 32/32 (тест видеокарты в общем прогоне упал по таймауту холодного старта, отдельно зелёный за 24 с). Сервис запущен руками (автозапуск выключен с отката 18.10), чат logonchekk подключён. Найдено по журналу: на стриме 19.10 оценка по мелодии давала 5-20 из 100. Не закоммичено.

→ 1) Владелец проверяет на стриме трек из ВК/YouTube Music, смотреть /api/state. 2) Разобрать оценку по мелодии на живом звуке (устройство loopback). 3) Решить, включать ли обратно автозапуск «Karaoke Chart». 4) Закоммитить sources.py, тесты, PROJECT.md.

17.10.2026, 20:10:59 · С5 / первый стрим · claude

17–18.10 первый живой стрим. Владелец попросил откатить правки OBS (фильтры голоса, панель Караоке, оверлей и сцену Топ-чарт) — откачены скриптом tools/obs_uninstall.py после закрытия OBS, автозапуск сервиса выключен. Потом владелец сам попросил запустить караоке фоном: сервис работал без OBS-встройки, оценки 1–10 и особые (11 «ОХУИТЕЛЬНО», 0 «КАЛ») и голоса чата писались (у «Рваные джинсы» 5 голосов). Добавлен прокручиваемый чарт /chart?all=1. Трансляция не стартовала из-за VPN tun2socks, не из-за правок. ПРОБЛЕМА: сравнение с мелодией на живых песнях даёт 1–12% совпадений (уровень случайности), цифры «Пение» 6–21, задержка часто упирается в край окна — голос с треком не сопоставляются.

→ 1) Разобрать живое сравнение: записать одну песню (мик + loopback REDMI) на диск в отладочном режиме, проверить выравнивание, задержку блютуса (>0,8 с?), громкость голоса. 2) Зрители в /chart?all=1 для всех песен (параметр limit в /api/chart). 3) Калибровка по записям 12.10 (нужны названия песен). 4) Что возвращать в OBS — только с владельцем и не перед эфиром.

17.10.2026, 16:59:44 · С4 · claude

Владелец дал канал Twitch logonchekk: вписан в data/config.json, сервис перезапущен, чат подключён анонимно, Twitch подтвердил вход (JOIN + 366). С4 закрыт.

→ Развилка оценки пения (A2.2, С2 заблокирован). Закрыть OBS, чтобы встройка установилась. Живой трек Яндекс Музыки для A1.1. Проверка по сроку 24.10.

17.10.2026, 16:25:59 · С1–С4 · claude

Собран локальный сервис караоке-чарта (127.0.0.1:8765, автозапуск задачей «Karaoke Chart»): трек из медиа-сеанса Windows, замер нот по сырому микрофону при запущенном OBS, карточка после песни, док оценок 1–10, сцена топ-чарта, статистика, голоса из чата. Экзамены 41/42, регресс 16/16, ОТК 3 круга (около 40 находок, подтверждённые исправлены с тестами). Найдено: честный метод показывает, что цифра пения у владельца неотличима от случайной (A2.2 красный). Встройка в OBS ждёт закрытия OBS (фоновое ожидание). Коммиты b984fed, 21b4a38, bca011b.

→ 1) Владелец: имя канала Twitch -> data/config.json. 2) Владелец: развилка оценки пения (мелодия оригинала / составная / оставить), от неё A2.2. 3) Закрыть OBS -> tools/obs_install.py ставит док, оверлей, сцену. 4) Первый трек из Яндекс Музыки -> закрыть A1.1. 5) Проверка по сроку 24.10.