Голосования¶
Голосования — это витрина опроса Twitch на сцене OBS плюс пульт в кабинете. Сам опрос живёт в Twitch:
PulseCaster его не подменяет, а показывает и вызывает те же действия, что и панель опросов на самом Twitch.
Опрос, запущенный из панели Twitch, со Stream Deck или чужим ботом, появится на сцене так же, как запущенный из кабинета. Никакого отдельного «нашего» голосования нет — есть один опрос канала.
Не путать с командой !опрос
Команда !опрос в чате считает сообщения «да» и «нет» и к этому разделу отношения не имеет. Здесь —
настоящий опрос Twitch: с кнопками у зрителей, голосом за баллы канала и итогами в чате.
Раздел устроен так же, как Предикты: если вы уже настроили предикт на сцене, здесь всё будет знакомо. Отличие в том, что у опроса нет ставок и победителя не выбирают руками — побеждает вариант с большинством голосов.
Нужна помощь разработчика?
Напишите mrgorkiy в Telegram. Укажите страницу, ожидаемый результат, что произошло и шаги для повторения. Можно приложить скриншот или короткое видео. Перед отправкой закройте токены, коды подтверждения и приватные ссылки OBS.
Что нужно, чтобы это работало¶
| Условие | Зачем | Что будет без него |
|---|---|---|
Статус Affiliate или Partner |
Twitch разрешает опросы только им | Запуск вернёт отказ Twitch |
| Подключён Twitch-аккаунт владельца | Через него идут все вызовы | Раздел скажет, что аккаунт не подключён |
Право channel:read:polls |
Голоса зрителей приходят событиями EventSub | Проценты на сцене замрут между действиями |
Право channel:manage:polls |
Пульт запускает и завершает опрос | Пульт покажет опрос, но кнопки будут недоступны |
Права выдаются при подключении Twitch-аккаунта владельца. Если раздел просит переподключиться — значит, токен выпущен до появления этих прав.
Кому в команде открыт раздел¶
Владельцу канала — всегда. Модератору — только если вы выдали ему зону Голосования в разделе
Модераторы. Она отдельная от зоны Предикты: запуск опроса ничего у зрителей не забирает,
а итог предикта раздаёт баллы и не отменяется, поэтому эти права удобно выдавать порознь.
Что можно делать¶
На странице Владелец → Голосования две вкладки.
Голосования — всё, что нужно во время эфира:
- пульт: идущее голосование с отсчётом и голосами,
Завершить и показать итоги,Убрать без итогов; - итог последнего голосования: победитель, ничья или «никто не проголосовал»;
- заготовки с запуском в одну кнопку и форма для новой заготовки.
Сцена OBS — то, что настраивается один раз:
- сколько итоги висят на сцене и показывать ли число голосов;
- оформление сцены с превью: цвета, размер текста, скругление, положение в источнике и появление;
- приватная OBS-ссылка для Browser Source и демонстрационный режим.
Как голосование ведёт себя на сцене¶
| Стадия | Что на сцене |
|---|---|
| Голосование идёт | опрос виден, проценты растут, лидер подсвечен, идёт обратный отсчёт |
| Время вышло | итоги видны ещё 15 секунд, победитель подсвечен |
| Завершено досрочно | итоги видны так же, ещё 15 секунд |
| Ничья | подсвечены все варианты, поделившие первое место |
| Никто не проголосовал | опрос виден с подписью «Никто не проголосовал» |
| Убрано без итогов | источник пустеет сразу |
| Удалено модерацией Twitch | источник пустеет сразу |
| Голосования нет | источник пустой |
15 секунд — значение по умолчанию, оно настраивается во вкладке Сцена OBS. Диапазон — от 0 до 3600
секунд; 0 означает «убрать сразу».
Пока голосование идёт, оно видно всегда — это не настраивается: иначе зритель не поймёт, за что голосует.
Twitch через некоторое время сам убирает итоги из чата. На сцене это показ не сокращает: итоги висят столько, сколько задано в кабинете.
Обратный отсчёт страница ведёт сама. Сервер присылает момент конца голосования, а не остаток, поэтому цифры идут ровно даже при коротком обрыве связи.
Два способа закончить раньше¶
| Кнопка | Что делает Twitch | Что на сцене |
|---|---|---|
Завершить и показать итоги |
останавливает голосование и объявляет итог в чате | итоги с победителем, как после конца времени |
Убрать без итогов |
останавливает голосование и убирает его из чата без результата | источник пустеет сразу |
Убрать без итогов подходит, если голосование запустили по ошибке. Кабинет попросит подтвердить это
действие: вернуть опрос после снятия нельзя.
Заготовки¶
Заготовка — это заранее собранное голосование: вопрос, варианты, длительность и цена дополнительного голоса. Запуск делается одной кнопкой, без набора текста в эфире.
Длительность вводится с переключателем секунды / минуты: 2 минуты и 120 секунд — одно и то же, но в
списке заготовок это видно без пересчёта в уме.
Дополнительные голоса за баллы канала¶
Первый голос у каждого зрителя бесплатный. Если включить опцию, зрители смогут докупать голоса за баллы канала — столько, сколько захотят. Цена одного голоса задаётся в заготовке.
Потраченные баллы не возвращаются ни при каком итоге: это не ставка, а покупка голоса. Такие голоса Twitch учитывает в процентах наравне с бесплатными; в пульте видно, сколько голосов куплено.
Заготовки живут в PulseCaster, а не в Twitch. Удаление заготовки не влияет на идущее голосование.
Ограничения Twitch¶
Кабинет проверяет поля теми же мерками, что и Twitch, поэтому отказ приходит до запуска, а не после.
| Поле | Ограничение |
|---|---|
| Вопрос | до 60 символов |
| Варианты | от 2 до 5, каждый до 25 символов |
| Длительность | от 15 секунд до 30 минут |
| Цена дополнительного голоса | от 1 до 1 000 000 баллов |
| Одновременных голосований | ровно одно на канал |
Голосования за Bits Twitch больше не поддерживает, поэтому в кабинете их нет.
Оформление сцены¶
Во вкладке Сцена OBS блок Оформление на сцене меняет вид голосования без CSS. Слева превью, справа
настройки: нажмите на элемент превью — откроются его настройки. Кнопки Голосование и Итог переключают
пример, Повторить проигрывает появление ещё раз.
| Настройка | Что меняет |
|---|---|
Положение в источнике |
Сверху или Снизу прижимает плашку к краю источника OBS. Как в адресе ссылки оставляет решение параметру position в адресе, без него — сверху |
Появление |
откуда плашка выезжает: снизу, сверху, слева, справа или просто проявляется |
Панель |
цвет фона, его непрозрачность и скругление углов |
Текст |
основной цвет (вопрос, названия вариантов, проценты), второстепенный (таймер, подписи, число голосов) и размер текста от 12 до 32 px; вопрос и таймер крупнее, подписи мельче — пропорции сохраняются |
Варианты |
цвет полос вариантов и цвет лидера: пока голосование идёт, вариант с наибольшим числом голосов подсвечивается им |
Победитель |
цвет полосы и значка победившего варианта и подписи с итогом |
Нажмите Сохранить оформление: открытый источник в OBS подхватит изменения сам, перезагружать его и
менять ссылку не нужно. Это работает и в демонстрационном режиме: выдуманное голосование продолжает крутиться,
а цвета меняются сразу. Вернуть стандартное подставляет встроенную тему — она тоже применяется только
после сохранения.
Пока оформление не сохраняли, голосование выглядит так же, как раньше. Правила из поля Custom CSS в OBS сильнее
настроек кабинета, поэтому готовые варианты оформления ниже задают свои цвета поверх них. С ?style=none
в адресе встроенная тема отключена, и из этих настроек действует только положение.
OBS-ссылка¶
Публичная ссылка имеет вид:
Токен показывается только сразу после создания или замены. PulseCaster хранит только хэш токена, поэтому
старую полную ссылку нельзя повторно раскрыть из настроек. Если URL потерялся, нажмите Заменить ссылку
и вставьте новый адрес в OBS.
Если ссылка выключена, токен неверный или канал не совпадает, страница отдаёт 404.
Ссылка голосования и ссылка предикта — разные: на сцену добавляются два источника, каждый со своим адресом.
Как добавить в OBS¶
- Откройте
Владелец→Голосования→ вкладкаСцена OBS. - Нажмите
Создать ссылкуи скопируйте адрес. - В OBS добавьте источник
Browser/Браузер. - Вставьте ссылку в поле URL.
- Задайте ширину
620и высоту480. Этого хватает на пять вариантов с длинными названиями; если подключаете крупный шрифт, проверьте демонстрационный режим и при необходимости увеличьте высоту. - При желании вставьте своё оформление в поле
Custom CSS.
Кабинет обновляет состояние в фоне без замены страницы экраном загрузки и без сброса несохранённых настроек и начатой заготовки.
Страница прозрачная и приходит с готовым оформлением — той же тёмной панелью, что у предикта, поэтому оба источника на одной сцене выглядят одной семьёй. Страница обновляется через SSE — перезагружать источник при запуске и завершении не нужно.
Параметры адреса¶
| Параметр | Что делает |
|---|---|
?demo=1 |
крутит выдуманное голосование: голоса прибывают, потом победитель, ничья, «никто не проголосовал» |
?style=none |
отключает декоративную тему; для полностью собственного CSS, а не шаблонов ниже |
?position=bottom |
прижимает голосование к нижнему краю источника, если в кабинете выбрано Как в адресе ссылки |
?position=top |
прижимает к верхнему краю (так же ведёт себя адрес без параметра) |
?demo=1 нужен, чтобы подбирать CSS: настоящее голосование для этого запускать не надо. Демонстрационное
голосование живёт только на этой странице, в Twitch оно не попадает.
Уберите ?demo=1 перед эфиром
Пока параметр в адресе источника, страница показывает выдуманное голосование и не следит за настоящим.
Положение проще задать в блоке Оформление на сцене: выбор Сверху или Снизу там сильнее параметра
в адресе и применяется к уже добавленному источнику без правки URL. Параметр position нужен, когда
положение хранится в адресе конкретного источника — так копировались ссылки раньше. Параметры совмещаются
через &: ?demo=1&position=bottom.
style=none нужен только для оформления с нуля. Готовые CSS ниже дополняют встроенную тему:
удалите style=none из адреса, полностью замените содержимое поля Custom CSS выбранным блоком
и обновите источник OBS. Не смешивайте несколько шаблонов. Без темы не будет отступов, цветов и полос;
скрытие отсчёта после конца, значка у не победивших вариантов и отключённого числа голосов сохраняется.
Стили в OBS¶
Оформление по умолчанию целиком завёрнуто в :where(), у которого нулевой вес. Поэтому обычное правило из
Custom CSS — например .pc-poll { ... } — сильнее любого правила темы, и !important не нужен.
Стабильная структура страницы:
<div class="pc-poll"
data-status="active"
data-visible="true"
data-choices="3"
data-votes="true"
data-hurry="false"
data-result=""
data-poll-id="f3c1...">
<div class="pc-poll-head">
<span class="pc-poll-title">Во что играем после перерыва?</span>
<span class="pc-poll-timer" data-seconds="95">01:35</span>
</div>
<span class="pc-poll-points">Дополнительный голос — 250 баллов</span>
<span class="pc-poll-note"></span>
<ol class="pc-poll-choices">
<li class="pc-poll-choice"
data-index="1"
data-choice-id="a1b2"
data-leader="true"
data-winner="false"
data-percent="54.0"
style="--pc-poll-percent: 53.95;">
<span class="pc-poll-choice-head">
<span class="pc-poll-choice-title">Doom</span>
<span class="pc-poll-choice-badge" hidden>Победитель</span>
</span>
<span class="pc-poll-choice-stats">
<span class="pc-poll-choice-percent">54%</span>
<span class="pc-poll-choice-votes">41 голос</span>
</span>
<span class="pc-poll-choice-bar"><span class="pc-poll-choice-fill"></span></span>
</li>
</ol>
<span class="pc-poll-total">Всего 76 голосов</span>
</div>
Что можно использовать в CSS:
| Селектор или атрибут | Что это |
|---|---|
.pc-poll |
корень: плашка, рамка, фон, размер |
.pc-poll-title |
вопрос |
.pc-poll-timer |
обратный отсчёт до конца голосования |
.pc-poll-points |
подсказка про дополнительный голос за баллы, пока голосование идёт |
.pc-poll-note |
подпись итога: победитель, ничья, «никто не проголосовал» |
.pc-poll-choice |
один вариант целиком |
.pc-poll-choice-title |
название варианта |
.pc-poll-choice-badge |
значок «Победитель» или «Ничья» |
.pc-poll-choice-percent |
доля голосов в процентах |
.pc-poll-choice-votes |
число голосов с подписью: «41 голос», «23 голоса» |
.pc-poll-choice-bar, .pc-poll-choice-fill |
полоса и её заполнение |
.pc-poll-total |
итоговая строка под вариантами |
[data-status="active\|completed\|terminated"] |
оформление под стадию |
[data-result="winner\|tie\|no_votes"] |
итог после конца голосования |
[data-choices] |
сколько всего вариантов |
[data-leader="true"] |
вариант, который лидирует, пока голосование идёт |
[data-winner="true"] |
победивший вариант; при ничьей — все поделившие первое место |
[data-index] |
номер варианта по порядку, чтобы раскрасить варианты по-разному |
[data-hurry="true"] |
последние десять секунд голосования |
[data-votes="false"] |
число голосов выключено в кабинете |
--pc-poll-percent |
доля голосов числом, для ширины полосы |
Скрытием управляет сама страница: когда срок показа вышел, она ставит data-visible="false". Своё правило
display для .pc-poll это не сломает. Если хочется своей анимации исчезновения, верните показ более
сильным селектором и анимируйте прозрачность:
html body .pc-poll[data-visible] { display: flex; }
.pc-poll { transition: opacity 0.4s ease; }
.pc-poll[data-visible="false"] { opacity: 0; }
Готовые варианты оформления¶
Каждый вариант рассчитан на источник шириной около 620 пикселей. Вставляйте CSS в поле Custom CSS
у Browser Source.
Список по умолчанию¶
Оформление по умолчанию уже такое — этот блок нужен, если хочется поменять цвета или размер, не собирая всё с нуля. Достаточно переопределить переменные:
.pc-poll {
--pc-poll-accent: #38bdf8;
--pc-poll-leader: #7dd3fc;
--pc-poll-win: #a3e635;
--pc-poll-surface: rgba(6, 10, 18, 0.9);
--pc-poll-text: #ffffff;
--pc-poll-muted: #9aa7bd;
--pc-poll-radius: 26px;
font-family: "Bahnschrift", "Segoe UI", system-ui, sans-serif;
}
.pc-poll-title {
font-size: 26px;
text-transform: uppercase;
}
.pc-poll-choice-bar {
height: 14px;
}
Табло¶
Варианты стоят в ряд, у каждого — крупный процент и свой цвет по номеру. Число голосов и подсказка про баллы скрыты, чтобы табло читалось с первого взгляда. Рассчитано на два–четыре варианта: пятый встанет вторым рядом.
html,
body {
margin: 0;
background: transparent;
overflow: hidden;
}
.pc-poll {
gap: 12px;
padding: 16px 20px;
font-family: "Segoe UI", system-ui, sans-serif;
}
.pc-poll-head {
justify-content: center;
gap: 12px;
}
.pc-poll-title,
.pc-poll-note {
text-align: center;
}
.pc-poll-title {
font-size: 22px;
}
.pc-poll-choices {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.pc-poll-choice {
flex: 1 1 130px;
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
padding: 12px 8px;
border-radius: 14px;
background: rgba(255, 255, 255, 0.05);
}
/* Свой цвет каждому варианту по номеру. */
.pc-poll-choice[data-index="1"] { --pc-poll-color: #3f8cff; }
.pc-poll-choice[data-index="2"] { --pc-poll-color: #ff3fa4; }
.pc-poll-choice[data-index="3"] { --pc-poll-color: #f7bd55; }
.pc-poll-choice[data-index="4"] { --pc-poll-color: #42d392; }
.pc-poll-choice[data-index="5"] { --pc-poll-color: #a18cff; }
.pc-poll-choice-head,
.pc-poll-choice-stats {
justify-content: center;
text-align: center;
}
.pc-poll-choice-stats {
order: -1;
}
.pc-poll-choice-percent {
color: var(--pc-poll-color);
font-size: 40px;
line-height: 1;
}
.pc-poll-choice-title {
font-size: 15px;
}
.pc-poll-choice-votes,
.pc-poll-points,
.pc-poll-total {
display: none;
}
.pc-poll-choice-bar {
width: 100%;
height: 6px;
}
/* Победитель остаётся своего цвета, но обводится. */
.pc-poll-choice[data-winner="true"] {
outline: 2px solid var(--pc-poll-win);
}
Без плашки¶
Текст поверх игры без фона: подходит, когда на сцене уже есть своя рамка.
html,
body {
margin: 0;
background: transparent;
overflow: hidden;
}
.pc-poll {
gap: 8px;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
box-shadow: none;
backdrop-filter: none;
color: #ffffff;
font-family: "Inter", system-ui, sans-serif;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.9);
}
.pc-poll-title {
font-size: 21px;
}
.pc-poll-choice-bar {
height: 6px;
background: rgba(255, 255, 255, 0.18);
}
.pc-poll-choice-votes,
.pc-poll-total {
display: none;
}
/* Итог виден без чтения: победитель загорается, остальные почти исчезают. */
.pc-poll[data-result="winner"] .pc-poll-choice[data-winner="false"],
.pc-poll[data-result="tie"] .pc-poll-choice[data-winner="false"] {
opacity: 0.25;
}
.pc-poll-choice[data-winner="true"] {
filter: drop-shadow(0 0 12px rgba(66, 211, 146, 0.55));
}
Промпт для AI-агента, который сделает свой CSS
Скопируйте текст ниже в ChatGPT, Codex или другой AI-инструмент, если хотите получить оформление под свою сцену.
Сделай готовый OBS Custom CSS для Browser Source с голосованием (опросом Twitch) PulseCaster.
Контекст:
- OBS открывает прозрачную HTML-страницу с опросом Twitch.
- Я не могу менять HTML и не хочу добавлять JavaScript.
- Можно использовать только CSS.
- У страницы уже есть оформление по умолчанию, завёрнутое в :where() с нулевым весом,
поэтому мои обычные правила его перебивают без !important.
- HTML-структура такая:
<div class="pc-poll"
data-status="active"
data-visible="true"
data-choices="3"
data-votes="true"
data-hurry="false"
data-result="">
<div class="pc-poll-head">
<span class="pc-poll-title">Во что играем после перерыва?</span>
<span class="pc-poll-timer" data-seconds="95">01:35</span>
</div>
<span class="pc-poll-points">Дополнительный голос — 250 баллов</span>
<span class="pc-poll-note"></span>
<ol class="pc-poll-choices">
<li class="pc-poll-choice" data-index="1" data-leader="true" data-winner="false"
data-percent="54.0" style="--pc-poll-percent: 53.95;">
<span class="pc-poll-choice-head">
<span class="pc-poll-choice-title">Doom</span>
<span class="pc-poll-choice-badge" hidden>Победитель</span>
</span>
<span class="pc-poll-choice-stats">
<span class="pc-poll-choice-percent">54%</span>
<span class="pc-poll-choice-votes">41 голос</span>
</span>
<span class="pc-poll-choice-bar"><span class="pc-poll-choice-fill"></span></span>
</li>
</ol>
<span class="pc-poll-total">Всего 76 голосов</span>
</div>
Что меняется само:
- data-status равен active, completed (время вышло) или terminated (завершено досрочно);
- data-visible становится false, когда срок показа вышел, и страница сама убирает голосование со сцены;
- data-result после конца равен winner, tie (ничья) или no_votes (никто не проголосовал);
- data-leader="true" стоит у лидирующего варианта, пока голосование идёт;
- data-winner="true" стоит у победителя после конца; при ничьей — у всех, кто поделил первое место;
- data-index — номер варианта по порядку, от 1 до 5;
- data-hurry="true" появляется в последние десять секунд;
- data-votes="false" появляется, если число голосов выключено в кабинете;
- переменная --pc-poll-percent на варианте всегда равна его доле голосов;
- .pc-poll-note содержит подпись итога, .pc-poll-points — подсказку про голос за баллы;
- значок .pc-poll-choice-badge пишет «Победитель», а при ничьей — «Ничья».
Задача:
- Сделай CSS для OBS Custom CSS.
- Фон должен быть прозрачным.
- Текст должен хорошо читаться поверх игры или камеры.
- Нужен стиль: [опиши стиль: неон, минимализм, ретро, киберпанк, спортивное табло и т.д.].
- Цвета сцены: [впиши основные цвета].
- Размер источника OBS: [например 620x480].
- Сколько вариантов обычно: [например два-три или до пяти].
- Шрифт: [системный или file:///путь/к/моему-шрифту.woff2].
Требования к ответу:
- Верни только готовый CSS.
- Не используй внешние URL, кроме моего file:/// шрифта, если я его указал.
- Используй селекторы .pc-poll, .pc-poll-title, .pc-poll-timer, .pc-poll-note,
.pc-poll-choice, .pc-poll-choice-title, .pc-poll-choice-percent,
.pc-poll-choice-bar, .pc-poll-choice-fill и атрибуты data-*.
- Не скрывай .pc-poll-choice-title и .pc-poll-choice-percent.
- Не пытайся скрывать голосование сам: это делает страница через data-visible.
- Ширину полосы бери из var(--pc-poll-percent), не из фиксированных значений.
- Сделай отдельный вид для data-result="winner", data-result="tie" и data-result="no_votes".
- Учитывай, что вариантов может быть от двух до пяти.
- Добавь font-variant-numeric: tabular-nums, чтобы проценты не дёргались.
- Если добавляешь анимацию, сделай её медленной и ненавязчивой.
Что делать, если на сцене пусто¶
| Признак | Причина | Что сделать |
|---|---|---|
| Источник пуст всегда | виджет выключен или ссылка заменена | включите виджет во вкладке Сцена OBS и проверьте адрес в OBS |
| Голосование видно, проценты стоят | нет права channel:read:polls |
переподключите Twitch-аккаунт владельца |
| Голосование не появилось после запуска из Twitch | события EventSub не дошли | откройте раздел Голосования — вход в него сверяет состояние с Twitch |
| Кнопки пульта недоступны | нет права channel:manage:polls |
переподключите Twitch-аккаунт владельца |
Запустить не нажимается |
на канале уже идёт голосование | завершите текущее |
| Twitch отказывает при запуске | канал не Affiliate и не Partner |
опросы Twitch такому каналу недоступны |
| Итоги пропали сразу | голосование убрали без итогов или задержка 0 |
проверьте настройку во вкладке Сцена OBS |
Безопасность¶
- Не публикуйте OBS-ссылку в чате или описании канала: по ней видно голосование канала.
- Не показывайте ссылку на стриме — в ней есть токен.
- Если ссылка утекла, нажмите
Заменить ссылку: старый адрес сразу перестанет открываться. - Если источник больше не нужен, нажмите
Выключить виджет: заготовки и настройки останутся.