Перейти к содержанию

Вставка одного потока в другой

Описание

Начиная со сборки 5.3.37 в версии 5.3 улучшена функция вставки медиа в опубликованный поток. Добавлено новое REST API для вставки в опубликованный поток медиа или статической картинки из файла. Прежнее API для вставки потоков доступно в версии 5.2

Поддерживаемые кодеки

Видео:

  • H264

Аудио:

  • AAC (аудио файла-источника)
  • Opus (аудио целевого потока)
  • G711 (аудио целевого потока)

Картинка:

  • JPEG
  • PNG

Ограничения и требования к файлам

  1. Вставка не применяется к потокам звонков. Для звонков используются собственные технологии вставки аудио и видео.

  2. Последовательная вставка не поддерживается. Вставка предыдущего файла должна быть остановлена до вставки следующего.

  3. Если аудио кодек файла отличается от аудио кодека потока, на сервере будет работать транскодинг аудио. Это приводит к росту нагрузки на CPU.

  4. Видео дорожка в файле должна быть закодирована без использования B-фреймов, поскольку их проигрывание по WebRTC не поддерживается в браузерах.

  5. При кодировании файла MP4 для размещения на внешнем HTTPS сервере или S3 совместимом хранилище атом MOOV должен быть помещен в заголовок файла. В противном случае, необходимо будет выставить настройку vod_mp4_container_new=false и ждать полного скачивания файла для вставки в поток.

REST API для вставки

REST-запрос должен быть HTTP/HTTPS POST запросом в таком виде:

  • HTTP: http://test.flashphoner.com:8081/rest-api/stream/inject3/startup
  • HTTPS: https://test.flashphoner.com:8444/rest-api/stream/inject3/startup

Здесь:

  • test.flashphoner.com - адрес WCS-сервера
  • 8081 - стандартный REST / HTTP порт WCS-сервера
  • 8444 - стандартный HTTPS порт
  • rest-api - обязательная часть URL
  • /stream/inject3/startup - используемый REST-метод

REST методы и ответы

/stream/inject3/startup

Вставить медиа дорожку или статическую картинку в поток

Request example
POST /rest-api/stream/inject3/startup HTTP/1.1
Host: localhost:8081
Content-Type: application/json

{
    "localStreamName": "test",
    "resources": [
        {
            "uri": "file:///opt/media/video.mp4",
            "media": "video"
        },
        {
            "uri": "file:///opt/media/audio.mp4",
            "media": "audio"
        }
    ],
    "audio": {
        "required": true,
        "wait": true,
        "stub": true
    },
    "video": {
        "required": true,
        "wait": true,
        "stub": true
    },
    "loop": true,
    "speed": 1,
    "duration": 20
}
Response example
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json
Return codes
Code Reason
200 OK
400 Bad request
404 Not found
409 Conflict
500 Internal error

/stream/inject3/find_all

Найти все активные вставки на сервере

Request example
POST /rest-api/stream/inject3/find_all HTTP/1.1
Host: localhost:8081
Content-Type: application/json
Response example
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json

[
    {
        "streamName": "test",
        "videoInjectorInfo": {
            "resource": {
                "uri": "file:///opt/media/video.mp4",
                "media": "video"
            },
            "startTime": 1749106490411
        },
        "audioInjectorInfo": {
            "resource": {
                "uri": "file:///opt/media/audio.mp4",
                "media": "audio"
            },
            "startTime": 1749106490410
        }
    }
]
Return codes
Code Reason
200 OK
404 Not found

stream/inject3/terminate

Остановить вставку в поток

Request example
POST /rest-api/stream/inject3/terminate HTTP/1.1
Host: localhost:8081
Content-Type: application/json

{
    "localStreamName": "test",
    "video": true,
    "audio": true
}
Response example
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json
Return codes
Code Reason
200 OK
400 Bad request
404 Not found
500 Internal error

Параметры

Parameter Description Example
localStreamName Имя потока, в который производится вставка test
resources Список медиа источников для вставки [{"uri": "file:///opt/media/video.mp4", "media": "video"}]
-- uri URI медиа источника file:///opt/media/video.mp4
-- media Тип медиа источника video
audio Условия для вставки аудио {"required": true, "wait": true, "stub": true}
video Условия для вставки видео {"required": true, "wait": true, "stub": true}
-- required Источник обязателен для вставки true
-- wait Ждать готовности другого источника (аудио ждет видео и наоборот) true
-- stub Отображать черный квадрат или тишину до готовности источника true
loop Зациклить вставку false
speed Скорость проигрывания вставляемого медия 1
duration Длительность вставки в секундах 20

Способы применения вставки

Вставка аудио и видео

Видео и аудио дорожки могут быть вставлены из одного и того же файла

POST /rest-api/stream/inject3/startup HTTP/1.1
Host: localhost:8081
Content-Type: application/json

{
    "localStreamName": "test",
    "resources": [
        {
            "uri": "file:///opt/media/video.mp4",
            "media": "audio, video"
        }
    ],
    "audio": {
        "required": true,
        "wait": true,
        "stub": true
    },
    "video": {
        "required": true,
        "wait": true,
        "stub": true
    }
}

или из двух различных источников

POST /rest-api/stream/inject3/startup HTTP/1.1
Host: localhost:8081
Content-Type: application/json

{
    "localStreamName": "test",
    "resources": [
        {
            "uri": "file:///opt/media/audio.mp4",
            "media": "audio"
        },
        {
            "uri": "file:///opt/media/video.mp4",
            "media": "video"
        }
    ],
    "audio": {
        "required": true,
        "wait": true,
        "stub": true
    },
    "video": {
        "required": true,
        "wait": true,
        "stub": true
    }
}

