Приватное защищённое вещание по ссылке с ключом

Защищённое вещание закрывает прямой доступ к аудиопотоку и позволяет выдавать слушателям временные ссылки, привязанные к IP-адресу.
Функция доступна в пакетах с возможностями PRO.
Важно! После сохранения секретного ключа стандартная ссылка на поток перестанет работать без действующего параметра key.

Для чего это можно использовать

Платная подписка. Сайт проверяет оплату и открывает поток только пользователям с действующей подпиской.
Закрытое корпоративное радио. Доступ получают только сотрудники, партнёры или участники команды.
Закрытый эфир или мероприятие. Ссылку можно выдать участникам курса, клуба, конференции или онлайн-события.
Временный гостевой доступ. Клиент или партнёр получает ссылку, которую нельзя использовать после окончания срока.
Демонстрационное прослушивание. Параметр duration ограничивает продолжительность одного подключения.
Защита не является системой оплаты или авторизации. MyRadio24 проверяет ссылку, а решение о том, кому её выдать, принимает ваш сайт.

Как работает защищённая ссылка

Ваш сервер создаёт подписанный ключ для конкретного слушателя и формирует ссылку:
https://myradio24.org/ЛОГИН?key=ПОДПИСАННЫЙ_КЛЮЧ
При подключении MyRadio24 проверяет:
Секретный ключ - хранится только у владельца радио.
IP-адрес - ссылка работает только для того адреса, для которого была создана.
expire - время, до которого разрешено начать новое подключение.
duration - ограничение продолжительности одного подключения в секундах.
Если подпись неверна, IP не совпадает или срок expire уже истёк, сервер отклоняет подключение.

Как включить защищённое вещание

1. Откройте панель управления радио.
2. Перейдите в раздел Настройки - Пакет PRO.
3. Найдите блок PRO Защищённое вещание по ссылке с ключом.
4. Укажите секретный ключ длиной от 6 до 30 символов. Используйте латинские буквы и цифры.
5. Сохраните настройки.
После сохранения панель покажет готовую ссылку на один час без ограничения времени проигрывания. Её можно использовать для быстрой проверки. Обычная ссылка на поток после включения защиты больше не воспроизводит радио - это нормальная работа функции.

Формат подписанного ключа

Ключ состоит из MD5-подписи и добавленного к ней значения expire:
key = md5(СЕКРЕТНЫЙ_КЛЮЧ + IP + expire + duration) + expire
Значения соединяются без разделителей и строго в указанном порядке.
expire - Unix timestamp в секундах. Отдельным параметром URL он не передаётся, так как уже добавлен в конец key.
duration - целое число секунд. Значение 0 означает отсутствие ограничения по продолжительности.
Если duration больше 0, его нужно передать в ссылке:
https://myradio24.org/ЛОГИН?key=ПОДПИСАННЫЙ_КЛЮЧ&duration=30
Duration участвует в подписи. Слушатель не сможет самостоятельно изменить 30 секунд на другое значение: после изменения параметра ключ станет недействительным.

Генерация ссылки на PHP

Секретный ключ храните в переменной окружения MYRADIO24_STREAM_SECRET.
<?php
function createMyRadio24Link(
    string $baseUrl,
    string $secretKey,
    string $listenerIp,
    int $expiresIn = 60,
    int $duration = 0
): string {
    if (!preg_match('/^[A-Za-z0-9]{6,30}$/', $secretKey)) {
        throw new InvalidArgumentException('Неверный формат секретного ключа');
    }
    if ($expiresIn < 1 || $duration < 0) {
        throw new InvalidArgumentException('Неверное ограничение времени');
    }

    $expire = time() + $expiresIn;
    $key = md5($secretKey . $listenerIp . $expire . $duration) . $expire;
    $query = ['key' => $key];

    if ($duration > 0) {
        $query['duration'] = $duration;
    }

    return $baseUrl . '?' . http_build_query($query);
}

$secretKey = getenv('MYRADIO24_STREAM_SECRET');
if (!$secretKey) {
    throw new RuntimeException('Не задан MYRADIO24_STREAM_SECRET');
}

$link = createMyRadio24Link(
    'https://myradio24.org/ЛОГИН',
    $secretKey,
    $_SERVER['REMOTE_ADDR'],
    60, // подключиться нужно в течение 60 секунд
    0   // без ограничения продолжительности
);

