diff --git a/.github/workflows/build-test-and-deploy.yml b/.github/workflows/build-test-and-deploy.yml index eacf046174..57803800c1 100644 --- a/.github/workflows/build-test-and-deploy.yml +++ b/.github/workflows/build-test-and-deploy.yml @@ -40,7 +40,7 @@ jobs: id: meta uses: docker/metadata-action@v3 with: - images: thecodingmachine/workadventure-front + images: mconf/workadventure-front - name: Build and push uses: docker/build-push-action@v3 @@ -50,8 +50,8 @@ jobs: file: front/Dockerfile platforms: linux/amd64,linux/arm64 push: true - tags: thecodingmachine/workadventure-front:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} - cache-from: type=registry,ref=thecodingmachine/workadventure-front:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + tags: mconf/workadventure-front:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + cache-from: type=registry,ref=mconf/workadventure-front:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} cache-to: type=inline labels: ${{ steps.meta.outputs.labels }} @@ -101,7 +101,7 @@ jobs: id: meta uses: docker/metadata-action@v3 with: - images: thecodingmachine/workadventure-chat + images: mconf/workadventure-chat - name: Build and push uses: docker/build-push-action@v3 @@ -111,8 +111,8 @@ jobs: file: front/chat/Dockerfile platforms: linux/amd64,linux/arm64 push: true - tags: thecodingmachine/workadventure-chat:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} - cache-from: type=registry,ref=thecodingmachine/workadventure-chat:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + tags: mconf/workadventure-chat:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + cache-from: type=registry,ref=mconf/workadventure-chat:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} cache-to: type=inline labels: ${{ steps.meta.outputs.labels }} @@ -162,7 +162,7 @@ jobs: id: meta uses: docker/metadata-action@v3 with: - images: thecodingmachine/workadventure-back + images: mconf/workadventure-back - name: Build and push uses: docker/build-push-action@v3 @@ -172,8 +172,8 @@ jobs: file: back/Dockerfile platforms: linux/amd64,linux/arm64 push: true - tags: thecodingmachine/workadventure-back:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} - cache-from: type=registry,ref=thecodingmachine/workadventure-back:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + tags: mconf/workadventure-back:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + cache-from: type=registry,ref=mconf/workadventure-back:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} cache-to: type=inline labels: ${{ steps.meta.outputs.labels }} @@ -223,7 +223,7 @@ jobs: id: meta uses: docker/metadata-action@v3 with: - images: thecodingmachine/workadventure-pusher + images: mconf/workadventure-pusher - name: Build and push uses: docker/build-push-action@v3 @@ -233,8 +233,8 @@ jobs: file: pusher/Dockerfile platforms: linux/amd64,linux/arm64 push: true - tags: thecodingmachine/workadventure-pusher:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} - cache-from: type=registry,ref=thecodingmachine/workadventure-pusher:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + tags: mconf/workadventure-pusher:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + cache-from: type=registry,ref=mconf/workadventure-pusher:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} cache-to: type=inline labels: ${{ steps.meta.outputs.labels }} @@ -280,7 +280,7 @@ jobs: id: meta uses: docker/metadata-action@v3 with: - images: thecodingmachine/workadventure-uploader + images: mconf/workadventure-uploader - name: Build and push uses: docker/build-push-action@v3 @@ -288,8 +288,8 @@ jobs: with: file: uploader/Dockerfile push: true - tags: thecodingmachine/workadventure-uploader:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} - cache-from: type=registry,ref=thecodingmachine/workadventure-uploader:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + tags: mconf/workadventure-uploader:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + cache-from: type=registry,ref=mconf/workadventure-uploader:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} cache-to: type=inline labels: ${{ steps.meta.outputs.labels }} @@ -336,7 +336,7 @@ jobs: id: meta uses: docker/metadata-action@v3 with: - images: thecodingmachine/workadventure-maps + images: mconf/workadventure-maps - name: Build and push uses: docker/build-push-action@v3 @@ -345,8 +345,8 @@ jobs: context: maps/ file: maps/Dockerfile push: true - tags: thecodingmachine/workadventure-maps:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} - cache-from: type=registry,ref=thecodingmachine/workadventure-maps:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + tags: mconf/workadventure-maps:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + cache-from: type=registry,ref=mconf/workadventure-maps:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} cache-to: type=inline labels: ${{ steps.meta.outputs.labels }} @@ -395,7 +395,7 @@ jobs: id: meta uses: docker/metadata-action@v3 with: - images: thecodingmachine/workadventure-map-storage + images: mconf/workadventure-map-storage - name: Build and push uses: docker/build-push-action@v3 @@ -405,8 +405,8 @@ jobs: file: map-storage/Dockerfile platforms: linux/amd64,linux/arm64 push: true - tags: thecodingmachine/workadventure-map-storage:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} - cache-from: type=registry,ref=thecodingmachine/workadventure-map-storage:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + tags: mconf/workadventure-map-storage:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + cache-from: type=registry,ref=mconf/workadventure-map-storage:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} cache-to: type=inline labels: ${{ steps.meta.outputs.labels }} @@ -456,7 +456,7 @@ jobs: id: meta uses: docker/metadata-action@v3 with: - images: thecodingmachine/workadventure-simple-ecs + images: mconf/workadventure-simple-ecs - name: Build and push uses: docker/build-push-action@v3 @@ -465,8 +465,8 @@ jobs: context: xmpp/ platforms: linux/amd64,linux/arm64 push: true - tags: thecodingmachine/workadventure-simple-ecs:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} - cache-from: type=registry,ref=thecodingmachine/workadventure-simple-ecs:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + tags: mconf/workadventure-simple-ecs:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} + cache-from: type=registry,ref=mconf/workadventure-simple-ecs:${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} cache-to: type=inline labels: ${{ steps.meta.outputs.labels }} @@ -657,82 +657,3 @@ jobs: path: tests/playwright-report/ retention-days: 30 - deeploy: - needs: - - build-front - - build-chat - - build-back - - build-pusher - - build-maps - - build-uploader - - build-map-storage - - build-ejabberd - runs-on: ubuntu-latest - if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }} - - steps: - - name: Checkout - uses: actions/checkout@v2 - - # Create a slugified value of the branch - - uses: rlespinasse/github-slug-action@3.1.0 - - - name: Set ADMIN_URL if "deploy-connect-to-admin" label is set - run: echo "ADMIN_API_URL=https://${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}.test.workadventu.re" >> $GITHUB_ENV - if: ${{ (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy-connect-to-admin')) || env.GITHUB_REF_SLUG == 'develop' }} - - - name: Write certificate - run: echo "${CERTS_PRIVATE_KEY}" > secret.key && chmod 0600 secret.key - env: - CERTS_PRIVATE_KEY: ${{ secrets.CERTS_PRIVATE_KEY }} - - - name: Download certificate - run: mkdir secrets && scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i secret.key ubuntu@cert.workadventu.re:./config/live/workadventu.re/* secrets/ - - - name: Create namespace - uses: steebchen/kubectl@v1.0.0 - env: - KUBE_CONFIG_DATA: ${{ secrets.KUBE_CONFIG_FILE_BASE64 }} - with: - args: create namespace workadventure-${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} - continue-on-error: true - - - name: Delete old certificates in namespace - uses: steebchen/kubectl@v1.0.0 - env: - KUBE_CONFIG_DATA: ${{ secrets.KUBE_CONFIG_FILE_BASE64 }} - with: - args: -n workadventure-${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} delete secret certificate-tls - continue-on-error: true - - - name: Install certificates in namespace - uses: steebchen/kubectl@v1.0.0 - env: - KUBE_CONFIG_DATA: ${{ secrets.KUBE_CONFIG_FILE_BASE64 }} - with: - args: -n workadventure-${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} create secret tls certificate-tls --key="secrets/privkey.pem" --cert="secrets/fullchain.pem" - - - name: Deploy - uses: thecodingmachine/deeployer-action@master - env: - KUBE_CONFIG_FILE: ${{ secrets.KUBE_CONFIG_FILE }} - ADMIN_API_TOKEN: ${{ secrets.ADMIN_API_TOKEN }} - ADMIN_SOCKETS_TOKEN: ${{ secrets.ADMIN_SOCKETS_TOKEN }} - JITSI_ISS: ${{ secrets.JITSI_ISS }} - JITSI_URL: ${{ secrets.JITSI_URL }} - SECRET_JITSI_KEY: ${{ secrets.SECRET_JITSI_KEY }} - TURN_STATIC_AUTH_SECRET: ${{ secrets.TURN_STATIC_AUTH_SECRET }} - DEPLOY_REF: ${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} - POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} - POSTHOG_URL: ${{ secrets.POSTHOG_URL }} - EJABBERD_JWT_SECRET: ${{ secrets.EJABBERD_JWT_SECRET }} - with: - namespace: workadventure-${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }} - - - name: Add a comment in PR - uses: unsplash/comment-on-pr@master - if: ${{ github.event_name == 'pull_request' }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - msg: "Environment deployed at https://play-${{ env.GITHUB_HEAD_REF_SLUG }}.test.workadventu.re \nTests available at https://maps-${{ env.GITHUB_HEAD_REF_SLUG }}.test.workadventu.re/tests" diff --git a/docker-compose.yaml b/docker-compose.yaml index c60938a00d..9d09e5d3e2 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -63,6 +63,8 @@ services: ENABLE_OPENID: "$OPID_CLIENT_ID" OPID_PROFILE_SCREEN_PROVIDER: "$OPID_PROFILE_SCREEN_PROVIDER" CHAT_URL: //chat.workadventure.localhost + PEER_VIDEO_MAX_BANDWIDTH_KBITS_PS: "$PEER_VIDEO_MAX_BANDWIDTH_KBITS_PS" + PEER_SCREENSHARE_MAX_BANDWIDTH_KBITS_PS: "$PEER_SCREENSHARE_MAX_BANDWIDTH_KBITS_PS" command: yarn run start volumes: - ./front:/usr/src/app diff --git a/front/src/Components/Video/utils.ts b/front/src/Components/Video/utils.ts index b97f5015e3..ce671bad95 100644 --- a/front/src/Components/Video/utils.ts +++ b/front/src/Components/Video/utils.ts @@ -63,3 +63,44 @@ export function getIceServersConfig(user: UserSimplePeerInterface): RTCIceServer } return config; } + +export function getSdpTransform(videoBandwidth = 0) { + return (sdp: string) => { + sdp = updateBandwidthRestriction(sdp, videoBandwidth, "video"); + + return sdp; + }; +} + +function updateBandwidthRestriction(sdp: string, bandwidth: integer, mediaType: string): string { + if (bandwidth <= 0) { + return sdp; + } + + for ( + let targetMediaPos = sdp.indexOf(`m=${mediaType}`); + targetMediaPos !== -1; + targetMediaPos = sdp.indexOf(`m=${mediaType}`, targetMediaPos + 1) + ) { + // offer TIAS and AS (in this order) + for (const modifier of ["AS", "TIAS"]) { + const nextMediaPos = sdp.indexOf(`m=`, targetMediaPos + 1); + const newBandwidth = modifier === "TIAS" ? (bandwidth >>> 0) * 1000 : bandwidth; + const nextBWPos = sdp.indexOf(`b=${modifier}:`, targetMediaPos + 1); + + let mediaSlice = sdp.slice(targetMediaPos); + const bwFieldAlreadyExists = nextBWPos !== -1 && (nextBWPos < nextMediaPos || nextMediaPos === -1); + if (bwFieldAlreadyExists) { + // delete it + mediaSlice = mediaSlice.replace(new RegExp(`b=${modifier}:.*[\r?\n]`), ""); + } + // insert b= after c= line. + mediaSlice = mediaSlice.replace(/c=IN (.*)(\r?\n)/, `c=IN $1$2b=${modifier}:${newBandwidth}$2`); + + // update the sdp + sdp = sdp.slice(0, targetMediaPos) + mediaSlice; + } + } + + return sdp; +} diff --git a/front/src/Enum/EnvironmentVariable.ts b/front/src/Enum/EnvironmentVariable.ts index 864763392b..03d9454d83 100644 --- a/front/src/Enum/EnvironmentVariable.ts +++ b/front/src/Enum/EnvironmentVariable.ts @@ -30,6 +30,10 @@ export const OPID_PROFILE_SCREEN_PROVIDER = getEnvConfig("OPID_PROFILE_SCREEN_PROVIDER") || (ADMIN_URL ? ADMIN_URL + "/profile" : undefined); const FALLBACK_LOCALE = getEnvConfig("FALLBACK_LOCALE") || undefined; export const CHAT_URL = getEnvConfig("CHAT_URL") || "//chat.workadventure.localhost"; +const PEER_VIDEO_MAX_BANDWIDTH_KBITS_PS = parseInt(getEnvConfig("PEER_VIDEO_MAX_BANDWIDTH_KBITS_PS") || "0"); +const PEER_SCREENSHARE_MAX_BANDWIDTH_KBITS_PS = parseInt( + getEnvConfig("PEER_SCREENSHARE_MAX_BANDWIDTH_KBITS_PS") || "0" +); export { DEBUG_MODE, @@ -48,4 +52,6 @@ export { JITSI_PRIVATE_MODE, ENABLE_FEATURE_MAP_EDITOR, FALLBACK_LOCALE, + PEER_VIDEO_MAX_BANDWIDTH_KBITS_PS, + PEER_SCREENSHARE_MAX_BANDWIDTH_KBITS_PS, }; diff --git a/front/src/WebRtc/ScreenSharingPeer.ts b/front/src/WebRtc/ScreenSharingPeer.ts index 7cfd8c92e9..a4fde8d3cc 100644 --- a/front/src/WebRtc/ScreenSharingPeer.ts +++ b/front/src/WebRtc/ScreenSharingPeer.ts @@ -2,11 +2,12 @@ import type { RoomConnection } from "../Connexion/RoomConnection"; import { MESSAGE_TYPE_CONSTRAINT, PeerStatus } from "./VideoPeer"; import type { UserSimplePeerInterface } from "./SimplePeer"; import { Readable, readable, writable, Writable } from "svelte/store"; -import { getIceServersConfig } from "../Components/Video/utils"; +import { getIceServersConfig, getSdpTransform } from "../Components/Video/utils"; import { highlightedEmbedScreen } from "../Stores/EmbedScreensStore"; import { isMediaBreakpointUp } from "../Utils/BreakpointsUtils"; import Peer from "simple-peer/simplepeer.min.js"; import { Buffer } from "buffer"; +import { PEER_SCREENSHARE_MAX_BANDWIDTH_KBITS_PS } from "../Enum/EnvironmentVariable"; /** * A peer connection used to transmit video / audio signals between 2 peers. @@ -35,6 +36,7 @@ export class ScreenSharingPeer extends Peer { config: { iceServers: getIceServersConfig(user), }, + sdpTransform: getSdpTransform(PEER_SCREENSHARE_MAX_BANDWIDTH_KBITS_PS), }); this.userId = user.userId; diff --git a/front/src/WebRtc/VideoPeer.ts b/front/src/WebRtc/VideoPeer.ts index 5fa07ae665..4e271fce21 100644 --- a/front/src/WebRtc/VideoPeer.ts +++ b/front/src/WebRtc/VideoPeer.ts @@ -12,12 +12,13 @@ import { newChatMessageWritingStatusSubject, writingStatusMessageStore, } from "../Stores/ChatStore"; -import { getIceServersConfig } from "../Components/Video/utils"; +import { getIceServersConfig, getSdpTransform } from "../Components/Video/utils"; import { isMediaBreakpointUp } from "../Utils/BreakpointsUtils"; import { SoundMeter } from "../Phaser/Components/SoundMeter"; import Peer from "simple-peer/simplepeer.min.js"; import { Buffer } from "buffer"; import { gameManager } from "../Phaser/Game/GameManager"; +import { PEER_VIDEO_MAX_BANDWIDTH_KBITS_PS } from "../Enum/EnvironmentVariable"; export type PeerStatus = "connecting" | "connected" | "error" | "closed"; @@ -60,6 +61,7 @@ export class VideoPeer extends Peer { config: { iceServers: getIceServersConfig(user), }, + sdpTransform: getSdpTransform(PEER_VIDEO_MAX_BANDWIDTH_KBITS_PS), }); this.userId = user.userId; diff --git a/front/tests/Components/Video/UtilsTest.ts b/front/tests/Components/Video/UtilsTest.ts new file mode 100644 index 0000000000..a88b8cce69 --- /dev/null +++ b/front/tests/Components/Video/UtilsTest.ts @@ -0,0 +1,133 @@ +import "jasmine"; + +import { getSdpTransform } from "../../../src/Components/Video/utils"; + +describe("getSdpTransform()", () => { + it("should not do anything if bandwidth = 0", () => { + const bw = 0; + const originalSdp = ` + m=audio + c=IN IP4 0.0.0.0 + b=AS:11 + m=video + c=IN IP4 0.0.0.0 + m=video + c=IN IP4 0.0.0.0 + b=AS:22 + m=application + c=IN IP4 0.0.0.0 + b=AS:33`.replace(/^[\s]*/gm, ""); + + const modifiedSdp = getSdpTransform(bw)(originalSdp); + expect(modifiedSdp).toEqual(originalSdp); + }); + + it("should create the 'b' field of the video media if it doesn't exist", () => { + const bw = 55; + const originalSdp = ` + m=audio + c=IN IP4 0.0.0.0 + m=video + c=IN IP4 0.0.0.0 + m=video + c=IN IP4 0.0.0.0 + m=application + c=IN IP4 0.0.0.0`.replace(/^[\s]*/gm, ""); + + const modifiedSdp = getSdpTransform(bw)(originalSdp); + expect(modifiedSdp).toEqual(expectedDefaultSdp(bw)); + }); + + it("should update the 'b' field of the video media if it already exists", () => { + const bw = 66; + const originalSdp = ` + m=audio + c=IN IP4 0.0.0.0 + m=video + c=IN IP4 0.0.0.0 + b=AS:11 + m=video + c=IN IP4 0.0.0.0 + b=AS:22 + m=application + c=IN IP4 0.0.0.0`.replace(/^[\s]*/gm, ""); + + const modifiedSdp = getSdpTransform(bw)(originalSdp); + expect(modifiedSdp).toEqual(expectedDefaultSdp(bw)); + }); + + it("should create and update the 'b' field of each video media if one doesn't exist and the other does", () => { + const bw = 77; + const originalSdp = ` + m=audio + c=IN IP4 0.0.0.0 + m=video + c=IN IP4 0.0.0.0 + b=AS:11 + m=video + c=IN IP4 0.0.0.0 + m=application + c=IN IP4 0.0.0.0`.replace(/^[\s]*/gm, ""); + + const modifiedSdp = getSdpTransform(bw)(originalSdp); + expect(modifiedSdp).toEqual(expectedDefaultSdp(bw)); + }); + + it("should not change the 'b' field of other medias", () => { + const bw = 88; + const originalSdp = ` + m=audio + c=IN IP4 0.0.0.0 + b=AS:11 + m=video + c=IN IP4 0.0.0.0 + b=AS:22 + m=video + c=IN IP4 0.0.0.0 + b=AS:33 + m=application + c=IN IP4 0.0.0.0 + b=AS:44`.replace(/^[\s]*/gm, ""); + + const modifiedSdp = getSdpTransform(bw)(originalSdp); + expect(modifiedSdp).toEqual(expectedFullBWSdp(bw)); + }); + + // Expected sdp where the audio and application medias have no 'b' fields + // and the video medias should have 'b=TIAS=:' and 'b=AS:'. + const expectedDefaultSdp = (bw: integer) => { + return ` + m=audio + c=IN IP4 0.0.0.0 + m=video + c=IN IP4 0.0.0.0 + b=TIAS:${bw * 1000} + b=AS:${bw} + m=video + c=IN IP4 0.0.0.0 + b=TIAS:${bw * 1000} + b=AS:${bw} + m=application + c=IN IP4 0.0.0.0`.replace(/^[\s]*/gm, ""); + }; + + // Expected sdp where the audio and application medias have a 'b' field + // and the video medias should have 'b=TIAS=:' and 'b=AS:'. + const expectedFullBWSdp = (bw: integer) => { + return ` + m=audio + c=IN IP4 0.0.0.0 + b=AS:11 + m=video + c=IN IP4 0.0.0.0 + b=TIAS:${bw * 1000} + b=AS:${bw} + m=video + c=IN IP4 0.0.0.0 + b=TIAS:${bw * 1000} + b=AS:${bw} + m=application + c=IN IP4 0.0.0.0 + b=AS:44`.replace(/^[\s]*/gm, ""); + }; +}); diff --git a/front/vite.config.ts b/front/vite.config.ts index 9a05e8b7b2..0d28809248 100644 --- a/front/vite.config.ts +++ b/front/vite.config.ts @@ -47,6 +47,8 @@ export default defineConfig({ "OPID_PROFILE_SCREEN_PROVIDER", "FALLBACK_LOCALE", "CHAT_URL", + "PEER_VIDEO_MAX_BANDWIDTH_KBITS_PS", + "PEER_SCREENSHARE_MAX_BANDWIDTH_KBITS_PS", ], }), pluginRewriteAll(),