Если один из источников не готов к вставке (например, файл не полностью загружен) и параметр wait для другого источника установлен в true, вставка не начнется до готовности источника (полного скачивания файла и его разбора).

Если установлен параметр duration, вставка остановится по истечении заданного времени длительности. Если этот параметр не установлен, вставка остановится по окончании хотя бы одного из файлов. В любом случае, вставка остановится по запросу /stream/inject3/terminate

POST /rest-api/stream/inject3/terminate HTTP/1.1
Host: localhost:8081
Content-Type: application/json

{
    "localStreamName": "test"
}

Вставка только видео или только аудио

В поток может быть вставлено только видео или только аудио, в этом случае другая составляющая останется нетронутой и продолжит проигрываться.

В этом примере, вставляется только видео

POST /rest-api/stream/inject3/startup HTTP/1.1
Host: localhost:8081
Content-Type: application/json

{
    "localStreamName": "test",
    "resources": [
        {
            "uri": "file:///opt/media/video.mp4",
            "media": "video"
        }
    ],
    "audio": {
        "required": false,
        "wait": false,
        "stub": false
    },
    "video": {
        "required": true,
        "wait": false,
        "stub": false
    }
}

А в этом примере заменяется только аудио

POST /rest-api/stream/inject3/startup HTTP/1.1
Host: localhost:8081
Content-Type: application/json

{
    "localStreamName": "test",
    "resources": [
        {
            "uri": "file:///opt/media/audio.mp4",
            "media": "audio"
        }
    ],
    "audio": {
        "required": true,
        "wait": false,
        "stub": false
    },
    "video": {
        "required": false,
        "wait": false,
        "stub": false
    }
}

Вставка статической картинки

В поток может быть вставлена статическая картинка с аудио

POST /rest-api/stream/inject3/startup HTTP/1.1
Host: localhost:8081
Content-Type: application/json

{
    "localStreamName": "test",
    "resources": [
        {
            "uri": "file:///opt/media/audio.mp4",
            "media": "audio"
        },
        {
            "uri": "file:///opt/media/image.png",
            "media": "image"
        }
    ],
    "audio": {
        "required": true,
        "wait": true,
        "stub": true
    },
    "video": {
        "required": true,
        "wait": true,
        "stub": true
    },
    "loop": true,
    "duration": 10
}

Это полезно, например, в качестве заставки для зрителей, ожидающих начала трансляции.

Возможные варианты размещения файла для вставки

Файл для вставки может находиьться на том же сервере, локально

{
    "localStreamName": "test",
    "resources": [
        {
            "uri": "file:///opt/media/video.mp4",
            "media": "audio, video"
        },
        ...
    ],
    ...
}

Файл также может быть загружен по HTTP/HTTPS с внешнего сервера или из CDN

{
    "localStreamName": "test",
    "resources": [
        {
            "uri": "https://cdn/downloads/video.mp4",
            "media": "audio, video"
        },
        ...
    ],
    ...
}

либо из S3 совместимого хранилища

{
    "localStreamName": "test",
    "resources": [
        {
            "uri": "s3/bucket/video.mp4",
            "media": "audio, video"
        },
        ...
    ],
    ...
}

Для файлов, размещенных на внешних серверах, доступно кэширование (см настройку кэширования ниже)

Настройка WCS

Новая реализация транскодинга должна быть отключена

transcoding_gen3=false

Чтобы при остановке инжекта у зрителей быстрее отображался оригинальный поток, рекомендуется быть включены периодические запросы ключевых кадров при публикации WebRTC из браузера

periodic_fir_request=true

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

vod_mp4_container_new=true

Настройка доступа к S3 хранилищу

Если файлы для вставки размещаются в S3 совместимом хранилище, к нему должны быть настроены доступы в зависимости от используемого провайдера.

AWS

Параметры для доступа к AWS S3 должны быть указаны в файле flashphoner.properties следующим образом

aws_s3_credentials=zone;login;hash

Здесь

  • zone - AWS регион, где располагается хранилище
  • login - Access Key ID
  • hash - Secret Accesss Key

Пример настройки доступов к AWS S3:

aws_s3_credentials=eu-central-1;AA22BB33CC44DE;DhlAkpZ4adclHhbLwhTNL4hvWTo80Njo

Digital Ocean Spaces

Параметры для доступа к DO Spaces должны быть указаны следующим образом

aws_s3_credentials=ams3;access_key;secret

Здесь

  • ams3 - поддомен digitaloceanspaces.com (Амстердам в данном примере)
  • access_key - storage access key
  • secret - storage access secret code

Selectel

параметры для доступа к Selectel S3 должны быть указаны следующим образом

aws_s3_credentials=ru-1a;login;password

Здесь

  • ru-1a - регион, гда располагается хранилище
  • login - имя пользователя
  • password - пароль

Настройка кэширования файлов

Начиная со сборки 5.3.38 файлы с внешних хранилищ могут кэшироваться для снижения входящего на сервер трафика и времени ожидания

http_client_cache_enabled=true
http_client_cache_path=.cache-http
http_client_max_cache_size=1g

В этом случае, файловый кэш будет размещен в каталоге /usr/local/FlashphonerWebCallServer/.cache-http (если такого каталога нет, WCS попытается его создать). Если суммарный размер всех загруженных файлов превысит 1 Гб (в данном примере), наиболее старые файлы будут удалены для освобождения места. Размер проверяется после завершения скачивания файла, поэтому в моменте каталог кэша может занимать на диске больше места, чем заданный максимальный размер.

Каталог для кэша должен быть доступен для записи пользователю flashphoner

drwxrwxr-x  2 flashphoner flashphoner 4096 Jun 19 00:28 .cache-http

Сожержимое заголовка Cache-Control может быть указано явно при помощи параметра

http_client_cache_control=max-age=0

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

OSZAR »