Skip to content

Интеграция через API

Внешняя система может создавать стримы и каналы, назначать подписки и получать адреса для приложения зрителя. Ниже — два последовательных примера: от создания стрима до ссылки воспроизведения для подписчика.

Где открыть справочник

Справочник встроен в установленную Catena. Откройте его из консоли или подставьте адрес своей установки вместо https://catena.example.com:

  • Central API — https://catena.example.com/central/api-v4/docs/: настройки стримов и управление кластером.
  • Catena API — https://catena.example.com/catena/api-v1/docs/: каналы, пакеты и подписчики.
  • Catena TV API — https://catena.example.com/catena/api-v1/docs/tv/: вход зрителя и доступные ему каналы.
  • Playback API — https://catena.example.com/central/api-v4/docs/playback/: воспроизведение медиа.

На каждой странице есть поиск и Download OpenAPI JSON. Схема относится к установленной сборке. Страницы справочника открываются без авторизации, если соответствующий API-префикс опубликован; сами управляющие запросы требуют авторизации.

Сущности и авторизация

  • Стрим хранит настройки вещания. Канал хранит название и номер для витрины, ссылается на стрим через stream_name и входит в пакеты.
  • Учётная запись оператора используется для запросов к Central и Catena API. В примерах применяется HTTP Basic; передавайте пароль по HTTPS.
  • Токен устройства возвращается при входе подписчика в TV API и передаётся в следующих запросах как Authorization: Bearer …. У подписчика также есть отдельный playback_token, который TV API принимает для идентификации абонента.
  • Билет воспроизведения уже включён в playback_url, полученный от TV API. Токен устройства и операторский пароль передавать плееру не требуется.

Перед началом

Перед началом подготовьте:

  • Bash — для выполнения примеров в одной сессии.
  • curl — для HTTP-запросов.
  • jq — для формирования и чтения JSON.
  • Учётную запись оператора с правом изменения настроек.

Запускайте оба примера в одной сессии Bash: второй использует переменные первого. Команды создают тестовые записи в вашей установке; используйте тестовую среду. Пароли вводятся скрыто и не записываются в команды.

Создать стрим и канал

Замените BASE и API_USER своими значениями. Пример создаёт выключенный стрим без источника (enabled: false), чтобы проверить работу с API без запуска вещания. If-None-Match: * запрещает перезаписать существующий стрим при совпадении имени.

set -euo pipefail

BASE='https://catena.example.com'
API_USER='admin'
read -r -s -p 'Operator password: ' API_PASSWORD
printf '\n'

BASE="${BASE%/}"
STREAM="api-example-$(date +%s)"

curl -fsS -u "$API_USER:$API_PASSWORD" \
  -X PUT "$BASE/central/api-v4/streams/configs/$STREAM" \
  -H 'Content-Type: application/json' \
  -H 'If-None-Match: *' \
  -d '{"title":"Integration example","enabled":false}'

CHANNEL=$(
  jq -n --arg stream "$STREAM" \
    '{title:"Example channel",number:1,stream_name:$stream}' |
  curl -fsS -u "$API_USER:$API_PASSWORD" \
    -X POST "$BASE/catena/api-v1/channels" \
    -H 'Content-Type: application/json' --data-binary @-
)
CHANNEL_ID=$(printf '%s' "$CHANNEL" | jq -er '.id')

CHANNEL=$(
  curl -fsS -u "$API_USER:$API_PASSWORD" \
    "$BASE/catena/api-v1/channels/$CHANNEL_ID"
)
VERSION=$(printf '%s' "$CHANNEL" | jq -er '.version')

curl -fsS -u "$API_USER:$API_PASSWORD" \
  -X PATCH "$BASE/catena/api-v1/channels/$CHANNEL_ID" \
  -H 'Content-Type: application/json' \
  -H "If-Match: \"$VERSION\"" \
  -d '{"title":"Updated example channel"}' | jq .

Ответ создания канала содержит его id. Перед изменением перечитываем канал и берём version: для этого ресурса значение ETag — эта версия в кавычках. PATCH передаёт только новое название; привязка к стриму сохраняется.

Назначить подписку и получить ссылку

Продолжайте в той же сессии. Введите пароль тестового подписчика длиной не менее восьми символов. Создаём пакет с обязательной подпиской (free: false), включаем канал в пакет и подписываем на него абонента. Затем входим от имени зрителя. Имя пакета должно содержать от 2 до 20 символов: латинские буквы, цифры, дефис или подчёркивание.

read -r -s -p 'Subscriber password: ' SUB_PASSWORD
printf '\n'

