...
REST-метод | Пример тела REST-запроса | Пример ответа | Статусы ответа | Описание | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|
/mixer/startup |
| 200 - OK 400 - Bad request 409 - Conflict 500 - Internal error | Создает микшер, для которого публикуется поток с указанным именем | ||||||||
/mixer/add |
| 200 - OK 404 - Mixer not found 404 - Stream not found 500 - Internal error | Добавить RTMP-поток в микшер | ||||||||
/mixer/remove |
| 200 - OK 404 - Mixer not found 404 - Stream not found 500 - Internal error | Убрать RTMP-поток из микшера | ||||||||
/mixer/find_all |
| 200 - OK 404 - Not found 500 - Internal error | Найти все микшеры | ||||||||
/mixer/terminate |
| 200 - OK 404 - Not found 500 - Internal error | Завершить работу микшера | ||||||||
/stream/startRecording |
| 200 - OK 404 - Not found 500 - Internal error | Начать запись потока в указанной медиасессии | ||||||||
/stream/stopRecording |
| 200 - OK 404 - Not found 500 - Internal error | Завершить запись потока в указанной медиасессии | ||||||||
/mixer/setAudioVideo |
| 200 - OK 400 - Bad request 404 - Not found 500 - Internal error | Заглушить/возобновить видео или изменить уровень громкости аудио входного потока микшера | ||||||||
/mixer/set_body_watermark |
| 200 - OK 400 - Bad request 404 - Not found | Добавить водяной знак к картинке выходного потоку микшера | ||||||||
/mixer/set_stream_watermark |
| 200 - OK 400 - Bad request 404 - Not found | Добавить водяной знак к картинке одного из входящих потоков микшера |
Параметры
...
Имя параметра
...
Описание
...
Пример
...
uri
...
Уникальный идентификатор микшера
...
...
localStreamName
...
Имя выходного потока микшера
...
stream3
...
remoteStreamName
...
Имя потока, добавляемого в микшер
...
stream1
rtmp://rtmp.flashphoner.com:1935/live/rtmp_stream1
...
mediaSessionId
...
Идентификатор медиасессии
...
ce92b134-2468-4460-8d06-1ea3c5aabace
...
status
...
Статус потока
...
PROCESSED_LOCAL
...
^stream.*
["stream1", "stream2"]
...
Настройка микшера при создании по REST API
...
/mixer/set_stream_label |
| 200 - OK 404 - Not found | Установить или изменить отображаемое имя участника в микшере | ||||||||
/mixer/set_parameter |
| 200 - OK 400 - Bad request 404 - Not found | Изменить параметр микшера | ||||||||
/mixer/set_stream_avatar |
| 200 - OK 400 - Bad request 404 - Not found 500 - Internal server error | Установить картинку аватара на аудио поток в микшере | ||||||||
/mixer/remove_stream_avatar |
| 200 - OK 404 - Not found 500 - Internal server error | Убрать картинку аватара с аудио потока в микшере | ||||||||
/mixer/set_position |
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
создаст микшер с выходным потоком 640x360, fps 24 и битрейтом 500 кбит/с, независимо от того, какие настройки указаны в файле flashphoner.properties.
Полный список параметров микшера можно получить в ответе на запрос /mixer/find_all, например
...
language | js |
---|---|
theme | RDark |
title | Mixer parameters full list |
collapse | true |
...
| 200 - OK 404 - Not found 500 - Internal server error | Переместить картинку потока в указанную позицию (только для собственных вариантов размещения картинок) |
Параметры
Имя параметра | Описание | Пример |
---|---|---|
uri | Уникальный идентификатор микшера | mixer://mixer1 |
localStreamName | Имя выходного потока микшера | stream3 |
hasVideo | Микшировать видео | true |
hasAudio | Микшировать аудио | true |
remoteStreamName | Имя потока, добавляемого в микшер | stream1 rtmp://rtmp.flashphoner.com:1935/live/rtmp_stream1 |
mediaSessionId | Идентификатор медиасессии | ce92b134-2468-4460-8d06-1ea3c5aabace |
status | Статус потока | PROCESSED_LOCAL |
background | Фоновое изображение | background.png |
watermark | Водяной знак | watermark.png |
mixerLayoutClass | Класс размещения картинок в потоке | com.flashphoner.mixerlayout.TestLayout |
streams | Список потоков или регулярное выражение для поиска | ^stream.* ["stream1", "stream2"] |
audioLevel | Уровень громкости аудио для входного потока | 0 |
videoMuted | Заглушить видео | true |
streamLabel | Отображаемое имя участника в микшере | John Doe |
avatar | URI картинки в форматах PNG, JPG, BMP | https://mystorage.com/storage/avatar.jpg |
videoPositionId | Идентификатор позиции в описании варианта размещения картинок | speaker |
Настройка микшера при создании по REST API
В сборке 5.2.872 добавлена возможность передать параметры, аналогичные настройкам микшера в файле flashphoner.properties, при создании микшера по запросу /mixer/startup. В этом случае параметры будут применены только к этому экземпляру микшера. Например, запрос
Code Block | ||||
---|---|---|---|---|
| ||||
{
"uri": "mixer://mixer1",
"localStreamName": "stream3",
"mixerVideoWidth": 640,
"mixerVideoHeight": 360,
"mixerVideoFps": 24,
"mixerVideoBitrateKbps": 500
} |
создаст микшер с выходным потоком 640x360, fps 24 и битрейтом 500 кбит/с, независимо от того, какие настройки указаны в файле flashphoner.properties.
Полный список параметров микшера можно получить в ответе на запрос /mixer/find_all, например
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
[ { "localMediaSessionId": "7c9e5353-8680-4ad2-8a47-1a366091785c", "localStreamName": "m1", "uri": "mixer://m1", "status": "PROCESSED_LOCAL", "hasAudio": true, "hasVideo": true, "record": false, "mediaSessions": [], "mixerLayoutClass": "com.flashphoner.media.mixer.video.presentation.GridLayout", "mixerLayoutDir": "/opt/mixer1-layout", "mixerActivityTimerCoolOffPeriod": 1, "mixerActivityTimerTimeout": -1, "mixerAppName": "defaultApp", "mixerAudioOpusFloatCoding": false, "mixerAudioSilenceThreshold": -50, "mixerAudioThreads": 4, "mixerAutoScaleDesktop": true, "mixerDebugMode": false, "mixerDesktopAlign": "TOP", "mixerDisplayStreamName": false, "mixerDecodeStreamName": false, "mixerFontSize": 20, "mixerFontSizeAudioOnly": 40, "mixerIdleTimeout": 20000, "mixerInBufferingMs": 200, "mixerIncomingTimeRateLowerThreshold": 0.95, "mixerIncomingTimeRateUpperThreshold": 1.05, "mixerMcuAudio": false, "mixerMcuVideo": false, "mixerMcuMultithreadedMix": false, "mixerMinimalFontSize": 1, "mixerMcuMultithreadedDelivery": false, "mixerOutBufferEnabled": false, "mixerOutBufferInitialSize": 2000, "mixerOutBufferStartSize": 150, "mixerOutBufferPollingTime": 100, "mixerOutBufferMaxBufferingsAllowed": -1, "mixerShowSeparateAudioFrame": true, "mixerTextAutoscale": true, "mixerTextColour": "0xFFFFFF", "urimixerTextBulkWriteWithBuffer": "mixer://m1"true, "mixerTextBulkWrite": true, "mixerTextBackgroundOpacity": 100, "statusmixerTextBackgroundColour": "PROCESSED_LOCAL""0x2B2A2B", "mixerTextPaddingLeft": 5, "hasAudiomixerVoiceActivitySwitchDelay": true0, "hasVideomixerVoiceActivityFrameThickness": true6, "recordmixerVoiceActivityFramePositionInner": false, "mediaSessionsmixerVoiceActivityColour": []"0x00CC66", "mixerLayoutClassmixerVoiceActivity": "com.flashphoner.media.mixer.video.presentation.GridLayout"true, "mixerLayoutDirmixerVideoWidth": "/opt/mixer1-layout"1280, "mixerActivityTimerCoolOffPeriodmixerVideoThreads": 14, "mixerActivityTimerTimeoutmixerVideoStableFpsThreshold": -115, "mixerAppNamemixerVideoQuality": "defaultApp"24, "mixerAudioOpusFloatCodingmixerVideoProfileLevel": false"42c02a", "mixerAudioSilenceThresholdmixerVideoLayoutDesktopKeyWord": -50"desktop", "mixerAudioThreadsmixerVideoHeight": 4720, "mixerAutoScaleDesktopmixerVideoGridLayoutPadding": true30, "mixerDebugModemixerVideoGridLayoutMiddlePadding": false10, "mixerDesktopAlignmixerVideoFps": "TOP"30, "mixerDisplayStreamNamemixerVideoDesktopLayoutPadding": false30, "mixerFontSizemixerVideoDesktopLayoutInlinePadding": 2010, "mixerFontSizeAudioOnlymixerVideoBufferLength": 401000, "mixerIdleTimeoutmixerVideoBitrateKbps": 200002000, "mixerInBufferingMsmixerUseSdpState": 200true, "mixerIncomingTimeRateLowerThresholdmixerType": 0.95"NATIVE", "mixerIncomingTimeRateUpperThresholdmixerThreadTimeoutMs": 1.0533, "mixerMcuAudiomixerTextPaddingTop": false5, "mixerMcuVideomixerTextPaddingRight": false4, "mixerMcuMultithreadedMixmixerTextFont": false"Serif", "mixerMinimalFontSizemixerTextPaddingBottom": 15, "mixerMcuMultithreadedDeliverymixerTextDisplayRoom": falsetrue, "mixerOutBufferEnabledmixerTextCutTop": false3, "mixerOutBufferInitialSizemixerRealtime": 2000true, "mixerOutBufferStartSizemixerPruneStreams": 150false, "mixerOutBufferPollingTimeaudioMixerOutputCodec": 100"alaw", "mixerOutBufferMaxBufferingsAllowedaudioMixerOutputSampleRate": -148000, "mixerShowSeparateAudioFrameaudioMixerMaxDelay": true300, "mixerTextAutoscalemixerAudioOnlyHeight": true360, "mixerTextColourmixerAudioOnlyWidth": "0xFFFFFF"640, "mixerTextBulkWriteWithBuffervideoOutputCodec": true"vp8", "mixerTextAlign": "mixerTextBulkWrite": true, "mixerTextBackgroundOpacity": 100, "mixerTextBackgroundColour": "0x2B2A2B", "mixerTextPaddingLeft": 5,TOP_CENTER" } ] |
Изменение параметров микшера в процессе его работы по REST API
Начиная со сборки 5.2.1480, следующие параметры можно менять для активного микшера при помощи запроса /mixer/set_parameter
:
Code Block | ||||
---|---|---|---|---|
| ||||
[ { ... "mixerVoiceActivitySwitchDelaymixerLayoutClass": 0, "mixerVoiceActivityFrameThickness": 6"com.flashphoner.media.mixer.video.presentation.GridLayout", "mixerVoiceActivityFramePositionInnermixerAutoScaleDesktop": falsetrue, "mixerVoiceActivityColourmixerDesktopAlign": "0x00CC66TOP", "mixerVoiceActivitymixerDisplayStreamName": true, "mixerVideoWidthmixerFontSize": 128020, "mixerVideoThreadsmixerFontSizeAudioOnly": 440, "mixerVideoStableFpsThresholdmixerMinimalFontSize": 151, "mixerVideoQualitymixerShowSeparateAudioFrame": 24true, "mixerVideoProfileLevelmixerTextAutoscale": "42c02a"true, "mixerVideoLayoutDesktopKeyWordmixerTextColour": "desktop0xFFFFFF", "mixerVideoHeightmixerTextBulkWriteWithBuffer": 720true, "mixerVideoGridLayoutPaddingmixerTextBulkWrite": 30true, "mixerVideoGridLayoutMiddlePaddingmixerTextBackgroundOpacity": 10100, "mixerVideoFpsmixerTextBackgroundColour": 30"0x2B2A2B", "mixerVideoDesktopLayoutPaddingmixerFrameBackgroundColour": 30"0x2B2A2B", "mixerVideoDesktopLayoutInlinePaddingmixerTextPaddingLeft": 105, "mixerVideoBufferLengthmixerVoiceActivitySwitchDelay": 10000, "mixerVideoBitrateKbpsmixerVoiceActivityFrameThickness": 20006, "mixerUseSdpStatemixerVoiceActivityFramePositionInner": truefalse, "mixerTypemixerVoiceActivityColour": "NATIVE0x00CC66", "mixerThreadTimeoutMsmixerVoiceActivity": 33true, "mixerTextPaddingTopmixerVideoLayoutDesktopKeyWord": 5"desktop", "mixerTextPaddingRightmixerVideoGridLayoutPadding": 430, "mixerTextFontmixerVideoGridLayoutMiddlePadding": "Serif"10, "mixerTextPaddingBottommixerVideoDesktopLayoutPadding": 530, "mixerTextDisplayRoommixerVideoDesktopLayoutInlinePadding": true10, "mixerTextCutTopmixerTextPaddingTop": 35, "mixerRealtimemixerTextPaddingRight": true4, "mixerPruneStreamsmixerTextFont": false"Serif", "audioMixerOutputCodecmixerTextPaddingBottom": "alaw"5, "audioMixerOutputSampleRatemixerTextDisplayRoom": 48000true, "audioMixerMaxDelaymixerTextCutTop": 3003, "mixerAudioOnlyHeightmixerTextAlign": 360"BOTTOM_LEFT", "mixerAudioOnlyWidthmixerVideoDesktopFullscreen": 640false, "videoOutputCodec":"vp8", "mixerTextAlignmixerLayoutDir": "TOP_CENTER"" } ] |
Если запрос содержит параметры, которые не могут быть изменены для активного микшера, такой запрос вернет 400 Bad request
с указанием неподдерживаемого параметра.
Отправка REST-запроса к WCS-серверу
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
package com.flashphoner.mixerlayout; // Import mixer layout interface import com.flashphoner.media.mixer.video.presentation.BoxPosition; import com.flashphoner.sdk.media.IVideoMixerLayout; // Import YUV frame description import com.flashphoner.sdk.media.YUVFrame; // Import Box class for picture operations import com.flashphoner.media.mixer.video.presentation.Box; // Uncomment this if using build 5.2.878-5.2.976 // import com.flashphoner.server.commons.rmi.data.impl.MixerConfig; // Import Java packages to use import java.awt.*; import java.util.ArrayList; public class SideBySideLayout implements IVideoMixerLayout { // Owner's stream name private static final String USERFOR = "user_for"; // Challenger's stream name private static final String USERAGAINST = "user_against"; /** * Function to compute layout, will be called by mixer before encoding output stream picture * This example computes grid layout * @param yuvFrames - incoming streams raw pictures array in YUV format * @param strings - incoming streams names array * @param canvasWidth - mixer output picture canwas width * @param canvasHeight - mixer output picture canwas heigth * @return array of pictures layouts */ @Override public Layout[] computeLayout(YUVFrame[] yuvFrames, String[] strings, int canvasWidth, int canvasHeight) { // This object represents mixer canvas Box mainBox = new Box(null, canvasWidth, canvasHeight); // Container to place CHALLENGER stream pictures Box userForContainer = new Box(mainBox, canvasWidth / 2, canvasHeight); userForContainer.setPosition(BoxPosition.LEFT); // Container to place OWNER stream pictures Box userAgainstContainer = new Box(mainBox, canvasWidth / 2, canvasHeight); userAgainstContainer.setPosition(BoxPosition.RIGHT); // Iterate through incoming stream pictures array for (int c = 0; c < yuvFrames.length; c++) { String name = strings[c]; Box container; // Chhose container depending on stream name if (name.contains(USERFOR)) { container = userForContainer; } else if (name.contains(USERAGAINST)) { container = userAgainstContainer; } else { // Wrong stream name continue; } // Fill the container by the stream picture Box frameBox = Box.computeBoxWithFrame(container, yuvFrames[c]); frameBox.fillParentNoScale(); } // Prepare an array to return layout calculated ArrayList<IVideoMixerLayout.Layout> layout = new ArrayList<>(); // Calculate mixer layout mainBox.computeLayout(layout); // Return the result return layout.toArray(new IVideoMixerLayout.Layout[layout.size()]); } /** * The function for internal use. * Uncomment this if using build 5.2.878-5.2.976 */ //@Override //public void setConfig(MixerConfig mixerConfig) { //} } //} } |
Отдельный каталог для собственных Java библиотек
Начиная со сборки 5.2.1512, Java библиотеки (jar файлы) собственных вариантов размещения картинок должны помещаться в каталог /usr/local/FlashphonerWebCallServer/lib/custom
Code Block | ||||
---|---|---|---|---|
| ||||
cp testlayout.jar /usr/local/FlashphonerWebCallServer/lib/custom |
Этот каталог сохраняется при дальнейших обновлениях сервера к более новым сборкам. Таким образом, нет необходимости снова копировать jar файлы после установки обновления.
Управление размещением картинок при создании микшера
...
/mixer/set_body_watermark
- к картинке всего выходного потока потока микшера
Code Block | ||||
---|---|---|---|---|
| ||||
{
"uri":"mixer://m1",
"watermark":"/opt/media/logo.png",
"x":0,
"y":0,
"marginTop":0,
"marginLeft":0,
"marginBottom":0,
"marginRight":0
} |
/mixer/set_stream_watermark
- к картинке одного из входных потоков микшера
Code Block | ||||
---|---|---|---|---|
| ||||
{ "uri":"mixer://m1", "watermark":"/opt/media/logo.png", "mediaSessionId": "030bb470-185c-11ed-9fad-918e05233ae9", "x":0, "y":0, "marginTop":0, "marginLeft":0, "marginBottom":0, "marginRight":0 } |
...
:0,
"marginRight":0
} |
Здесь
- watermark - имя файла водяного знака
- x, y - координаты верхнего левого угла водяного знака на картинке потока
- marginTop, marginLeft, marginBottom, marginRignt - отступы от границ картинки потока
Если координаты выходят за границы картинки потока, водяной знак будет вписан в эти границы с учетом отступов.
Для того, чтобы переместить водяной знак в другое место на картинке, необходимо отправить запрос с тем же файлом, но новыми координатами. Чтобы убрать водяной знак с картинки, необходимо отправить запрос с пустым полем watermark
Code Block | ||||
---|---|---|---|---|
| ||||
{ "uri":"mixer://m1", "watermark":"/opt/media/logo.png", "mediaSessionId": "030bb470-185c-11ed-9fad-918e05233ae9", "x":0, "y":0, "marginTop":0, "marginLeft":0, "marginBottom":0, "marginRight":0 } |
Здесь
- watermark - имя файла водяного знака
- x, y - координаты верхнего левого угла водяного знака на картинке потока
- marginTop, marginLeft, marginBottom, marginRignt - отступы от границ картинки потока
Если координаты выходят за границы картинки потока, водяной знак будет вписан в эти границы с учетом отступов.
...
} |
Стерео звук в выходном потоке микшера
По умолчанию, микшер преобразует стерео аудио из входящих потоков в моно, чтобы снизить количество обрабатываемых данных. Это позволяет уменьшить возможные задержки при использовании микшеров реального времени для видеоконференций.
При необходимости, микшер может быть переключен в режим обработки стерео звука, например, в случае онлайн-радиостанции для трансляции музыки. Для этого в сборке 5.2.922 добавлена настройка, позволяющая задать количество аудио каналов микшера
Code Block | ||
---|---|---|
| ||
audio_mixer_output_channels=2 |
Декодирование символов в имени входящего потока
В сборке 5.2.1802 добавлена возможность декодирования символов в имени потока, закодированных на стороне клиента при помощи encodeURIComponent(). Эта возможность включается настройкой
Code Block | ||
---|---|---|
| ||
mixer_decode_stream_name=true |
или добавлением параметра при создании микшера запросом /mixer/startup
Code Block | ||||
---|---|---|---|---|
| ||||
{ "uri": "mixer://m1"mixer1", "localStreamName": "mixer1", ..., "watermarkmixerDecodeStreamName":"" true } |
Стерео звук в выходном потоке микшера
По умолчанию, микшер преобразует стерео аудио из входящих потоков в моно, чтобы снизить количество обрабатываемых данных. Это позволяет уменьшить возможные задержки при использовании микшеров реального времени для видеоконференций.
При необходимости, микшер может быть переключен в режим обработки стерео звука, например, в случае онлайн-радиостанции для трансляции музыки. Для этого в сборке 5.2.922 добавлена настройка, позволяющая задать количество аудио каналов микшера
...
theme | RDark |
---|
...
В этом случае в изображении будут отображаться декодированные символы, если такие символы есть в используемом шрифте, или близкие к ним по начертанию.
Поддержка MCU
Поддержка MCU в микшере включается для аудио настройкой
...