Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

REST-method

Example of REST query

Example of response

Response statuses

Description

/mixer/startup

Code Block
languagejs
themeRDark
{
  "uri": "mixer://mixer1",
  "localStreamName": "stream3",
  "hasVideo": "true",
  "hasAudio": "true",
  "watermark": "watermark.png",
  "background": "background.png",
  "mixerLayoutClass": "com.flashphoner.mixerlayout.TestLayout"
}

200 - OK

400 - Bad request

409 - Conflict

500 - Internal error

Creates a mixer the provided stream is published for

/mixer/add

Code Block
languagejs
themeRDark
{
  "uri": "mixer://mixer1",
  "remoteStreamName": "stream1",
  "hasVideo": "true",
  "hasAudio": "true",
  "streamLabel": "John Doe",
  "avatar": "https://mystorage/storage/avatar.png",
  "videoPositionId": "speaker"
}

200 - OK

404 - Mixer not found

404 - Stream not found

500 - Internal error

Add the RTMP stream to the mixer

/mixer/remove

Code Block
languagejs
themeRDark
{
  "uri": "mixer://mixer1",
  "remoteStreamName": "stream1"
}

200 - OK

404 - Mixer not found

404 - Stream not found

500 - Internal error

Remove the RTMP stream from the mixer

/mixer/find_all


Code Block
languagejs
themeRDark
{
"localMediaSessionId": "ce92b134-2468-4460-8d06-1ea3c5aabace",
"remoteMediaSessionId": null,
"localStreamName": "mixer1",
"remoteStreamName": null,
"uri": "mixer://mixer1",
"status": "PROCESSED_LOCAL",
"mediaSessions": [
  "95bf2be8-f459-4f62-9a7f-c588f33e0ad3",
  "693781de-cada-4589-abe1-c3ee55c66901"
],
}

200 - OK

404 - Not found

500 - Internal error

Find all mixers

/mixer/terminate

Code Block
languagejs
themeRDark
{
  "uri": "mixer://mixer1"
}

200 - OK

404 - Not found

500 - Internal error

Terminate operation of the mixer

/stream/startRecording

Code Block
languagejs
themeRDark
{
  "mediaSessionId": "23d07fa1-3c74-4d6f-a0de-9b4bf83ce665"
}

200 - OK

404 - Not found

500 - Internal error

Start recording of the stream in the given media session

/stream/stopRecording

Code Block
languagejs
themeRDark
{
  "mediaSessionId": "23d07fa1-3c74-4d6f-a0de-9b4bf83ce665"
}

200 - OK

404 - Not found

500 - Internal error

Stop recording the stream in the given media session

/mixer/setAudioVideo

Code Block
languagejs
themeRDark
{
 "uri": "mixer://m1",
 "streams": "^stream.*",
 "audioLevel": 0,
 "videoMuted": true
}

200 - OK

400 - Bad request

404 - Not found

500 - Internal error

Mute/unmute video or change audio level for mexer incoming stream
/mixer/set_body_watermark
Code Block
languagejs
themeRDark
{
 "uri":"mixer://m1",
 "watermark":"/opt/media/logo.png",
 "x":10,
 "y":10,
 "marginTop":5,
 "marginLeft":5,
 "marginBottom":5,
 "marginRight":5
}

200 - OK

400 - Bad request

404 - Not found

Add watermark to mixer output stream picture
/mixer/set_stream_watermark
Code Block
languagejs
themeRDark
{
 "uri":"mixer://m1",
 "watermark":"/opt/media/logo.png",
 "mediaSessionId": "030bb470-185c-11ed-9fad-918e05233ae9",
 "x":10,
 "y":10,
 "marginTop":5,
 "marginLeft":5,
 "marginBottom":5,
 "marginRight":5
}

200 - OK

400 - Bad request

404 - Not found

Add watermark to one of the mixer input streams pictures in the mixer output stream

Parameters

...

Parameter name

...

Description

...

Example

...

uri

...

Unique identifier of the mixer

...

mixer://mixer1

...

localStreamName

