Hamy Radio

API для разработчиков

Открытый JSON без ключей и лимитов на чтение. CORS разрешён для любых сайтов — можно запрашивать прямо из браузера, игры или бота.

Прямой поток

https://radio.hamystudio.ru/listen/demka        MP3 128 кбит/с, 44.1 кГц, стерео
https://radio.hamystudio.ru/listen/demka.mp3    то же самое (для плееров, которым нужно расширение)
https://radio.hamystudio.ru/listen/demka.m3u    плейлист M3U
https://radio.hamystudio.ru/listen/demka.pls    плейлист PLS

Поддерживаются ICY-метаданные: пришлите заголовок Icy-MetaData: 1 — в ответе будет icy-metaint, а в потоке — StreamTitle='Исполнитель - Название'. Так название песни показывают VLC, Winamp, AIMP, Unity/FMOD и большинство игровых движков. Заголовки icy-name, icy-genre, icy-description, icy-br приходят всегда.

Новый слушатель сразу получает несколько секунд эфира — воспроизведение начинается мгновенно.

Станции

GET https://radio.hamystudio.ru/api/v1/stations
GET https://radio.hamystudio.ru/api/v1/stations?genre=rock        фильтр по жанру
GET https://radio.hamystudio.ru/api/v1/stations?nowplaying=0      без текущих треков (легче)
GET https://radio.hamystudio.ru/api/v1/stations?all=1             включая станции вне каталога

Список станций в эфире со всеми полями из ответа ниже.

GET https://radio.hamystudio.ru/api/v1/stations/demka
{
  "id": 1,
  "slug": "demka",
  "name": "Название станции",
  "slogan": "Короткий слоган",
  "description": "Описание",
  "genre": "Lo-fi",
  "tags": ["chill", "ночь"],
  "language": "ru",
  "country": "RU",
  "timezone": "Europe/Moscow",
  "website": "https://…",
  "color": "#7c5cff",                    // фирменный цвет — для оформления в игре
  "logo_url": "https://radio.hamystudio.ru/media/logo/1?v=…", // PNG 512×512 (или SVG-заглушка, если has_logo=false)
  "has_logo": true,
  "page_url": "https://radio.hamystudio.ru/s/demka",
  "online": true,
  "online_since": 1762790000,
  "listeners": 12,
  "listeners_peak": 40,
  "max_listeners": 100,
  "owner": "логин владельца",
  "stream": {
    "url": "https://radio.hamystudio.ru/listen/demka",
    "format": "mp3", "codec": "mp3", "content_type": "audio/mpeg",
    "bitrate": 128, "sample_rate": 44100, "channels": 2,
    "icy_metadata": true,
    "m3u": "…/listen/demka.m3u", "pls": "…/listen/demka.pls"
  },
  "library": {"songs": 230, "jingles": 6, "public": false},
  "now_playing": { …см. nowplaying… },
  "history": [ …10 последних песен… ],
  "links": {"self": "…", "nowplaying": "…", "history": "…", "events": "…", "stream": "…"},
  "created_at": 1762700000
}

Сейчас в эфире

GET https://radio.hamystudio.ru/api/v1/stations/demka/nowplaying
{
  "station": "demka",
  "online": true,
  "listeners": 12,
  "track": {
    "id": 42,
    "kind": "music",            // music | jingle | tts (озвучка) | silence (пауза)
    "title": "Название",
    "artist": "Исполнитель",
    "album": "Альбом",
    "genre": "Жанр",
    "year": 2024,
    "text": "Исполнитель - Название",
    "duration": 215.3,          // секунды
    "cover_url": "https://radio.hamystudio.ru/media/cover/42",
    "has_cover": true
  },
  "started_at": 1762790123,     // unix-время начала трека
  "elapsed": 61.2,
  "remaining": 154.1,
  "progress": 0.284,
  "next": { …трек того же вида… },   // что прозвучит следующим (если известно)
  "server_time": 1762790184
}

Чтобы плавно двигать прогресс-бар, считайте elapsed = now - started_at с поправкой на server_time.

События в реальном времени

GET https://radio.hamystudio.ru/api/v1/stations/demka/events     (text/event-stream)

Server-Sent Events: событие nowplaying приходит сразу при подключении, при каждой смене трека и раз в 15 секунд (с актуальным числом слушателей). Данные — тот же JSON, что у /nowplaying. Опрашивать API по таймеру не нужно.

const es = new EventSource('https://radio.hamystudio.ru/api/v1/stations/demka/events');
es.addEventListener('nowplaying', e => {
  const np = JSON.parse(e.data);
  console.log(np.track.text, np.listeners);
});

История и библиотека

GET https://radio.hamystudio.ru/api/v1/stations/demka/history?limit=50     до 200 последних песен
GET https://radio.hamystudio.ru/api/v1/stations/demka/tracks?q=поиск        список песен (если владелец открыл библиотеку или с ключом)

Управление эфиром

Нужен ключ станции (панель станции → API). Передавайте его в заголовке X-Api-Key или Authorization: Bearer ….

POST /api/v1/stations/{slug}/skip
     следующий трек

POST /api/v1/stations/{slug}/queue
     {"track_id": 42}
     песня прозвучит после текущей

POST /api/v1/stations/{slug}/announce
     {"text": "Привет!", "voice": "irina"}
     озвучить текст после текущего трека

Голоса: irina — Ирина, ruslan — Руслан, denis — Денис, dmitri — Дмитрий. В тексте работают подстановки:

{станция}название станции{время}время по часовому поясу станции словами: «двадцать один час пятнадцать минут»{дата}«десятое ноября»{день}день недели{приветствие}«Доброе утро / Добрый день / Добрый вечер / Доброй ночи»{далее}что прозвучит следующим: «Исполнитель — Название»{далее_исполнитель}исполнитель следующей песни{далее_название}название следующей песни{было}песня, которая только что прозвучала{слушателей}число слушателей прописью

Платформа

GET https://radio.hamystudio.ru/api/v1/platform

Название, число станций в эфире и слушателей, параметры потока.

Ошибки

Ответ с кодом 4xx/5xx и JSON {"error": "код"}: station_not_found, bad_api_key, offline, track_not_found, empty_text, unknown_voice, library_is_private.