LOGIN="api-$(date +%s)"

PACKAGE=$(
  jq -n --arg name "$LOGIN" '{name:$name,free:false}' |
  curl -fsS -u "$API_USER:$API_PASSWORD" \
    -X POST "$BASE/catena/api-v1/packages" \
    -H 'Content-Type: application/json' --data-binary @-
)
PACKAGE_ID=$(printf '%s' "$PACKAGE" | jq -er '.id')

jq -n --arg p "$PACKAGE_ID" --arg c "$CHANNEL_ID" \
  '{package_id:$p,channel_id:$c}' |
curl -fsS -u "$API_USER:$API_PASSWORD" \
  -X POST "$BASE/catena/api-v1/package-channels" \
  -H 'Content-Type: application/json' --data-binary @-

SUBSCRIBER=$(
  curl -fsS -u "$API_USER:$API_PASSWORD" \
    -X POST "$BASE/catena/api-v1/subscribers" \
    -H 'Content-Type: application/json' \
    -d '{"name":"Integration example"}'
)
SUBSCRIBER_ID=$(printf '%s' "$SUBSCRIBER" | jq -er '.id')

jq -n --arg login "$LOGIN" --arg password "$SUB_PASSWORD" \
  '{login:$login,password:$password}' |
curl -fsS -u "$API_USER:$API_PASSWORD" \
  -X PATCH "$BASE/catena/api-v1/subscribers/$SUBSCRIBER_ID/credentials" \
  -H 'Content-Type: application/json' --data-binary @- >/dev/null

jq -n --arg s "$SUBSCRIBER_ID" --arg p "$PACKAGE_ID" \
  '{subscriber_id:$s,package_id:$p}' |
curl -fsS -u "$API_USER:$API_PASSWORD" \
  -X POST "$BASE/catena/api-v1/subscriptions" \
  -H 'Content-Type: application/json' --data-binary @-

SESSION=$(
  jq -n --arg login "$LOGIN" --arg password "$SUB_PASSWORD" \
    '{login:$login,password:$password,device_name:"Example app"}' |
  curl -fsS -X POST "$BASE/playback/tv/login" \
    -H 'Content-Type: application/json' --data-binary @-
)
DEVICE_TOKEN=$(printf '%s' "$SESSION" | jq -er '.token')

curl -fsS "$BASE/playback/tv/channels" \
  -H "Authorization: Bearer $DEVICE_TOKEN" |
jq --arg id "$CHANNEL_ID" \
  '.channels[] | select(.id == $id) | {title,playback_url}'

Последний запрос выводит название канала и playback_url — путь от корня установки с уже включённым билетом. Для абсолютного адреса добавьте к нему BASE. Повторный запрос /playback/tv/channels получает актуальный билет. Ручка GET /playback/tv/channels/{channel_id}/play с авторизацией зрителя отвечает 307 и заголовком Location со ссылкой воспроизведения.

Условия воспроизведения

Получение ссылки подтверждает, что канал доступен подписчику. Для просмотра настройте источник стрима, включите его и проверьте размещение на стримере. Приведённый пример оставляет стрим выключенным. Параметры допуска к видео описаны в защите воспроизведения и билетах Catena.

Обработка ошибок

  • 401 — проверьте учётные данные оператора или токен зрителя. Управляющий API и TV API используют разные учётные данные.
  • 412 — запись уже изменилась. Перечитайте её и проверьте актуальные значения перед повторной отправкой PATCH с новой версией.
  • 422 — проверьте error.errors: каждый элемент содержит path к неверному полю и message. Например, строка вместо числа в number возвращает путь ["number"].

Канал появляется у подписчика, если входит в пакет из его подписок или в бесплатный пакет. В приведённом примере до назначения подписки канал отсутствует в списке. Подробнее — в правилах доступа подписчика.

Удалить тестовые записи

После проверки выполните команды в той же сессии. Они удаляют созданные примерами записи; подписки и связи пакета с каналом снимаются каскадом.

curl -fsS -u "$API_USER:$API_PASSWORD" \
  -X DELETE "$BASE/catena/api-v1/subscribers/$SUBSCRIBER_ID"
curl -fsS -u "$API_USER:$API_PASSWORD" \
  -X DELETE "$BASE/catena/api-v1/packages/$PACKAGE_ID"
curl -fsS -u "$API_USER:$API_PASSWORD" \
  -X DELETE "$BASE/catena/api-v1/channels/$CHANNEL_ID"
curl -fsS -u "$API_USER:$API_PASSWORD" \
  -X DELETE "$BASE/central/api-v4/streams/configs/$STREAM"