Streaming custom layout to Youtube/Facebook

Hello,
Currently we have jitsi meet deployment on our server and configured to stream to youtube and facebook. So the jitsi meet UI is available at jitsi.out-server.com/meeting-name
We have a requirement for custom layout which the moderator can change during the meeting.
I came across this post and the Fishbowl example by @maxired

My question is when we implement a custom layout using lib-jitsi-meet, how do we ensure that the same layout gets sent to Youtube/Facebook when we do a live stream?
I’m aware that in jitsi-meet we can do this by turning on ‘Everyone follows me’ option. But jitsi-meet only offers a grid and focus layout. What happens when we have a custom layout implemented using lib-jitsi-meet? Do we have to change any configuration in jibri on server side to capture the custom layout? If yes can someone please point me to the correct config file the the same.

Thanks for any hints :pray:

JIbri spins a virtual instance of chrome and joins like a meeting participant. It then records that browser. So whatever layout it sees is what it records, there is no special configuration.

Hi Freddie,

I do not want to broadcast the default jitsi-meet layout. I have to build a custom layout using lib-jitsi-meet. My question is ‘how do I point jibri to record from this layout?’. I understand that jibri runs a virtual chrome instance. I need help connecting jibri and my custom lib-jitsi-meet implementation so that when jibri opens the browser for recording its the lib-jitsi-meet implementation hosted on some example-domain.com server and not the one I got with sudo apt install jitsi-meet

I’m new to Jitsi. Really appreciate your patience and help.

There is no such feature at the moment, I think.

Did you came across https://github.com/jitsi/jibri/issues/231 ?

Yes there are a couple of such issues in the community and the workaround is to replace meet.jitsi with public_url. for example, replace recorder.meet.jitsi with recorder.public_url. do this for the entire config not just for jibri. I’m not sure how to do it for vanilla config but with docker, it’s easy since it uses env variables. I’m using it for a while now and I never faced this issue.

Thanks for the leads @maxired @metadata

I’ll setup the docker and try.

@metadata

  1. What all config files do i need to change? (/etc/jitsi/jibri/jibri.conf, /etc/nginx/nginx.conf, prosody.cfg.lua, and?)
  2. What should be the specification (any samples?) of the pages that must be hosted in the public URL)?

Only change meet.jitsi in .env file with public_url because docker-compose uses .env file for its config.

Didn’t get it.

My public_url will have a custom jitsi meet layout frontend built using lib-jitsi-meet. I want to add a stream to Youtube button in this layout and when I click on it the custom layout will be sent to YouTube. So apart from the config changes in docker do I also need to add anything to my custom layout frontend?

I’m not sure if I can help you with this but below is the steps I follow If I made any changes to jitsi-meet and want to replace default layout with custom one.

In general if I make any changes to jitsi-meet then I need to compile it and then it results in two directories. one is css and other is libs. In case of docker, I have created a directory CustomConfig in web directory and put css and libs directory in it and then In web/Dockerfile, I’m doing COPY CustomConfig/ /usr/share/jitsi-meet to replace the default libs and css files with the custom ones. Then creating a docker image with this config.

ARG JITSI_REPO=jitsi
FROM ${JITSI_REPO}/base

ADD https://raw.githubusercontent.com/acmesh-official/acme.sh/2.8.8/acme.sh /opt
COPY rootfs/ /

RUN \
	apt-dpkg-wrap apt-get update && \
	apt-dpkg-wrap apt-get install -y cron nginx-extras jitsi-meet-web socat && \
	apt-dpkg-wrap apt-get -d install -y jitsi-meet-web-config && \
    dpkg -x /var/cache/apt/archives/jitsi-meet-web-config*.deb /tmp/pkg && \
    mv /tmp/pkg/usr/share/jitsi-meet-web-config/config.js /defaults && \
	mv /usr/share/jitsi-meet/interface_config.js /defaults && \
	rm -f /etc/nginx/conf.d/default.conf && \
	apt-cleanup && \
	rm -rf /tmp/pkg /var/cache/apt

COPY CustomConfig/ /usr/share/jitsi-meet

EXPOSE 80 443

VOLUME ["/config", "/usr/share/jitsi-meet/transcripts"]