...

Name of the output stream of the mixer

...

stream3

...

remoteStreamName

...

Name of the stream added to the mixer

...

stream1

rtmp://rtmp.flashphoner.com:1935/live/rtmp_stream1

...

mediaSessionId

...

Media session identifier

...

ce92b134-2468-4460-8d06-1ea3c5aabace

...

status

...

Stream status

...

PROCESSED_LOCAL

...

^stream.*

["stream1", "stream2"]

...

Mixer configuration while creating the instance using REST API

Since build 5.2.872 it is possible to pass most of mixer parameters corresponding to flashphoner.properties mixer settings while creating the mixer using /mixer/startup REST query. In this case, parameters will be applied to the created mixer instance only. For example, the following query

Code Block
languagejs
themeRDark
{
 "uri": "mixer://mixer1",
 "localStreamName": "stream3",
 "mixerVideoWidth": 640,
 "mixerVideoHeight": 360,
 "mixerVideoFps": 24,
 "mixerVideoBitrateKbps": 500
}

will create the mixer with output stream resolution 640x360, fps 24 and bitrate 500 kbps, no matter what settings are set in flashphoner.properties file

The mixer parameters fukll list can be retrieved using /mixer/find_all REST query, for example

...

languagejs
themeRDark
titleMixer parameters full list
collapsetrue

...

/mixer/set_stream_label
Code Block
languagejs
themeRDark
{
 "uri":"mixer://m1",
 "remoteStreamName":"stream1",
 "streamLabel": "Mr. John Doe"
}

200 - OK

404 - Not found

Set or change mixer participant stream label to display
/mixer/set_parameter
Code Block
languagejs
themeRDark
{
 "uri":"mixer://m1",
 "mixerLayoutDir":"/opt/GridLayout"
}

200 - OK

400 - Bad request

404 - Not found

Change the mixer parameter
/mixer/set_stream_avatar
Code Block
languagejs
themeRDark
{
 "uri":"mixer://m1",
 "remoteStreamName":"stream1",
 "avatar": "https://mystorage/storage/avatar.png"
}

200 - OK

400 - Bad request

404 - Not found

500 - Internal server error

Set avatar picture to audio stream in mixer
/mixer/remove_stream_avatar
Code Block
languagejs
themeRDark
{
 "uri":"mixer://m1",
 "remoteStreamName":"stream1"
}

200 - OK

404 - Not found

500 - Internal server error

Remove avatar picture from audio stream in mixer
/mixer/set_position
Code Block
languagejs
themeRDark
{
 "uri":"mixer://m1",
 "remoteStreamName":"stream1",
 "videoPositionId":"speaker"
}

200 - OK

404 - Not found

500 - Internal server error

Move the stream picture to the position (for custom XML layouts only)

Parameters

Parameter name

Description

Example

uri

Unique identifier of the mixer

mixer://mixer1

localStreamName

Name of the output stream of the mixer

stream3

hasVideoMix videotrue
hasAudioMix audiotrue

remoteStreamName

Name of the stream added to the mixer

stream1

rtmp://rtmp.flashphoner.com:1935/live/rtmp_stream1

mediaSessionId

Media session identifier

ce92b134-2468-4460-8d06-1ea3c5aabace

status

Stream status

PROCESSED_LOCAL

backgroundMixer backgroundbackground.png
watermarkMixer watermarkwatermark.png
mixerLayoutClassMixer layoutcom.flashphoner.mixerlayout.TestLayout
streamsStreams list or regular expression for search

^stream.*

["stream1", "stream2"]

audioLevelIncoming stream audio level0
videoMutedMute videotrue
streamLabelMixer participant stream label to displayJohn Doe
avatarPicture URI in PNG, JPG, BMP formats

https://mystorage.com/storage/avatar.jpg

videoPositionIdPosition identifier in custom XML layout to place a stream picturespeaker

Mixer configuration while creating the instance using REST API

Since build 5.2.872 it is possible to pass most of mixer parameters corresponding to flashphoner.properties mixer settings while creating the mixer using /mixer/startup REST query. In this case, parameters will be applied to the created mixer instance only. For example, the following query

