<!-- Canonical: https://docs.shopstory.live/docs/guide/mini-player -->

# Mini-player API

API возвращает состояние контента для собственного интерфейса. Для готового виджета используйте [mini-player Web SDK](<https://docs.shopstory.live/docs/guide/web-mini-player>); для нативного приложения — [Mobile SDK](<https://docs.shopstory.live/docs/guide/mobile-sdk>).

[Схема режимов Web PiP](<https://docs.shopstory.live/docs/guide/web-mini-player#web-pip-modes-caption>) показывает превью записи, live, Continuous Video и постер в готовом виджете. Их отображением управляет Web SDK.

Запрос stock-check к API магазина выполняет код клиента; mini-player API этого не делает.

## Состояние по товару

```http
GET https://app.shopstory.live/v2/mini-player/stream-state?application=<application-id>&feedProductId=<feed-product-id>
Accept: application/json
```

| Параметр | Обязательно | Описание |
| --- | --- | --- |
| `application` | Да | Выданный ShopStory идентификатор приложения. Он не является секретом или способом авторизации. |
| `feedProductId` | Да для новых интеграций | Канонический строковый идентификатор товара из согласованного фида. |
| `productCode` | Только по legacy-контракту | Строковый артикул продавца для ранее согласованных интеграций с поиском по `vendorCode`. |
| `feedProductGroupId` | Только по legacy-контракту | Дополнительная группа товара. Используется только вместе с `productCode`, если такой маппинг уже согласован. |

В новой интеграции используйте один `feedProductId` во всех поверхностях. Не чередуйте его с `productCode` и не передавайте оба параметра одновременно. Идентификаторы должны оставаться строками, включая ведущие нули.

### Найден live или VOD

```json
{
  "serverTime": "2025-01-15T10:00:00.000Z",
  "status": 200,
  "body": {
    "status": "active",
    "stream": {
      "streamId": "stream-123",
      "streamStatus": "completed",
      "productId": "product-456",
      "feedProductId": "0001001",
      "playbackLink": "https://media.example.net/stream.m3u8",
      "previewUrl": "https://media.example.net/preview.webm",
      "posterUrl": "https://media.example.net/poster.jpg",
      "startTime": 120,
      "mediaOrientation": "portrait",
      "playerUrl": "https://app.shopstory.live/sdk/"
    }
  }
}
```

| Поле `body.stream` | Обязательно | Описание |
| --- | --- | --- |
| `streamId` | Да | Строковый идентификатор эфира. |
| `streamStatus` | Да | `online` или `completed`. |
| `productId` | Да | Внутренний идентификатор товара ShopStory. |
| `feedProductId` | Нет | Идентификатор из фида. Может отсутствовать у ранее загруженных товаров или при поиске по `productCode`. |
| `playerUrl` | Да | Готовый HTTPS URL WebView-плеера. Считайте его непрозрачным и передавайте без изменения. |
| `mediaOrientation` | Да | `portrait`, `landscape`, `square` или `unknown`. |
| `playbackLink` | Да | Совместимое поле медиапотока. Не определяйте по нему видеопровайдера и не собирайте из него `playerUrl`. |
| `previewUrl`, `posterUrl` | Нет | Готовые HTTPS URL превью и статического постера. Превью может быть видео или анимированным изображением в зависимости от профиля. Используйте URL без изменения; не подменяйте расширение файла. |
| `startTime` | Нет | Неотрицательное смещение релевантного эпизода VOD в секундах. |

В ручной web-интеграции открывайте `playerUrl` без изменения. В нативном приложении [Mobile SDK](<https://docs.shopstory.live/docs/guide/mobile-sdk>) выполняет lookup и возвращает типизированный entrypoint, а приложение отдельно передаёт его в SDK coordinator для открытия плеера. Не конструируйте URL плеера из `streamId`, `playbackLink` или других полей. Ответ может содержать дополнительные диагностические поля. Игнорируйте неизвестные поля и не используйте их для бизнес-логики.

### Связанного эфира нет

Когда связанный live или VOD не найден, API возвращает HTTP `200` с `no_active_stream`:

```json
{
  "serverTime": "2025-01-15T10:00:00.000Z",
  "status": 200,
  "body": {
    "status": "no_active_stream",
    "stream": null
  }
}
```

Это штатное отсутствие готового контента: с товаром может не быть связанного эфира либо его запись ещё не готова к показу. В Web SDK товарный PiP в этом состоянии не загружает превью или HLS. В ручной интеграции также скрывайте точку входа и не запрашивайте медиа.

Сейчас API возвращает `no_active_stream`. Неизвестное значение `status` обрабатывайте как отсутствие контента: скрывайте точку входа и не открывайте `stream`.

### Ошибки запроса

Этот эндпоинт выставляет HTTP-код ошибки и повторяет его в JSON-конверте:

```json
{
  "serverTime": "2025-01-15T10:00:00.000Z",
  "status": 400,
  "body": {
    "error": "invalid",
    "message": "Bad request: either 'productCode' or 'feedProductId' must be provided"
  }
}
```

- HTTP `400` — отсутствует `application` либо оба идентификатора товара.
- HTTP `500` — серверная часть не смогла сформировать воспроизводимый источник.

Скрывайте контейнер при `no_active_stream`, транспортной ошибке, невалидном ответе или если `playerUrl` отсутствует либо не является HTTPS URL.

## Текущий live

```http
GET https://app.shopstory.live/v2/mini-player/online?application=<application-id>
Accept: application/json
```

При наличии эфира `body.online` содержит `streamId`, `streamStatus: "online"` и `playbackLink`. Игнорируйте неизвестные дополнительные поля.

Если live сейчас нет, эндпоинт возвращает успешный ответ с пустым объектом `body`:

```json
{
  "serverTime": "2025-01-15T10:00:00.000Z",
  "status": 200,
  "body": {}
}
```

Отсутствующий `application` возвращает HTTP `400` и такой же `status` в конверте.

## Краткое состояние эфира

```http
GET https://app.shopstory.live/v3/translation/quick-state?translationId=<stream-id>
Accept: application/json
```

```json
{
  "status": 200,
  "serverTime": "2025-01-15T10:00:00.000Z",
  "body": {
    "translationState": "completed",
    "translationId": "stream-123",
    "expires": "2025-01-15T10:01:00.000Z"
  }
}
```

`translationState` принимает `draft`, `confirmed`, `online`, `completed` или пустую строку, если состояние неизвестно. Отсутствующий `translationId` возвращается как HTTP `200` с `status: 400` внутри конверта.

Если вызываете эндпоинт периодически, обрабатывайте HTTP `429` и `5xx` с увеличивающейся задержкой и случайным разбросом. Не используйте его для проверки товарного остатка.

## Мобильные приложения

В нативном приложении lookup и открытие выполняются через [Mobile SDK](<https://docs.shopstory.live/docs/guide/mobile-sdk>). Lookup возвращает `active`, `unavailable` или техническую ошибку. Для `active` приложение передаёт entrypoint в SDK coordinator, после чего host app открывает плеер.

WebView bridge из web-примеров в mobile contract не входит. Открывайте плеер через SDK coordinator. Маршрутизация товара и добавление в корзину остаются в приложении продавца. Оно получает текущий остаток, цену, авторизацию и результат операции из своих commerce-систем. Точная версия пакета и host contract передаются в integration handoff.

## Диагностика

| Наблюдение | Значение | Проверка |
| --- | --- | --- |
| `body.status: "no_active_stream"` | Для идентификатора нет готового live/VOD. | Сверьте `feedProductId` или согласованный `productCode` с фидом и привязкой эфира. |
| `body.status: "active"`, виджета на странице нет | Серверная часть нашла эфир, но web-компонент не отрисован. | Проверьте домен, CSP и настройку шаблона карточки товара. |
| Вместо движущегося превью виден постер | Браузер не поддерживает кодек либо медиа не загрузилось. | Проверьте поддержку VP9, запрос к `previewUrl` и ошибки media/CSP в браузере. |
| Во время эфира в PiP нет live | Режим Live в PiP не включён в конфигурации проекта либо эфир не связан с товаром. | Проверьте `streamStatus: "online"` в ответе `stream-state` и согласуйте включение режима с ShopStory. |
| После перехода из плеера началось короткое превью | Условия Continuous Video не выполнены. | Проверьте включение режима, общий origin, ту же вкладку, доступность `sessionStorage` и совпадение товара/эфира. |
| Continuous Video воспроизводится без звука | Браузер мог отклонить autoplay со звуком. | Включите звук кнопкой PiP; проверьте сценарий на целевых устройствах. |
| `body.online` отсутствует | Текущего live нет. | Проверяйте VOD через `stream-state` для известного товара. |
| `translationState: "completed"` | Эфир завершён. | Используйте `playerUrl` из `stream-state` для связанного товара. |

## Связанные разделы

- [Web SDK](<https://docs.shopstory.live/docs/guide/web-sdk>)
- [Mobile SDK](<https://docs.shopstory.live/docs/guide/mobile-sdk>)
- [Требования к товарному фиду](<https://docs.shopstory.live/docs/guide/feed-requirements>)
- [Добавление товара в корзину](<https://docs.shopstory.live/docs/guide/add-to-cart>)
- [OpenAPI и Postman](<https://docs.shopstory.live/docs/reference/openapi>)
