KZFR // УПРАВЛЕНИЕ РАДИОЭФИРОМ
Эта тема — единый источник медиатеки радио Кибер-Сиэтла. Каждый следующий ответ описывает один аудиоэлемент. В коде форума хранятся только логика плеера и правила ротации; треки, джинглы и перебивки добавляются и отключаются здесь.
Как будет работать эфир
• MUSIC — музыкальная основа станции.
• JINGLE — короткая заставка или опознавательный сигнал KZFR.
• BREAK — голосовая перебивка: новости, реклама, погода, предупреждение, обращение ведущего или сюжетное объявление.
Плеер собирает случайную колоду без повторов. Музыка остаётся основой потока; джинглы и перебивки вставляются между треками и не должны идти друг за другом. После полного круга колода перемешивается заново. Запись с ACTIVE: NO сохраняется в архиве темы, но в эфир не попадает.
Подготовка и загрузка аудио
1. Используйте только собственные материалы либо звук, на который у проекта есть разрешение.
2. Рекомендуемый формат — MP3. Допустим OGG, если файл стабильно открывается в браузере.
3. Для музыки желательно 128–192 kbps; голосовые вставки можно сжимать сильнее.
4. Нормализуйте громкость: джингл или реклама не должны быть заметно громче музыки.
5. Название файла делайте понятным: kzfr_music_night-drive_01.mp3 или kzfr_break_acid-rain_01.mp3.
6. Загрузите файл через кнопку «Вложения» в форме ответа либо в форумное файловое хранилище.
7. После загрузки получите прямую HTTPS-ссылку на сам файл. Она должна оканчиваться на .mp3 или .ogg и открывать/воспроизводить аудио, а не страницу загрузки.
8. Создайте новый ответ по шаблону ниже. Один ответ — один аудиофайл.
Шаблон новой записи
TYPE: MUSIC TITLE: Название трека или вставки ARTIST: Автор / ведущий / KZFR AUDIO: https://прямая-ссылка-на-файл.mp3 WEIGHT: 1 ACTIVE: YES NOTE: Короткое служебное пояснение
Значения полей
TYPE — MUSIC, JINGLE или BREAK.
TITLE — отображаемое название записи.
ARTIST — исполнитель, голос ведущего или название станции.
AUDIO — только прямая HTTPS-ссылка на MP3/OGG.
WEIGHT — частота появления: 1 — обычная, 2 — чаще, 3 — приоритетная. Значения выше 3 без необходимости не использовать.
ACTIVE — YES включает запись, NO временно исключает её из эфира.
NOTE — внутреннее примечание: назначение, сюжет, срок актуальности или версия.
Обновление записи
Чтобы заменить джингл, отредактируйте соответствующий ответ и поменяйте AUDIO. Чтобы временно убрать материал, установите ACTIVE: NO. Не удаляйте старые записи без необходимости: тема одновременно служит журналом медиатеки.
Важно
Автоматическое воспроизведение со звуком браузеры блокируют, поэтому пользователь сам включает радио. Плеер должен запоминать громкость, текущую запись и позицию между страницами.
КОНСТРУКТОР ЗАПИСИ KZFR
[html]
<style>body{margin:0;background:#071014;color:#d9faff;font:13px Arial,sans-serif}.kzbox{border:1px solid #00c7d4;background:linear-gradient(135deg,#07171c,#040b10);padding:16px;box-sizing:border-box}.kztop{display:flex;justify-content:space-between;gap:10px;color:#59f3ff;font:700 15px monospace;letter-spacing:2px;margin-bottom:12px}.badge{color:#b5ff3d}.grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}.wide{grid-column:1/-1}label{display:block;color:#66bfc8;font:700 10px monospace;letter-spacing:1px;margin-bottom:4px}input,select,textarea{width:100%;box-sizing:border-box;border:1px solid #17616b;background:#02090c;color:#eaffff;padding:9px;font:13px Arial}textarea{min-height:72px;resize:vertical}.out{min-height:145px;font-family:monospace;color:#9df8ff}.buttons{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}button{border:1px solid #00c7d4;background:#08323a;color:#a5f9ff;padding:9px 14px;font:700 11px monospace;cursor:pointer}button:hover{background:#0b4a55}.status{margin-top:8px;color:#86aeb4;font:11px monospace}.error{color:#ff6d7a}@media(max-width:600px){.grid{grid-template-columns:1fr}.kztop{display:block}.badge{margin-top:4px}}</style>
<div class="kzbox"><div class="kztop"><span>KZFR // MEDIA ENTRY BUILDER</span><span class="badge">108.6 FM</span></div><div class="grid"><div><label>ТИП ЗАПИСИ</label><select id="kz_type"><option>MUSIC</option><option>JINGLE</option><option>BREAK</option></select></div><div><label>ЧАСТОТА / WEIGHT</label><select id="kz_weight"><option>1</option><option>2</option><option>3</option></select></div><div class="wide"><label>НАЗВАНИЕ</label><input id="kz_title" placeholder="Название трека или вставки"></div><div class="wide"><label>ИСПОЛНИТЕЛЬ / ГОЛОС / СТАНЦИЯ</label><input id="kz_artist" placeholder="Автор / ведущий / KZFR"></div><div class="wide"><label>ПРЯМАЯ HTTPS-ССЫЛКА НА MP3 ИЛИ OGG</label><input id="kz_audio" placeholder="https://forumstatic.ru/files/...mp3"></div><div><label>АКТИВНОСТЬ</label><select id="kz_active"><option>YES</option><option>NO</option></select></div><div><label>СЛУЖЕБНОЕ ПРИМЕЧАНИЕ</label><input id="kz_note" placeholder="Ротация, версия или назначение"></div><div class="wide"><label>ГОТОВАЯ ЗАПИСЬ</label><textarea id="kz_out" class="out" readonly></textarea></div></div><div class="buttons"><button type="button" onclick="kzBuild()">СОБРАТЬ</button><button type="button" onclick="kzCopy()">КОПИРОВАТЬ</button><button type="button" onclick="kzClear()">ОЧИСТИТЬ</button></div><div id="kz_status" class="status">Один аудиофайл — одна запись в теме.</div></div>
<script>function kzv(id){return document.getElementById(id).value.trim()}function kzBuild(){var a=kzv('kz_audio'),st=document.getElementById('kz_status');if(a.indexOf('https://')!==0||(a.toLowerCase().indexOf('.mp3')<8&&a.toLowerCase().indexOf('.ogg')<8)){st.className='status error';st.textContent='Нужна прямая HTTPS-ссылка, оканчивающаяся на .mp3 или .ogg';return ''}var s='TYPE: '+kzv('kz_type')+'\nTITLE: '+(kzv('kz_title')||'—')+'\nARTIST: '+(kzv('kz_artist')||'KZFR')+'\nAUDIO: '+a+'\nWEIGHT: '+kzv('kz_weight')+'\nACTIVE: '+kzv('kz_active')+'\nNOTE: '+(kzv('kz_note')||'—');document.getElementById('kz_out').value=s;st.className='status';st.textContent='Запись собрана и готова для вставки в новый ответ.';return s}function kzCopy(){var o=document.getElementById('kz_out');if(!o.value&&!kzBuild())return;o.focus();o.select();var done=false;try{done=document.execCommand('copy')}catch(e){}if(navigator.clipboard){navigator.clipboard.writeText(o.value).then(function(){document.getElementById('kz_status').textContent='Скопировано в буфер обмена.'}).catch(function(){document.getElementById('kz_status').textContent=done?'Скопировано в буфер обмена.':'Выделите результат и скопируйте вручную.'})}else document.getElementById('kz_status').textContent=done?'Скопировано в буфер обмена.':'Выделите результат и скопируйте вручную.'}function kzClear(){['kz_title','kz_artist','kz_audio','kz_note','kz_out'].forEach(function(id){document.getElementById(id).value=''});document.getElementById('kz_type').value='MUSIC';document.getElementById('kz_weight').value='1';document.getElementById('kz_active').value='YES';var st=document.getElementById('kz_status');st.className='status';st.textContent='Форма очищена.'}</script>
[/html]