В каких случаях включается транскодинг

Транскодинг видеопотока включается автоматически в одном из следующих случаев:

1. Кодеки стримера и плеера не совпадают по имени.
Например, стример отправляет H.264, плеер пытается играть VP8.

2. Кодеки H.264 отличаются по параметру packetization-mode
Например стример отправляет packetization-mode=1 (по умолчанию), а плеер явно указывает packetization-mode=0. Ситуация достаточно редкая, т.к. почти все устройства поддерживают packetization-mode=1

3. Явно указано разрешение плеера.
Пример:

session.createStream({name:"stream1", constraints:{audio:true, video:{width:640,height:480}}}).play();

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

4. Явно указан битрейт плеера.

Пример

session.createStream({name:"stream1", constraints:{audio:true, video:{bitrate:300}}}).play();

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

Кроме того, транскодинг может быть принудительно включен на сервере при помощи параметра в файле flashphoner.properties

disable_streaming_proxy=true

Транскодинг значительно увеличивает потребление ресурсов сервера (процессорных ядер). Поэтому включать его следует с осторожностью!

Принудительное отключение транскодинга

Транскодинг может быть полностью отключен на сервере при помощи параметра в файле flashphoner.properties

transcoding_disabled=true

Если транскодинг принудительно отключен, во всех четырех случаях, перечисленных выше, клиенту возвращается ошибка TRANSCODING_REQUIRED_BUT_DISABLED.

Отключение транскодинга не влияет на микшер, при использовании микшера транскодинг будет включаться.

Управление транскодингом при помощи REST API

Устаревшая версия REST API (сборки сервера до 5.2.898)

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

Здесь:

REST-методы и статусы ответа

REST-метод

Пример тела REST-запроса

Пример тела REST-ответа

Статусы ответа

Описание

/transcoder/startup

{
 "uri": "transcoder://tcode1",
 "remoteStreamName": "test",
 "localStreamName": "testT",
 "encoder": {
  "width": 640,
  "height": 480,
  "keyFrameInterval": 30,
  "fps": 30,
  "watermark": "Test.png"
 }
}

400 - Bad request

409 - Conflict

500 - Internal error


Создать транскодер с указанными параметрами для заданного потока


/transcoder/find
{
 "remoteStreamName": "test"
}
[
    {
        "localMediaSessionId": "42a92132-bcd1-4436-a96f-3fec36b32b37",
        "localStreamName": "testT",
        "remoteStreamName": "test",
        "uri": "transcoder://tcode1",
        "status": "PROCESSED_LOCAL",
        "hasAudio": true,
        "hasVideo": true,
        "record": false,
        "encoder": {
            "width": 640,
            "height": 480,
            "keyFrameInterval": 30,
            "fps": 30,
            "watermark": "Test.png"
        }
    }
]

200 – транскодеры найдены

404 – транскодеры не найдены

Найти транскодер по указанным критериям

/transcoder/find_all


[
    {
        "localMediaSessionId": "42a92132-bcd1-4436-a96f-3fec36b32b37",
        "localStreamName": "testT",
        "remoteStreamName": "test",
        "uri": "transcoder://tcode1",
        "status": "PROCESSED_LOCAL",
        "hasAudio": true,
        "hasVideo": true,
        "record": false,
        "encoder": {
            "width": 640,
            "height": 480,
            "keyFrameInterval": 30,
            "fps": 30
        }
    }
]

200 – транскодеры найдены

404 – транскодеры не найдены

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

/transcoder/terminate

{
"uri":"transcoder://tcode1"
}

200 - транскодер завершен

404 - транскодер не найден

Остановить транскодер и его выходной поток

Параметры

Имя параметра

Описание

Пример

uri

URL транскодера

transcoder://tcode1
localStreamNameИмя выходного потока транскодера
testT
remoteStreamNameИмя транскодируемого потока
test
localMediaSessionIdИдентификатор медиасессии транскодера
42a92132-bcd1-4436-a96f-3fec36b32b37

status

Текущий статус транскодера