I came across a jibri api here that allows to pass domain and base url as a part of the API request.
The first health check request (/jibri/api/v1.0/health) worked and gave 200. However the actual call to start streaming is giving 500 Internal Server Error.

Same API request in Postman:
POST http://my-server.com:2222/jibri/api/v1.0/startService
Body

{
“sessionId”: “streamTest”, // the recording operation session (e.g. RecordTest)
“callParams”: {
“callUrlInfo”: {
“baseUrl”: “https://my-server.com”, // the base url of the call (e.g. https://meet.jit.si)
“callName”: “daily_standup” // the call name to be appended to the base url
}
},
“callLoginParams”: {
“domain”: “recorder.my-server.com”, // The xmpp domain the Jibri client should log into when joining the call
“username”: “recorder”, // The username to use for logging in to the above domain
“password”: “HW8gv#7Hv6” // The password to use for logging in to the above domain
},
“sinkType”: “stream”, // “stream” for streaming, “file” for recording
“youTubeStreamKey”: “” // If using “stream” above, this is the YouTube stream key to use
}

I checks the jibri server logs in /var/log/jitsi/jibri/log.0.txt but the only log added after the api call is:

2021-05-03 05:42:23.009 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

/etc/jitsi/jibri/logging.properties:

handlers = java.util.logging.FileHandler
java.util.logging.FileHandler.level = FINE
java.util.logging.FileHandler.pattern = /var/log/jitsi/jibri/log.%g.txt
java.util.logging.FileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter
java.util.logging.FileHandler.count = 10
java.util.logging.FileHandler.limit = 10000000
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.level = FINE
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.pattern = /var/log/jitsi/jibri/ffmpeg.%g.txt
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.count = 10
org.jitsi.jibri.capture.ffmpeg.util.FfmpegFileHandler.limit = 10000000
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.level = FINE
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.pattern = /var/log/jitsi/jibri/pjsua.%g.txt
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.count = 10
org.jitsi.jibri.sipgateway.pjsua.util.PjsuaFileHandler.limit = 10000000
org.jitsi.jibri.selenium.util.BrowserFileHandler.level = FINE
org.jitsi.jibri.selenium.util.BrowserFileHandler.pattern = /var/log/jitsi/jibri/browser.%g.txt
org.jitsi.jibri.selenium.util.BrowserFileHandler.formatter = net.java.sip.communicator.util.ScLogFormatter
org.jitsi.jibri.selenium.util.BrowserFileHandler.count = 10
org.jitsi.jibri.selenium.util.BrowserFileHandler.limit = 10000000
org.jitsi.level = FINE
org.jitsi.jibri.config.level = INFO
org.glassfish.level = INFO
org.osgi.level = INFO
org.jitsi.xmpp.level = INFO

Do I need to change some config to check the error?
Which file would get the error message for the failed request?

Can you include the entire Jibri log from when you try and run that rest call?

The only thing that gets printed to the jibri log was after doing the rest call.

2021-05-03 05:42:23.009 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

This is the log at: /var/log/jitsi/jibri/log.0.txt rest of the files at /var/log/jitsi/jibri were not updated after the rest call.
Is there any other place I should be looking at for logs?
I also check for the all the file changed in my EC2 instance in the last 1 minute immediately after doing the API call

find / -type d -mmin -1 -ls

This command showed some Jibri processes but no logs files.

Can you explicitly set org.jitsi.jibri.api.http.level = FINE in your logging config and try again? There’s a debug log in the startService handler that should be showing (logger.debug { "Got a start service request with params $startServiceParams" }). If you’re not even seeing that, then you’ve got a more fundamental problem. What return code are you getting from the request?

I changed the log level to FINE.
Command:
less log.0.txt | grep "service request"
less log.1.txt | grep "service request"
Output:
Gives no output.

Command:
less log.0.txt | grep 2222
Output:
2021-05-05 17:05:11.222 INFO: [1] org.jitsi.jibri.Main.main() Using port 2222 for HTTP API

The API request is giving return code 500.

Ok, and none of those other error logs are printed either? It would speed things up if you could just attach log.0.txt.

Yes all other files don’t have it either

tail -f *.txt | grep “service request”
shows no logs

Here is log.0.txt

2021-05-05 17:05:09.964 INFO: [1] org.jitsi.jibri.Main.handleCommandLineArgs() Jibri run with args [–config, /etc/jitsi/jibri/config.json]