Code Block
languagejs
themeRDark
{
 "uri": "mixer://mixer1",
 "localStreamName": "stream3",
 "mixerVideoWidth": 640,
 "mixerVideoHeight": 360,
 "mixerVideoFps": 24,
 "mixerVideoBitrateKbps": 500
}

will create the mixer with output stream resolution 640x360, fps 24 and bitrate 500 kbps, no matter what settings are set in flashphoner.properties file

The mixer parameters fukll list can be retrieved using /mixer/find_all REST query, for example

Code Block
languagejs
themeRDark
titleMixer parameters full list
collapsetrue
[
  {
    "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",
    "mixerTextBulkWriteWithBuffer": true,
    "mixerTextBulkWrite": true,
    "mixerTextBackgroundOpacity": 100,
    "mixerTextBackgroundColour": "0x2B2A2B",
    "mixerTextPaddingLeft": 5,
    "mixerVoiceActivitySwitchDelay": 0,
    "mixerVoiceActivityFrameThickness": 6,
    "mixerVoiceActivityFramePositionInner": false,
    "mixerVoiceActivityColour": "0x00CC66",
    "mixerVoiceActivity": true,
    "mixerVideoWidth": 1280,
    "mixerVideoThreads": 4,
    "mixerVideoStableFpsThreshold": 15,
    "mixerVideoQuality": 24,
    "mixerVideoProfileLevel": "42c02a",
    "mixerVideoLayoutDesktopKeyWord": "desktop",
    "mixerVideoHeight": 720,
    "mixerVideoGridLayoutPadding": 30,
    "mixerVideoGridLayoutMiddlePadding": 10,
    "mixerVideoFps": 30,
    "mixerVideoDesktopLayoutPadding": 30,
    "mixerVideoDesktopLayoutInlinePadding": 10,
    "mixerVideoBufferLength": 1000,
    "mixerVideoBitrateKbps": 2000,
    "mixerUseSdpState": true,
    "mixerType": "NATIVE",
    "mixerThreadTimeoutMs": 33,
    "mixerTextPaddingTop": 5,
    "mixerTextPaddingRight": 4,
    "mixerTextFont": "Serif",
    "mixerTextPaddingBottom": 5,
    "mixerTextDisplayRoom": true,
    "mixerTextCutTop": 3,
    "mixerRealtime": true,
    "mixerPruneStreams": false,
    "audioMixerOutputCodec": "alaw",
    "audioMixerOutputSampleRate": 48000,
    "audioMixerMaxDelay": 300,
    "mixerAudioOnlyHeight": 360,
    "mixerAudioOnlyWidth": 640,
    "videoOutputCodec":"vp8",
    "mixerTextAlign": "TOP_CENTER"
  }
]

Changing mixer parameters on the fly by REST API

Since build 5.2.1480, the following parameters can be changed for an active mixer using /mixer/set_parameter REST query:

Code Block
languagejs
themeRDark
[
  {
    ...
    "mixerLayoutClass": "com.flashphoner.media.mixer.video.presentation.GridLayout",
    "mixerAutoScaleDesktop": true,
    "mixerDesktopAlign": "TOP",
    "mixerDisplayStreamName": true,
    "mixerVideoWidthmixerFontSize": 128020,
    "mixerVideoThreadsmixerFontSizeAudioOnly": 440,
    "mixerVideoStableFpsThresholdmixerMinimalFontSize": 151,
    "mixerVideoQualitymixerShowSeparateAudioFrame": 24true,
    "mixerVideoProfileLevelmixerTextAutoscale": "42c02a",
    "mixerVideoLayoutDesktopKeyWord": "desktop"true,
    "mixerVideoHeightmixerTextColour": 720"0xFFFFFF",
    "mixerVideoGridLayoutPaddingmixerTextBulkWriteWithBuffer": 30true,
    "mixerVideoGridLayoutMiddlePaddingmixerTextBulkWrite": 10true,
    "mixerVideoFpsmixerTextBackgroundOpacity": 30100,
    "mixerVideoDesktopLayoutPaddingmixerTextBackgroundColour": 30"0x2B2A2B",
    "mixerVideoDesktopLayoutInlinePaddingmixerFrameBackgroundColour": 10"0x2B2A2B",
    "mixerVideoBufferLengthmixerTextPaddingLeft": 10005,
    "mixerVideoBitrateKbpsmixerVoiceActivitySwitchDelay": 20000,
    "mixerUseSdpStatemixerVoiceActivityFrameThickness": true6,
    "mixerTypemixerVoiceActivityFramePositionInner": "NATIVE"false,
    "mixerThreadTimeoutMsmixerVoiceActivityColour": 33"0x00CC66",
    "mixerTextPaddingTopmixerVoiceActivity": 5true,
    "mixerTextPaddingRightmixerVideoLayoutDesktopKeyWord": 4"desktop",
    "mixerTextFontmixerVideoGridLayoutPadding": "Serif"30,
    "mixerTextPaddingBottommixerVideoGridLayoutMiddlePadding": 510,
    "mixerTextDisplayRoommixerVideoDesktopLayoutPadding": true30,
    "mixerTextCutTopmixerVideoDesktopLayoutInlinePadding": 310,
    "mixerRealtimemixerTextPaddingTop": true5,
    "mixerPruneStreamsmixerTextPaddingRight": false4,
    "audioMixerOutputCodecmixerTextFont": "alawSerif",
    "audioMixerOutputSampleRatemixerTextPaddingBottom": 480005,
    "audioMixerMaxDelaymixerTextDisplayRoom": 300true,
    "mixerAudioOnlyHeightmixerTextCutTop": 3603,
    "mixerAudioOnlyWidthmixerTextAlign": 640"BOTTOM_LEFT",
    "videoOutputCodecmixerVideoDesktopFullscreen":"vp8" false,
      "mixerTextAlignmixerLayoutDir": "TOP_CENTER"
  }
]

If the REST query contains a parameters which cannot be set for active mixer, it will return 400 Bad request with unsupported parameters list.

Sending the REST query to the WCS server

...

Code Block
languagejava
themeRDark
titleSideBySideLayout.java
collapsetrue
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) {
    //}
}
/
    //@Override
    //public void setConfig(MixerConfig mixerConfig) {
    //}
}

A separate folder for custom Java libraries

Since build 5.2.1512, custom layout Java libraries (jar files) should be placed to the folder /usr/local/FlashphonerWebCallServer/lib/custom 

Code Block
languagebash
themeRDark
cp testlayout.jar /usr/local/FlashphonerWebCallServer/lib/custom

This folder is kept while updating WCS to a newer builds. A jar files do not need to be copied again after updating.

Mixer layout management while creating mixer

...

Mixer can be switched to stereo sound processing if necessary, for example, in case of online music radio. Since build 5.2.922 it is possible to set mixer audio channels count usig is possible to set mixer audio channels count usig the following parameter

Code Block
themeRDark
audio_mixer_output_channels=2

Characters decoding in input stream name

Since build 5.2.1802 it is possible to decode a characters encoded by encodeURIComponent() in input stream name. The feature may be enabled by the following parameter

Code Block
themeRDark
audiomixer_mixerdecode_outputstream_channels=2name=true

or by the following /mixer/startup query parameter

Code Block
languagejs
themeRDark
{
  "uri": "mixer://mixer1",
  "localStreamName": "mixer1",
  ...,
  "mixerDecodeStreamName": true
}

In this case a decoded characters available in the font used will be displayed, or a similar characters.

MCU support

Mixer MCU support for audio can be enabled with the following parameter

...

By default, mixer REST hooks are handled by defaultApp like another streams REST hooks.

REST hook for

...

adding stream to mixer or removing it

Since build 5.2.1416 it is possible to receive an events about a certain stream is added or removed to/from mixer. WCS sends to a backend server the REST hook /StreamEvent  

...