PROCESSED_LOCAL
hasAudioВыходной поток содержит аудио
true
hasVideoВыходной поток содержит видео
true
recordВыходной поток записывается
false
Параметры кодирования
widthШирина картинки
640
heightВысота картинки (обязательный параметр)
480
keyFrameIntervalЧастота генерации ключевых кадров (GOP)
30
fpsЧастота кадров в секунду
30
bitrateБитрейт в кб/с
500
typeКодек
OPENH264
watermarkФайл водяного знакаTest.png

Ограничения

1. Для потоков без видео (только с аудио составляющей) создание транскодера при помощи REST API невозможно. Если отправить запрос /transcoder/startup для такого потока, сервер вернет 400 Bad request с сообщением "Can't start transcoder for audio only stream"

2. Если при создании транскодера по REST API не указать ни ширину, ни высоту, транскодинг не включится, поток будет скопирован без перекодирования.

3. Если указана только высота картинки, поток будет транскодирован с сохранением соотношения сторон, если эта возможность включена.

4, Если указана только ширина картинки, запрос вернет 400 Bad request с сообщением "Height is not specified"

Версия 2 REST API (сборки сервера, начиная с 5.2.898)

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

Здесь:

REST-методы и статусы ответа

REST-метод

Пример тела REST-запроса

Пример тела REST-ответа

Статусы ответа

Описание

/transcoder2/startup

{
 "uri": "transcoder2://tcode2",
 "remoteStreamName": "test",
 "localStreamName": "testT",
 "encoder": {
  "videoCodec": "H264",
  "audioCodec": "mpeg4-generic",
  "width": 320,
  "height": 240,
  "keyFrameInterval": 60,
  "fps": 30,
  "audioRate": 44100,
  "audioBitrate": 64000
 }
}

200 - OK

400 - Bad request

409 - Conflict

500 - Internal error


Создать транскодер с указанными параметрами для заданного потока


/transcoder2/find
{
 "remoteStreamName": "test"
}
[
  {
    "localMediaSessionId": "82ad5545-e11e-4f0f-801a-49e69d8c38f2",
    "localStreamName": "testT",
    "remoteStreamName": "test",
    "uri": "transcoder2://tcode2",
    "status": "PROCESSED_LOCAL",
    "hasAudio": true,
    "hasVideo": true,
    "record": false,
    "encoder": {
      "width": 320,
      "height": 240,
      "keyFrameInterval": 60,
      "fps": 30,
      "audioRate": 44100,
      "audioCodec": "mpeg4-generic",
      "videoCodec": "H264",
      "videoRate": 90000
    }
  }
]

200 – OK

404 – Not found

Найти транскодер по указанным критериям

/transcoder/find_all


[
  {
    "localMediaSessionId": "82ad5545-e11e-4f0f-801a-49e69d8c38f2",
    "localStreamName": "testT",
    "remoteStreamName": "test",
    "uri": "transcoder2://tcode2",
    "status": "PROCESSED_LOCAL",
    "hasAudio": true,
    "hasVideo": true,
    "record": false,
    "encoder": {
      "width": 320,
      "height": 240,
      "keyFrameInterval": 60,
      "fps": 30,
      "audioRate": 44100,
      "audioCodec": "mpeg4-generic",
      "videoCodec": "H264",
      "videoRate": 90000
    }
  }
]

200 – OK

404 – Not found

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

/transcoder/terminate

{
 "uri":"transcoder2://tcode2"
}

200 – OK

404 – Not found

Остановить транскодер и его выходной поток

Параметры

Имя параметра

Описание

Пример

uri

URL транскодера

transcoder2://tcode2
localStreamNameИмя выходного потока транскодера
testT
remoteStreamNameИмя транскодируемого потока
test
localMediaSessionIdИдентификатор медиасессии транскодера
82ad5545-e11e-4f0f-801a-49e69d8c38f2

status

Текущий статус транскодера