2021-05-05 17:05:10.046 INFO: [1] org.jitsi.jibri.Main.setupLegacyConfig() Checking legacy config file /etc/jitsi/jibri/config.json

2021-05-05 17:05:10.046 INFO: [1] org.jitsi.jibri.Main.setupLegacyConfig() Legacy config file /etc/jitsi/jibri/config.json doesn’t exist

2021-05-05 17:05:10.745 INFO: [1] org.jitsi.jibri.webhooks.v1.JwtInfo.Companion.fromConfig() got jwtConfig: {}

2021-05-05 17:05:10.746 INFO: [1] org.jitsi.jibri.webhooks.v1.JwtInfo.Companion.fromConfig() Unable to create JwtInfo: com.typesafe.config.ConfigException$Missing: reference.conf @ jar:file:/opt/jitsi/jibri/jibri.jar!/reference.conf: 52: No configuration setting found for key ‘signing-key-path’

2021-05-05 17:05:10.883 INFO: [1] org.jitsi.jibri.Main.main() Using port 3333 for internal HTTP API

2021-05-05 17:05:10.891 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:05:11.194 INFO: [1] org.jitsi.jibri.api.xmpp.XmppApi.updatePresence() Jibri reports its status is now JibriStatus(busyStatus=IDLE, health=OverallHealth(healthStatus=HEALTHY, details={})), publishing presence to connections

2021-05-05 17:05:11.201 INFO: [1] org.jitsi.jibri.api.xmpp.XmppApi.start() Connecting to xmpp environment on jitsi.myserver.com with config XmppEnvironmentConfig(name=Jibri Sessions, xmppServerHosts=[jitsi.myserver.com], xmppDomain=jitsi.myserver.com, controlLogin=XmppCredentials(domain=auth.jitsi.myserver.com, username=jibri, password=mqjzsbvbf7), controlMuc=XmppMuc(domain=internal.auth.jitsi.myserver.com, roomName=JibriBrewery, nickname=Live), sipControlMuc=null, callLogin=XmppCredentials(domain=recorder.jitsi.myserver.com, username=recorder, password=HW8gv#5Hv7), stripFromRoomDomain=conference., usageTimeoutMins=0, trustAllXmppCerts=true)

2021-05-05 17:05:11.202 INFO: [1] org.jitsi.jibri.api.xmpp.XmppApi.start() The trustAllXmppCerts config is enabled for this domain, all XMPP server provided certificates will be accepted

2021-05-05 17:05:11.222 INFO: [1] org.jitsi.jibri.Main.main() Using port 2222 for HTTP API

2021-05-05 17:05:11.223 WARNING: [26] org.jitsi.xmpp.mucclient.MucClient.log() Disabling certificate verification!

2021-05-05 17:05:11.387 INFO: [26] org.jitsi.xmpp.mucclient.MucClient.log() Connected.

2021-05-05 17:05:11.387 INFO: [26] org.jitsi.xmpp.mucclient.MucClient.log() Logging in.

2021-05-05 17:05:11.450 INFO: [26] org.jitsi.xmpp.mucclient.MucClient.log() Joined MUC: jibribrewery@internal.auth.jitsi.myserver.com

2021-05-05 17:06:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:07:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:08:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:09:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:10:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:11:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:12:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:13:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:14:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:15:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:16:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:17:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:18:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

There are no ERROR logs. Just WARNING, FINE, and INFO logs

Ok, and retrieving health does work, right? Can you do a run where you get the health and then try startService and attach those logs?

Here is the log file after doing a health followed by startService:

2021-05-05 17:47:08.377 FINE: [128] org.jitsi.jibri.api.http.HttpApi.invokeSuspend() Got health request

2021-05-05 17:47:08.378 FINE: [128] org.jitsi.jibri.api.http.HttpApi.invokeSuspend() Returning health JibriHealth(status=JibriStatus(busyStatus=IDLE, health=OverallHealth(healthStatus=HEALTHY, details={})), environmentContext=null)

2021-05-05 17:47:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:48:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status

2021-05-05 17:49:10.878 FINE: [17] org.jitsi.jibri.webhooks.v1.WebhookClient.invokeSuspend() Updating 0 subscribers of status