echo $link;
Для обычной выдачи ссылки рекомендуется expire от 30 до 60 секунд. Этого достаточно для запуска плеера, но недостаточно для длительной передачи ссылки другим людям.

Рекомендуемая схема для сайта с авторизацией

В плеере лучше указывать постоянный адрес своего сайта, например:
https://example.com/listen.php
Обработчик listen.php должен:
1. Проверить авторизацию пользователя.
2. Проверить подписку, приглашение или другое право доступа.
3. Сформировать новую ссылку для IP слушателя.
4. Перенаправить плеер на MyRadio24 ответом HTTP 302.
При переподключении плеер снова обратится к listen.php, а сайт повторно проверит доступ и выдаст свежую ссылку.
Упрощённый пример после подключения функции createMyRadio24Link из предыдущего раздела:
<?php
session_start();

// Замените эту проверку запросом к своей базе данных.
$userId = isset($_SESSION['user_id']) ? (int) $_SESSION['user_id'] : 0;
$accessAllowed = $userId > 0;

if (!$accessAllowed) {
    http_response_code(403);
    exit('Доступ к эфиру закрыт.');
}

$secretKey = getenv('MYRADIO24_STREAM_SECRET');
if (!$secretKey) {
    http_response_code(500);
    exit('Защищённое вещание не настроено.');
}

$streamUrl = createMyRadio24Link(
    'https://myradio24.org/ЛОГИН',
    $secretKey,
    $_SERVER['REMOTE_ADDR'],
    60,
    0
);

session_write_close();
header('Cache-Control: no-store, private');
header('Location: ' . $streamUrl, true, 302);
exit;
В HTML-плеере укажите свой адрес:
<audio controls preload="none">
    <source src="https://example.com/listen.php" type="audio/mpeg">
</audio>

Пробный доступ и duration

Пример ссылки, которая ограничивает одно подключение 30 секундами:
$duration = 30;
Duration ограничивает конкретное подключение, а не общий срок подписки пользователя.
Если требуется правило «первые 30 минут бесплатно», сохраните начало или окончание пробного периода в своей базе данных. При каждом обращении к listen.php передавайте только оставшееся время, а после окончания периода возвращайте HTTP 403.
Иначе пользователь сможет переподключиться и получить новый полный лимит.
Обратите внимание! Плеер может воспроизводить звук на несколько секунд дольше значения duration из-за уже загруженного стартового буфера. Размер задержки зависит от буфера и битрейта потока. Не используйте duration как точный посекундный расчёт оплаты.

IP-адрес, прокси и мобильные сети

В подпись нужно включать публичный IP, с которого слушатель подключится к MyRadio24.
Если сайт работает через Cloudflare, CDN, reverse proxy или балансировщик, настройте веб-сервер так, чтобы REMOTE_ADDR содержал реальный IP клиента.
Не доверяйте произвольному заголовку X-Forwarded-For: его можно подделать. Обрабатывайте его только для запросов от своего известного прокси.
При переключении между Wi-Fi и мобильной сетью IP может измениться. Старый ключ тогда перестанет работать, а listen.php должен выдать новую ссылку при следующем подключении.

Частые вопросы

Почему обычная ссылка перестала работать?
Это происходит после включения секретного ключа. Используйте подписанную ссылку с параметром key.
Почему новая ссылка сразу отклоняется?
Проверьте секретный ключ, IP слушателя, системное время сервера, порядок значений в MD5 и значение duration. Время сервера должно быть синхронизировано.
Почему ссылка работает на одном устройстве, но не работает на другом?
Она привязана к IP, для которого была создана.
Почему поток не возобновился после обрыва?
Expire прямой ссылки мог истечь. Используйте в плеере постоянный адрес listen.php, который создаёт новый ключ при каждом разрешённом подключении.
Почему отключение по duration произошло с небольшой задержкой?
Плеер доигрывает данные, которые успел получить в стартовый буфер. Это нормальная работа потокового воспроизведения.

Безопасность

1. Создавайте ссылки только на своём сервере.
2. Не размещайте секретный ключ в HTML, JavaScript, мобильном приложении или публичном репозитории.
3. Используйте HTTPS и запрещайте кеширование ответов listen.php.
4. Проверяйте право доступа при каждом новом подключении.
5. Не записывайте секрет и полные защищённые ссылки в открытые журналы.
6. При раскрытии секрета замените его в панели и на своём сервере.
7. Защищённая ссылка ограничивает доступ к потоку, но не является DRM и не запрещает авторизованному слушателю записать воспроизводимый звук.