Creating Custom Mixer Layout

MM2 Mutlimedia

New Member
I would like to create a custom mixer layout using the instructions on the following page:
https://docs.flashphoner.com/displa...Streammixer-Mixeroutputstreamlayoutmanagement
The instructions said to run this line:
javac -cp/usr/local/FlashphonerWebCallServer/lib/tbs-flashphoner.jar ./com/flashphoner/mixerlayout/mylayout.java

But tbs-flashphoner.jar does not exist in my /usr/local/FlashphonerWebCallServer/lib folder.

When I run the command, the following error appears:
programLayout.java:3: error: package com.flashphoner.sdk.media does not exist

1) Should tbs-flashphoner.jar be in the lib folder? How can I get it there?
2) If I fix the tbs-flashphoner.jar issue, will it also fix the missing com.flashphoner.sdk.media package?

Thank you!
 

MM2 Mutlimedia

New Member
I see the FP team has changed the documentation from:
javac -cp/usr/local/FlashphonerWebCallServer/lib/tbs-flashphoner.jar ./com/flashphoner/mixerlayout/TestLayout.java
to:
javac -cp/usr/local/FlashphonerWebCallServer/lib/wcs-core.jar ./com/flashphoner/mixerlayout/TestLayout.java

This works fine now!
Many thanks you for the quick change.
 

MM2 Mutlimedia

New Member
One more question regarding this topic.
The documentation in https://docs.flashphoner.com/displa...Streammixer-Mixeroutputstreamlayoutmanagement mentioned to set the following parameter in flashphoner.properties:
mixer_layout_class=com.flashphoner.mixerlayout.myLayout

But when I initiate a mixer the flashphoner.log shows this error:
ERROR A - HTTPS-pool-4-thread-2 Can't load class com.flashphoner.mixerlayout.myLayout

These work good:
  • mixer_layout_class=com.flashphoner.media.mixer.video.presentation.GridLayout
  • mixer_layout_class=com.flashphoner.media.mixer.video.presentation.CenterNoPaddingGridLayout
It looks like the class reference for custom templates in flashphoner.properties isn't correct.

This is myLayout.java file:

Code:
package com.flashphoner.mixerlayout;
import com.flashphoner.sdk.media.IVideoMixerLayout;
import com.flashphoner.sdk.media.YUVFrame;
import java.awt.*;
import java.util.ArrayList;
public class myLayout implements IVideoMixerLayout {
    private static final int PADDING = 5;
    @Override
    public Layout[] computeLayout(YUVFrame[] yuvFrames, String[] strings, int canvasWidth, int canvasHeight) {
        ArrayList<IVideoMixerLayout.Layout> layout = new ArrayList<>();
        for (int c = 0; c < yuvFrames.length; c++) {
            Point prevPoint = new Point();
            Dimension prevDimension = new Dimension(canvasWidth, canvasHeight);
            if (layout.size() > 0) {
                prevPoint.setLocation(layout.get(c-1).getPoint());
                prevDimension.setSize(layout.get(c-1).getDimension());
            }
            Point currentPoint = new Point((int) (prevPoint.getX()+prevDimension.getWidth()+PADDING),
                                           (int)(prevPoint.getY()+prevDimension.getHeight()));
            layout.add(new IVideoMixerLayout.Layout(currentPoint, new Dimension(canvasWidth/yuvFrames.length,
                                                    canvasHeight/yuvFrames.length), yuvFrames[c]));
        }
        return layout.toArray(new IVideoMixerLayout.Layout[layout.size()]);
    }
}
Thanks in advance!
 

Max

Administrator
Staff member
Good day.
We checked your mixer layout sample build by this manual, and it was correctly loaded. Please check if you copied mylayout.jar to /usr/local/FlashphonerWebCallServer/lib
Code:
cp mylayout.jar /usr/local/FlashphonerWebCallServer/lib
Please note that there are the mixer tickets WCS-2419 and WCS-2490 we're working on.
 

Max

Administrator
Staff member
Good day.
We fixed custom mixer layout example:
Code:
public class TestLayout implements IVideoMixerLayout {

    private static final int PADDING = 4; // This value should be even

    @Override
    public Layout[] computeLayout(YUVFrame[] yuvFrames, String[] strings, int canvasWidth, int canvasHeight) {
        ArrayList<IVideoMixerLayout.Layout> layout = new ArrayList<>();

        int canvasCenter = canvasHeight / 2;
        int frameCenter = canvasCenter - (canvasHeight / yuvFrames.length) / 2;

        int layoutWidth = canvasWidth / yuvFrames.length - PADDING;
        int layoutHeight = canvasHeight / yuvFrames.length;

        for (int c = 0; c < yuvFrames.length; c++) {
            Point prevPoint = new Point();
            Dimension prevDimension = new Dimension();
            if (layout.size() > 0) {
                prevPoint.setLocation(layout.get(c - 1).getPoint());
                prevDimension.setSize(layout.get(c - 1).getDimension());
            }
            Point currentPoint = new Point((int) (prevPoint.getX() + prevDimension.getWidth() + PADDING),
                    frameCenter);

            layout.add(new IVideoMixerLayout.Layout(currentPoint, new Dimension(layoutWidth,
                    layoutHeight), yuvFrames[c]));
        }
        return layout.toArray(new IVideoMixerLayout.Layout[layout.size()]);
    }
}
Note that custom layout padding and mixer output resolution should always be even, for example, 640x360, but not 641x365. We still working on ticket WCS-2419 to fix this.
 

Max

Administrator
Staff member
The issue with uneven custom layout padding or mixer output resolution has been fixed in WCS v. 5.2.572: if width or height is uneven, it will be decremented.
 
Top