PROCESSED_LOCAL
hasAudioВыходной поток содержит аудио
true
hasVideoВыходной поток содержит видео
true
recordВыходной поток записывается
false
Параметры кодирования
widthШирина картинки
320
heightВысота картинки (обязательный параметр)
240
audioCodecКодек аудиоmpeg4-generic
audioRateЧастота дискретизации аудио, Гц 44100
audioChannelsКоличество каналов аудио2
audioBitrateБитрейт аудио, бит/с64000
videoCodecКодек видеоH264
keyFrameIntervalЧастота генерации ключевых кадров (GOP)
30
fpsЧастота кадров в секунду
30
bitrateБитрейт видео в кб/с
500
typeКодировщик
OPENH264
watermarkФайл водяного знакаTest.png
videoRateЧастота дискретизации видео, Гц90000

Ограничения

1. Если параметры транскодирования видео переданы для потока без видео, либо параметры транскодирования аудио переданы для потока без аудио, запрос вернет 400 Bad request

Краткое руководство по тестированию

1. Для тестирования используем

2. Откройте приложение Two Way Streaming, опубликуйте поток test

3. Откройте REST-клиент, отправьте запрос /transcoder/startup

4. Откройте веб-приложение Player, укажите в поле Stream имя потока testT и нажмите Start

5. Откройте REST-клиент, отправьте запрос /transcoder/terminate

6. Воспроизведение потока останавливается в связи с остановкой транскодера

Сохранение соотношения сторон видео при транскодинге

По умолчанию, если поток опубликован с одними размерами кадра, а запрашивается для воспроизведения с другими размерами, WCS пытается сохранить соотношение сторон видео. Например, если на сервере опубликован поток разрешением 640x360 и соотношением сторон 16:9, а подписчик запрашивает воспроизведение 320x240 (4:3), поток будет транскодирован к разрешению 320x180 (16:9). Если подписчик запрашивает только высоту картинки, не указывая ширину, соотношение сторон также будет сохранено.

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

video_transcoder_preserve_aspect_ratio=false

При этом поток будет транскодирован к тем ширине и высоте кадра, которые запрашивает подписчик. Если высота не указана подписчиком, будет установлена высота картинки 120. Если ширина не указана подписчиком, будет установлена ширина картинки 160.

Синхронизация аудио и видео на выходе транскодера

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

av_paced_sender=true

Размер выравнивающего буфера задается в кадрах настройкой

av_paced_sender_max_buffer_size=5000

По умолчанию размер буфера составляет 5000 кадров

Для контроля работы выравнивающего буфера используется статистика, получаемая при помощи запроса

curl -s 'http://localhost:8081/?action=stat&format=json&groups=buffer_stats'

Добавление водяного знака в определенный поток

В сборке 5.2.693 появилась возможность добавлять в выходной поток транскодера водяной знак при создании транскодера по REST API, например

{
 "uri": "transcoder://tcode1",
 "remoteStreamName": "test",
 "localStreamName": "testT",
 "encoder": {
  "width": 640,
  "height": 480,
  "keyFrameInterval": 30,
  "fps": 30,
  "watermark": "Test.png"
 }
}

Если имя файла указано без пути, файл должен располагаться в каталоге /usr/local/FlashphonerWebCallServer/conf. Можно также указать полный путь к файлу, например

{
 "uri": "transcoder://tcode1",
 "remoteStreamName": "test",
 "localStreamName": "testT",
 "encoder": {
  "width": 640,
  "height": 480,
  "keyFrameInterval": 30,
  "fps": 30,
  "watermark": "/opt/media/Test.png"
 }
}

Многопоточное кодирование

В сборке 5.2.816 добавлена возможность многопоточного кодирования при использовании кодировщика на базе OpenH264. Количество потоков кодирования устанавливается следующей настройкой

video_encoder_max_threads=2

По умолчанию, количество потоков установлено в 2.

Многопоточное кодирование включается в зависимости от разрешения выходного потока транскодера. Граница устанавливается при помощи следующей настройки

video_encoder_second_thread_threshold=777000

Значение представляет собой произведение ширины картинки на высоту. Таким образом, по умолчанию в несколько потоков кодируются картинки разрешением 720p. При необходимости, этот порог можно понизить. Например, для того, чтобы кодировать в несколько потоков картинки 480p, установите значение

video_encoder_second_thread_threshold=408950