diff --git a/app/docker-compose.yml b/app/docker-compose.yml index df7fee4..d734c20 100644 --- a/app/docker-compose.yml +++ b/app/docker-compose.yml @@ -58,7 +58,7 @@ services: # https://github.com/jitsi/jicofo PREFIXV: stable/jitsi-meet_ VERSION: 5390 - image: superboum/amd64_jitsi_conference_focus:v6 + image: superboum/amd64_jitsi_conference_focus:v7 jitsi-videobridge: build: @@ -67,7 +67,7 @@ services: # https://github.com/jitsi/jitsi-videobridge PREFIXV: stable/jitsi-meet_ VERSION: 5390 - image: superboum/amd64_jitsi_videobridge:v16 + image: superboum/amd64_jitsi_videobridge:v17 jitsi-xmpp: build: diff --git a/app/jitsi/build/jitsi-conference-focus/Dockerfile b/app/jitsi/build/jitsi-conference-focus/Dockerfile index e2c459c..f78cc78 100644 --- a/app/jitsi/build/jitsi-conference-focus/Dockerfile +++ b/app/jitsi/build/jitsi-conference-focus/Dockerfile @@ -18,10 +18,7 @@ FROM debian:buster RUN apt-get update && \ apt-get install -y openjdk-11-jre-headless ca-certificates -ENV JAVA_SYS_PROPS="-Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/root -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=.sip-communicator -Dnet.java.sip.communicator.SC_LOG_DIR_LOCATION=/var/log/jitsi" - -COPY --from=builder /srv/build /srv/jicofo -COPY jicofo /usr/local/bin/jicofo -COPY sip-communicator.properties /root/.sip-communicator/sip-communicator.properties +COPY --from=builder /srv/build /usr/share/jicofo +COPY jicofo /usr/local/bin CMD ["/usr/local/bin/jicofo"] diff --git a/app/jitsi/build/jitsi-conference-focus/jicofo b/app/jitsi/build/jitsi-conference-focus/jicofo index 2bc6e3f..1c1f77d 100755 --- a/app/jitsi/build/jitsi-conference-focus/jicofo +++ b/app/jitsi/build/jitsi-conference-focus/jicofo @@ -8,7 +8,14 @@ ${JITSI_PROSODY_HOST} jitsi.deuxfleurs.fr conference.jitsi.deuxfleurs.fr jitsi-v 127.0.0.1 `hostname` EOF -/srv/jicofo/jicofo.sh \ +exec java \ + -Xmx400m \ + -XX:+HeapDumpOnOutOfMemoryError \ + -XX:HeapDumpPath=/tmp \ + -Djdk.tls.ephemeralDHKeySize=2048 \ + -Djava.util.logging.config.file=/srv/jicofo/lib/logging.properties \ + -cp "/usr/share/jicofo/*:/usr/share/jicofo/lib/*" \ + org.jitsi.jicofo.Main \ --host=${JITSI_PROSODY_HOST} \ --domain=jitsi.deuxfleurs.fr \ --secret=${JITSI_SECRET_JICOFO_COMPONENT} \ diff --git a/app/jitsi/build/jitsi-conference-focus/sip-communicator.properties b/app/jitsi/build/jitsi-conference-focus/sip-communicator.properties deleted file mode 100644 index 53c32e2..0000000 --- a/app/jitsi/build/jitsi-conference-focus/sip-communicator.properties +++ /dev/null @@ -1,2 +0,0 @@ -org.jitsi.jicofo.SHORT_ID=1 -org.jitsi.jicofo.BRIDGE_MUC=JvbBrewery@internal.auth.jitsi.deuxfleurs.fr diff --git a/app/jitsi/integration/README.md b/app/jitsi/integration/README.md index 70b59fc..8d81150 100644 --- a/app/jitsi/integration/README.md +++ b/app/jitsi/integration/README.md @@ -1,26 +1,9 @@ -This installation is inspired by: https://github.com/jitsi/jitsi-meet/blob/master/doc/manual-install.md +Extract conf templates: -To build images: +```bash +sudo docker-compose run jitsi-conference-focus bash -c \ + 'apt-get update && apt-get install -y unzip && unzip /srv/jicofo/jicofo.jar && cat reference.conf' -``` -docker-compose -f 02_run.yml build -``` - -To gen the certs: - -``` -docker-compose -f 01_gen_certs.yml up --force-recreate -``` - -To run the stack: - - -``` -docker-compose -f 02_run.yml up --force-recreate -``` - -To push the stack on the docker registry: - -``` -docker-compose -f 02_run.yml push +sudo docker-compose run jitsi-videobridge bash -c \ + 'apt-get update && apt-get install -y unzip && unzip /srv/jvb/jitsi-videobridge.jar && cat reference.conf' ``` diff --git a/app/jitsi/integration/jicofo.conf b/app/jitsi/integration/jicofo.conf new file mode 100644 index 0000000..ecf45fc --- /dev/null +++ b/app/jitsi/integration/jicofo.conf @@ -0,0 +1,273 @@ +jicofo { + // Authentication with external services + authentication { + enabled = false + // The type of authentication. Supported values are XMPP, JWT or SHIBBOLETH (default). + type = SHIBBOLETH + + // The pattern of authentication URL. See ShibbolethAuthAuthority for more information. + # login-url = + + # logout-url = + + authentication-lifetime = 24 hours + enable-auto-login = true + } + // Configuration related to jitsi-videobridge + bridge { + // The maximum number of participants in a single conference to put on one bridge (use -1 for no maximum). + max-bridge-participants = -1 + // The assumed maximum packet rate that a bridge can handle. + max-bridge-packet-rate = 50000 + // The assumed average packet rate per participant. + average-participant-packet-rate-pps = 500 + // The assumed average stress per participant. + average-participant-stress = 0.01 + // The assumed time that an endpoint takes to start contributing fully to the load on a bridge. To avoid allocating + // a burst of endpoints to the same bridge, the bridge stress is adjusted by adding the number of new endpoints + // in the last [participant-rampup-time] multiplied by [average-participant-stress]. + participant-rampup-interval = 20 seconds + // The stress level above which a bridge is considered overstressed. + stress-threshold = 0.8 + // The amount of to wait before retrying using a failed bridge. + failure-reset-threshold = 1 minute + // The bridge selection strategy. The built-in strategies are: + // SingleBridgeSelectionStrategy: Use the least loaded bridge, do not split a conference between bridges (Octo). + // SplitBridgeSelectionStrategy: Use a separate bridge for each participant (for testing). + // RegionBasedBridgeSelectionStrategy: Attempt to put each participant in a bridge in their local region (i.e. use + // Octo for geo-location). + // IntraRegionBridgeSelectionStrategy: Use additional bridges when a bridge becomes overloaded (i.e. use Octo for + // load balancing). + // + // Additionally, you can use the fully qualified class name for custom BridgeSelectionStrategy implementations. + selection-strategy = SingleBridgeSelectionStrategy + health-checks { + // Whether jicofo should perform periodic health checks to the connected bridges. + enabled = true + // The interval at which to perform health checks. + interval = 10 seconds + // When a health checks times out, jicofo will retry and only consider it fail after the retry fails. This + // configures the delay between the original health check timing out and the second health check being sent. + // It is a duration and defaults to half the [interval]. + # retry-delay = 5 seconds + } + + // The JID of the MUC to be used as a brewery for bridge instances. + brewery-jid = jvbbrewery@example.com + } + // Configure the codecs and RTP extensions to be used in the offer sent to clients. + codec { + video { + vp8 { + enabled = true + pt = 100 + // Payload type for the associated RTX stream. Set to -1 to disable RTX. + rtx-pt = 96 + } + vp9 { + enabled = true + pt = 101 + // Payload type for the associated RTX stream. Set to -1 to disable RTX. + rtx-pt = 97 + } + h264 { + enabled = true + pt = 107 + // Payload type for the associated RTX stream. Set to -1 to disable RTX. + rtx-pt = 99 + } + } + + audio { + isac-16000 { + enabled = true + pt = 103 + } + isac-32000 { + enabled = true + pt = 104 + } + opus { + enabled = true + pt = 111 + minptime = 10 + use-inband-fec = true + red { + enabled = false + pt = 112 + } + } + telephone-event { + enabled = true + pt = 126 + } + } + + // RTP header extensions + rtp-extensions { + audio-level { + enabled = true + id = 1 + } + tof { + // TOF is currently disabled, because we don't support it in the bridge + // (and currently clients seem to not use it when abs-send-time is + // available). + enabled = false + id = 2 + } + abs-send-time { + enabled = true + id = 3 + } + rid { + enabled = false + id = 4 + } + tcc { + enabled = true + id = 5 + } + video-content-type { + enabled = false + id = 7 + } + framemarking { + enabled = false + id = 9 + } + } + } + + conference { + // Whether to automatically grant the 'owner' role to the first participant in the conference (and subsequently to + // the next in line when the current owner leaves). + enable-auto-owner = true + + // How long to wait for the initial participant in a conference. + initial-timeout = 15 seconds + + // Whether jicofo should inject a random SSRC for endpoints which don't advertise any SSRCs. This is a temporary + // workaround for an issue with signaling endpoints for Octo. + inject-ssrc-for-recv-only-endpoints = false + + max-ssrcs-per-user = 20 + + // How long a participant's media session will be kept alive once it remains the only participant in the room. + single-participant-timeout = 20 seconds + + // The minimum number of participants required for the conference to be started. + min-participants = 2 + + // Experimental. + enable-lip-sync = false + + shared-document { + // If `true` the shared document uses a random name. Otherwise, it uses the conference name. + use-random-name = false + } + } + + // Configuration for the internal health checks performed by jicofo. + health { + // Whether to perform health checks. + enabled = false + + // The interval between health checks. If set to 0, periodic health checks will not be performed. + interval = 10 seconds + + # The timeout for a health check + timeout = 30 seconds + + # If performing a health check takes longer than this, it is considered unsuccessful. + max-check-duration = 20 seconds + + # The prefix to use when creating MUC rooms for the purpose of health checks. + room-name-prefix = "__jicofo-health-check" + } + + jibri { + // The JID of the MUC to be used as a brewery for jibri instances for streaming. + # brewery-jid = "jibribrewery@example.com" + + // How many times to retry a given Jibri request before giving up. Set to -1 to allow infinite retries. + num-retries = 5 + + // How long to wait for Jibri to start recording from the time it accepts a START request. + pending-timeout = 90 seconds + } + + jibri-sip { + // The JID of the MUC to be used as a brewery for jibri instances for SIP. + # brewery-jid = "jibrisipbrewery@example.com" + } + + jigasi { + // The JID of the MUC to be used as a brewery for jigasi instances. + # brewery-jid = "jigasibrewery@example.com" + } + + // The region in which the machine is running. + #local-region="us-east-1" + + octo { + // Whether or not to use Octo. Note that when enabled, its use will be determined by + // $jicofo.bridge.selection-strategy. + enabled = true + + // An identifier of the Jicofo instance, used for the purpose of generating conference IDs unique across a set of + // Jicofo instances. Valid values are [1, 65535]. The value 0 is used when none is explicitly configured. + #id = 1234 + } + + rest { + port = 8888 + tls-port = 8843 + } + + sctp { + // Whether to allocate SCTP channels on the bridge (only when the client advertises support, and SCTP is + // enabled in the per-conference configuration). + enabled = true + } + + task-pools { + shared-pool-max-threads = 1500 + } + + xmpp { + // The separate XMPP connection used for communication with clients (endpoints). + client { + enabled = true + hostname = "localhost" + port = 5222 + #domain = + username = "focus" + #password = + + // How long to wait for a response to a stanza before giving up. + reply-timeout = 15 seconds + + // The JID/domain of the MUC service used for conferencing. + # conference-muc-jid = conference.example.com + + // A flag to suppress the TLS certificate verification. + disable-certificate-verification = false + } + // The separate XMPP connection used for internal services (currently only jitsi-videobridge). + service { + enabled = false + hostname = "localhost" + port = 6222 + #domain = + #username = + #password = + + // How long to wait for a response to a stanza before giving up. + reply-timeout = 15 seconds + + // A flag to suppress the TLS certificate verification. + disable-certificate-verification = false + } + } +} diff --git a/app/jitsi/integration/videobridge.conf b/app/jitsi/integration/videobridge.conf new file mode 100644 index 0000000..2e2548b --- /dev/null +++ b/app/jitsi/integration/videobridge.conf @@ -0,0 +1,279 @@ +videobridge { + entity-expiration { + # If an entity has no activity after this timeout, it is expired + timeout=1 minute + + # The interval at which the videobridge will check for expired entities + check-interval=${videobridge.entity-expiration.timeout} + } + health { + # The interval between health checks + interval=10 seconds + + # The timeout for a health check + timeout=30 seconds + + # If performing a health check takes longer than this, it is considered unsuccessful. + max-check-duration=3 seconds + + # Whether or not health check failures should be 'sticky' + # (i.e. once the bridge becomes unhealthy, it will never + # go back to a healthy state) + sticky-failures=false + } + ep-connection-status { + # How long we'll wait for an endpoint to *start* sending + # data before we consider it 'inactive' + first-transfer-timeout=15 seconds + + # How long an endpoint can be 'inactive' before it will + # be considered disconnected + max-inactivity-limit=3 seconds + + # How often we check endpoint's connectivity status + check-interval=500 milliseconds + } + cc { + bwe-change-threshold=0.15 + thumbnail-max-height-px=180 + onstage-ideal-height-px=1080 + onstage-preferred-height-px=360 + onstage-preferred-framerate=30 + enable-onstage-video-suspend=false + trust-bwe=true + + # How often we check to send probing data + padding-period=15ms + + # How often we'll force recalculations of forwarded + # streams + max-time-between-calculations = 15 seconds + + # A JVB-wide last-n value, observed by all endpoints. Endpoints + # will take the minimum of their setting and this one (-1 implies + # no last-n limit) + jvb-last-n = -1 + } + # The APIs by which the JVB can be controlled + apis { + xmpp-client { + # The interval at which presence is published in the configured MUCs. + presence-interval = ${videobridge.stats.interval} + + configs { + # example-connection-id { + # For the properties which should be + # filled out here, see MucClientConfiguration + # } + } + } + # The COLIBRI REST API + rest { + enabled = false + } + jvb-api { + enabled = false + } + } + # Configuration of the different REST APIs. + # Note that the COLIBRI REST API is configured under videobridge.apis.rest instead. + rest { + debug { + enabled = true + } + health { + enabled = true + } + shutdown { + # Note that the shutdown API requires the COLIBRI API to also be enabled. + enabled = false + } + version { + enabled = true + } + } + http-servers { + # The HTTP server which hosts services intended for 'public' use + # (e.g. websockets for the bridge channel connection) + public { + # See JettyBundleActivatorConfig in Jicoco for values + port = -1 + tls-port = -1 + } + # The HTTP server which hosts services intended for 'private' use + # (e.g. health or debug stats) + private { + # See JettyBundleActivatorConfig in Jicoco for values + host = 127.0.0.1 + } + } + octo { + # Whether or not Octo is enabled + enabled=false + + # A string denoting the 'region' of this JVB. This region + # will be used by Jicofo in the selection of a bridge for + # a client by comparing it to the client's region. + # Must be set when 'enabled' is true + #region="us-west-1" + + # The address on which the Octo relay should bind + # Must be set when 'enabled' is true + #bind-address=198.51.100.1 + + # The port to which the Octo relay should bind + bind-port=4096 + + # The address which controls the public address which + # will be part of the Octo relayId + #public-address=198.51.100.1 + + # The size of the incoming octo queue. This queue is per-remote-endpoint, + # so it matches what we use for local endpoints + recv-queue-size=1024 + + # The size of the outgoing octo queue. This is a per-originating-endpoint + # queue, so assuming all packets are routed (as they currently are for Octo) + # it should be the same size as the transceiver recv queue in + # jitsi-media-transform. Repeating the description from there: + # Assuming 300pps for high-definition, 200pps for standard-definition, + # 100pps for low-definition and 50pps for audio, this queue is fed + # 650pps, so its size in terms of millis is 1024/650*1000 ~= 1575ms. + send-queue-size=1024 + } + load-management { + # Whether or not the reducer will be enabled to take actions to mitigate load + reducer-enabled = false + load-measurements { + packet-rate { + # The packet rate at which we'll consider the bridge overloaded + load-threshold = 50000 + # The packet rate at which we'll consider the bridge 'underloaded' enough + # to start recovery + recovery-threshold = 40000 + } + } + load-reducers { + last-n { + # The factor by which we'll reduce the current last-n when trying to reduce load + reduction-scale = .75 + # The factor by which we'll increase the current last-n when trying to recover + recover-scale = 1.25 + # The minimum time in between runs of the last-n reducer to reduce or recover from + # load + impact-time = 1 minute + # The lowest value we'll set for last-n + minimum-last-n-value = 0 + # The highest last-n value we'll enforce. Once the enforced last-n exceeds this value + # we'll remove the limit entirely + maximum-enforced-last-n-value = 40 + } + } + } + sctp { + # Whether SCTP data channels are enabled. + enabled=true + } + stats { + # Whether periodic collection of statistics is enabled or not. When enabled they are accessible through the REST + # API (at `/colibri/stats`), and are available to other modules (e.g. to be pushed to callstats or in a MUC). + enabled = false + + # The interval at which stats are gathered. + interval = 5 seconds + + # Configuration related to pushing statistics to callstats.io. + callstats { + # An integer application ID (use 0 to disable pushing stats to callstats). + app-id = 0 + + # The shared secred to authentication with callstats.io. + //app-secret = "s3cret" + + # ID of the key that was used to generate token. + //key-id = "abcd" + + # The path to private key file. + //key-path = "/etc/jitsi/videobridge/ecpriv.jwk" + + # The ID of the server instance to be used when reporting to callstats. + bridge-id = "jitsi" + + # TODO: document + //conference-id-prefix = "abcd" + + # The interval at which statististics will be published to callstats. This affects both per-conference and global + # statistics. + # Note that this value will be overriden if a "callstatsio" transport is defined in the parent "stats" section. + interval = ${videobridge.stats.interval} + } + } + websockets { + enabled=false + server-id="default-id" + + # Optional, even when 'enabled' is set to true + # tls=true + # Must be set when enabled = true + #domain="some-domain" + } + ice { + tcp { + # Whether ICE/TCP is enabled. + enabled = false + + # The port to bind to for ICE/TCP. + port = 443 + + # An optional additional port to advertise. + # mapped-port = 8443 + # Whether to use "ssltcp" or plain "tcp". + ssltcp = true + } + + udp { + # The port for ICE/UDP. + port = 10000 + } + + # An optional prefix to include in STUN username fragments generated by the bridge. + #ufrag-prefix = "jvb-123:" + + # Which candidate pairs to keep alive. The accepted values are defined in ice4j's KeepAliveStrategy: + # "selected_and_tcp", "selected_only", or "all_succeeded". + keep-alive-strategy = "selected_and_tcp" + + # Whether to use the "component socket" feature of ice4j. + use-component-socket = true + + # Whether to attempt DNS resolution for remote candidates that contain a non-literal address. When set to 'false' + # such candidates will be ignored. + resolve-remote-candidates = false + + # The nomination strategy to use for ICE. THe accepted values are defined in ice4j's NominationStrategy: + # "NominateFirstValid", "NominateHighestPriority", "NominateFirstHostOrReflexiveValid", or "NominateBestRTT". + nomination-strategy = "NominateFirstValid" + } + + transport { + send { + # The size of the dtls-transport outgoing queue. This is a per-participant + # queue. Packets from the egress end-up in this queue right before + # transmission by the outgoing srtp pipeline (which mainly consists of the + # packet sender). + # + # Its size needs to be of the same order of magnitude as the rtp sender + # queue. In a 100 participant call, assuming 300pps for the on-stage and + # 100pps for low-definition, last-n 20 and 2 participants talking, so + # 2*50pps for audio, this queue is fed 300+19*100+2*50 = 2300pps, so its + # size in terms of millis is 1024/2300*1000 ~= 445ms. + queue-size=1024 + } + } + + version { + // Wheather to announe the jitsi-videobridge version to clients in the ServerHello message. + announce = false + } +} +