0

Trying to deploy https://github.com/fmeringdal/nettu-meet which uses mediasoup lib. Medisoup version tried are 3.7 and 3.8

When a user turns on his/her video or audio in the meeting room then getting this message on the console "transport connstate new" and then it stays stuck in this state.

Here is the code snippet which prints the above output.

signalingChannel.on("newConsumer", async (data: any) => {
const { joined } = useRoomStore.getState();
if (!joined) return;
const {
  peerId,
  producerId,
  id,
  kind,
  rtpParameters,
  type,
  appData,
  producerPaused,
} = data;

console.log('*************', 'utils.ts - temp log to check rtpParameters, **************')
console.log(data)
console.log(rtpParameters)

const { transports } = useTransportStore.getState();
if (!transports) return;

const consumer = await transports.recv.consume({
  id,
  producerId,
  kind,
  rtpParameters,
  appData: { ...appData, peerId }, // Trick.
});

useRoomStore.getState().addConsumer(consumer);

// the server-side consumer will be started in paused state. wait
// until we're connected, then send a resume request to the server
// to get our first keyframe and start displaying video
while (transports.recv.connectionState !== "connected") {
  log("  transport connstate", transports.recv.connectionState);
  await sleep(100);
}

if (!producerPaused) {
  // okay, we're ready. let's ask the peer to send us media
  await resumeConsumer(consumer.id);
} else {
  await pauseConsumer(consumer.id);
}

consumer.on("transportclose", () => {
  closeConsumer(consumer.id);
});

Attaching below the transport related parameters in case it helps.

When the first user joins I am getting these transport options on the client.

{
"id": "2c2239b1-18e3-478c-86f3-5e3bfd31941d",
"iceParameters": {
    "iceLite": true,
    "password": "v128uo3o9ixphketku7pz9gtu7222lr6",
    "usernameFragment": "a4t3lzi3o50ckvxw"
},
"iceCandidates": [
    {
        "foundation": "udpcandidate",
        "ip": "0.0.0.0",
        "port": 44449,
        "priority": 1076558079,
        "protocol": "udp",
        "type": "host"
    },
    {
        "foundation": "tcpcandidate",
        "ip": "0.0.0.0",
        "port": 47212,
        "priority": 1076302079,
        "protocol": "tcp",
        "tcpType": "passive",
        "type": "host"
    }
],
"dtlsParameters": {
    "fingerprints": [
        {
            "algorithm": "sha-1",
            "value": "7B:A7:5D:F1:A6:EA:72:83:4B:83:21:E2:7A:8D:A1:B1:A4:8B:A6:87"
        },
        {
            "algorithm": "sha-224",
            "value": "8A:E5:5F:5C:30:34:BD:D4:75:52:B5:0A:28:1C:5C:11:6B:84:01:5F:FE:72:82:BA:C9:6F:B6:63"
        },
        {
            "algorithm": "sha-256",
            "value": "CC:D8:6A:94:DA:71:27:45:FB:1B:32:88:2C:5C:1C:26:94:6E:BF:84:47:CA:FE:41:53:5B:D7:36:D5:66:42:A0"
        },
        {
            "algorithm": "sha-384",
            "value": "FF:25:F0:2F:A5:CF:C4:D8:9E:A1:4F:D5:47:44:98:25:BE:30:12:71:53:AB:61:D1:D1:78:BA:96:65:75:7B:A5:3B:94:49:9F:61:DA:B1:C6:B9:FF:57:41:1F:2B:78:65"
        },
        {
            "algorithm": "sha-512",
            "value": "7F:D3:E0:C6:1B:D1:AB:1F:A3:35:72:7D:9C:24:91:62:BF:A0:5E:A8:1F:EE:F0:9A:1D:05:37:AD:78:B9:E8:8E:42:6E:F9:09:4B:A5:B4:66:23:26:A1:A8:DE:08:85:27:0B:3C:60:90:89:FD:3D:1F:30:73:81:F7:35:49:7D:F5"
        }
    ],
    "role": "auto"
}
} 

{
"id": "5485ff92-9bd2-4f74-9c5f-9c1873cbaedb",
"iceParameters": {
    "iceLite": true,
    "password": "hv1nyjohkworxcrpm0icbcd29hdcy98e",
    "usernameFragment": "cesy56bc7zfqg3uk"
},
"iceCandidates": [
    {
        "foundation": "udpcandidate",
        "ip": "0.0.0.0",
        "port": 41434,
        "priority": 1076558079,
        "protocol": "udp",
        "type": "host"
    },
    {
        "foundation": "tcpcandidate",
        "ip": "0.0.0.0",
        "port": 44080,
        "priority": 1076302079,
        "protocol": "tcp",
        "tcpType": "passive",
        "type": "host"
    }
],
"dtlsParameters": {
    "fingerprints": [
        {
            "algorithm": "sha-1",
            "value": "7B:A7:5D:F1:A6:EA:72:83:4B:83:21:E2:7A:8D:A1:B1:A4:8B:A6:87"
        },
        {
            "algorithm": "sha-224",
            "value": "8A:E5:5F:5C:30:34:BD:D4:75:52:B5:0A:28:1C:5C:11:6B:84:01:5F:FE:72:82:BA:C9:6F:B6:63"
        },
        {
            "algorithm": "sha-256",
            "value": "CC:D8:6A:94:DA:71:27:45:FB:1B:32:88:2C:5C:1C:26:94:6E:BF:84:47:CA:FE:41:53:5B:D7:36:D5:66:42:A0"
        },
        {
            "algorithm": "sha-384",
            "value": "FF:25:F0:2F:A5:CF:C4:D8:9E:A1:4F:D5:47:44:98:25:BE:30:12:71:53:AB:61:D1:D1:78:BA:96:65:75:7B:A5:3B:94:49:9F:61:DA:B1:C6:B9:FF:57:41:1F:2B:78:65"
        },
        {
            "algorithm": "sha-512",
            "value": "7F:D3:E0:C6:1B:D1:AB:1F:A3:35:72:7D:9C:24:91:62:BF:A0:5E:A8:1F:EE:F0:9A:1D:05:37:AD:78:B9:E8:8E:42:6E:F9:09:4B:A5:B4:66:23:26:A1:A8:DE:08:85:27:0B:3C:60:90:89:FD:3D:1F:30:73:81:F7:35:49:7D:F5"
        }
    ],
    "role": "auto"
}
}

When the second user joins the meet room, I am getting these transport options on the client.

{
"id": "4abfb816-734a-4b66-a860-2dd88fd95f8a",
"iceParameters": {
    "iceLite": true,
    "password": "ze87is9bl32vwx0ko7d8v1qgm0fk1u9h",
    "usernameFragment": "alrip3oyoaluv83n"
},
"iceCandidates": [
    {
        "foundation": "udpcandidate",
        "ip": "0.0.0.0",
        "port": 41783,
        "priority": 1076558079,
        "protocol": "udp",
        "type": "host"
    },
    {
        "foundation": "tcpcandidate",
        "ip": "0.0.0.0",
        "port": 45051,
        "priority": 1076302079,
        "protocol": "tcp",
        "tcpType": "passive",
        "type": "host"
    }
],
"dtlsParameters": {
    "fingerprints": [
        {
            "algorithm": "sha-1",
            "value": "7B:A7:5D:F1:A6:EA:72:83:4B:83:21:E2:7A:8D:A1:B1:A4:8B:A6:87"
        },
        {
            "algorithm": "sha-224",
            "value": "8A:E5:5F:5C:30:34:BD:D4:75:52:B5:0A:28:1C:5C:11:6B:84:01:5F:FE:72:82:BA:C9:6F:B6:63"
        },
        {
            "algorithm": "sha-256",
            "value": "CC:D8:6A:94:DA:71:27:45:FB:1B:32:88:2C:5C:1C:26:94:6E:BF:84:47:CA:FE:41:53:5B:D7:36:D5:66:42:A0"
        },
        {
            "algorithm": "sha-384",
            "value": "FF:25:F0:2F:A5:CF:C4:D8:9E:A1:4F:D5:47:44:98:25:BE:30:12:71:53:AB:61:D1:D1:78:BA:96:65:75:7B:A5:3B:94:49:9F:61:DA:B1:C6:B9:FF:57:41:1F:2B:78:65"
        },
        {
            "algorithm": "sha-512",
            "value": "7F:D3:E0:C6:1B:D1:AB:1F:A3:35:72:7D:9C:24:91:62:BF:A0:5E:A8:1F:EE:F0:9A:1D:05:37:AD:78:B9:E8:8E:42:6E:F9:09:4B:A5:B4:66:23:26:A1:A8:DE:08:85:27:0B:3C:60:90:89:FD:3D:1F:30:73:81:F7:35:49:7D:F5"
        }
    ],
    "role": "auto"
}
}


{
"id": "6f2e2284-2468-4a79-928b-b044765a6777",
"iceParameters": {
    "iceLite": true,
    "password": "b2tjomcqdmno3bjig7q85rpr2jwd4s8j",
    "usernameFragment": "eho67d7lw16nee2l"
},
"iceCandidates": [
    {
        "foundation": "udpcandidate",
        "ip": "0.0.0.0",
        "port": 48942,
        "priority": 1076558079,
        "protocol": "udp",
        "type": "host"
    },
    {
        "foundation": "tcpcandidate",
        "ip": "0.0.0.0",
        "port": 49477,
        "priority": 1076302079,
        "protocol": "tcp",
        "tcpType": "passive",
        "type": "host"
    }
],
"dtlsParameters": {
    "fingerprints": [
        {
            "algorithm": "sha-1",
            "value": "7B:A7:5D:F1:A6:EA:72:83:4B:83:21:E2:7A:8D:A1:B1:A4:8B:A6:87"
        },
        {
            "algorithm": "sha-224",
            "value": "8A:E5:5F:5C:30:34:BD:D4:75:52:B5:0A:28:1C:5C:11:6B:84:01:5F:FE:72:82:BA:C9:6F:B6:63"
        },
        {
            "algorithm": "sha-256",
            "value": "CC:D8:6A:94:DA:71:27:45:FB:1B:32:88:2C:5C:1C:26:94:6E:BF:84:47:CA:FE:41:53:5B:D7:36:D5:66:42:A0"
        },
        {
            "algorithm": "sha-384",
            "value": "FF:25:F0:2F:A5:CF:C4:D8:9E:A1:4F:D5:47:44:98:25:BE:30:12:71:53:AB:61:D1:D1:78:BA:96:65:75:7B:A5:3B:94:49:9F:61:DA:B1:C6:B9:FF:57:41:1F:2B:78:65"
        },
        {
            "algorithm": "sha-512",
            "value": "7F:D3:E0:C6:1B:D1:AB:1F:A3:35:72:7D:9C:24:91:62:BF:A0:5E:A8:1F:EE:F0:9A:1D:05:37:AD:78:B9:E8:8E:42:6E:F9:09:4B:A5:B4:66:23:26:A1:A8:DE:08:85:27:0B:3C:60:90:89:FD:3D:1F:30:73:81:F7:35:49:7D:F5"
        }
    ],
    "role": "auto"
}
}

Below is the data being sent from the server which is used in code snippet pasted above when newConsumer event happens.

{
"peerId": "VZwCYhzUbcjc9nLiAAAJ",
"producerId": "c673fb19-7b32-44f9-b45d-43355a193277",
"id": "48ba5d06-942d-47ca-aaf6-3985a22de91b",
"kind": "video",
"rtpParameters": {
    "codecs": [
        {
            "mimeType": "video/VP8",
            "payloadType": 101,
            "clockRate": 90000,
            "parameters": {},
            "rtcpFeedback": [
                {
                    "type": "nack",
                    "parameter": ""
                },
                {
                    "type": "nack",
                    "parameter": "pli"
                },
                {
                    "type": "ccm",
                    "parameter": "fir"
                },
                {
                    "type": "transport-cc",
                    "parameter": ""
                }
            ]
        },
        {
            "mimeType": "video/rtx",
            "payloadType": 102,
            "clockRate": 90000,
            "parameters": {
                "apt": 101
            },
            "rtcpFeedback": []
        }
    ],
    "headerExtensions": [
        {
            "uri": "urn:ietf:params:rtp-hdrext:sdes:mid",
            "id": 1,
            "encrypt": false,
            "parameters": {}
        },
        {
            "uri": "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time",
            "id": 4,
            "encrypt": false,
            "parameters": {}
        },
        {
            "uri": "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01",
            "id": 5,
            "encrypt": false,
            "parameters": {}
        },
        {
            "uri": "http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07",
            "id": 6,
            "encrypt": false,
            "parameters": {}
        },
        {
            "uri": "urn:ietf:params:rtp-hdrext:framemarking",
            "id": 7,
            "encrypt": false,
            "parameters": {}
        },
        {
            "uri": "urn:3gpp:video-orientation",
            "id": 11,
            "encrypt": false,
            "parameters": {}
        },
        {
            "uri": "urn:ietf:params:rtp-hdrext:toffset",
            "id": 12,
            "encrypt": false,
            "parameters": {}
        }
    ],
    "encodings": [
        {
            "ssrc": 306981400,
            "rtx": {
                "ssrc": 306981401
            }
        }
    ],
    "rtcp": {
        "cname": "jjCf7Ex05NUeAQBn",
        "reducedSize": true,
        "mux": true
    },
    "mid": "0"
},
"type": "simple",
"appData": {
    "mediaTag": "webcam",
    "peerId": "VZwCYhzUbcjc9nLiAAAJ",
    "transportId": "2c2239b1-18e3-478c-86f3-5e3bfd31941d"
},
"producerPaused": false
}

Deployment infra info.

Frontend and backend are deployed as docker containers along with nginx on aws multi docker container .

For testing purposes I opened up all tcp and udp ports on the load balancer as well as the ec2 instance.

Frontend Docker File

FROM nginx

WORKDIR /usr/share/nginx/html

RUN rm -rf ./*

COPY build/ .

COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf

EXPOSE 3000

CMD ["nginx", "-g", "daemon off;"]

Backend Docker File

FROM node:14.15.4

# Install DEB dependencies and others.

RUN \

set -x \

&& apt-get update \

&& apt-get install -y net-tools build-essential valgrind

WORKDIR /app

COPY package*.json ./

COPY tsconfig.json .

COPY src src

RUN npm install

EXPOSE 5000

EXPOSE 40000-49999

CMD ["npm", "run", "start:prod]

Nginx Docker File

FROM nginx

EXPOSE 80

RUN rm /usr/share/nginx/html/*

COPY configs/default.conf /etc/nginx/conf.d/default.conf

CMD [ "nginx", "-g", "daemon off;" ]

Https is enabled on the load balancer and node server is running as a http server.

Below is the mediasoup config file

export const config = {
    // http server ip, port, and peer timeout constant
    //
    httpIp: '0.0.0.0',
    httpPort: 5000,
    httpPeerStale: 15000,

    // ssl certs. we'll start as http instead of https if we don't have
    // these
    sslCrt: 'local.crt', // is not being used
    sslKey: 'local.key',

    mediasoup: {
        worker: {
            rtcMinPort: 40000,
            rtcMaxPort: 49999,
            logLevel: 'debug',
            logTags: [
                'info',
                'ice',
                'dtls',
                'rtp',
                'srtp',
                'rtcp',
                // 'rtx',
                // 'bwe',
                // 'score',
                // 'simulcast',
                // 'svc'
            ],
        } as WorkerSettings,
        router: {
            mediaCodecs: [
                {
                    kind: 'audio',
                    mimeType: 'audio/opus',
                    clockRate: 48000,
                    channels: 2,
                },
                {
                    kind: 'video',
                    mimeType: 'video/VP8',
                    clockRate: 90000,
                    parameters: {
                        //                'x-google-start-bitrate': 1000
                    },
                },
                {
                    kind: 'video',
                    mimeType: 'video/h264',
                    clockRate: 90000,
                    parameters: {
                        'packetization-mode': 1,
                        'profile-level-id': '4d0032',
                        'level-asymmetry-allowed': 1,
                        //                        'x-google-start-bitrate'  : 1000
                    },
                },
                {
                    kind: 'video',
                    mimeType: 'video/h264',
                    clockRate: 90000,
                    parameters: {
                        'packetization-mode': 1,
                        'profile-level-id': '42e01f',
                        'level-asymmetry-allowed': 1,
                        //                        'x-google-start-bitrate'  : 1000
                    },
                },
            ] as RtpCodecCapability[],
        },

        // rtp listenIps are the most important thing, below. you'll need
        // to set these appropriately for your network for the demo to
        // run anywhere but on localhost
        webRtcTransport: {
            listenIps: [
                {
                    ip: process.env.LISTEN_IP,
                    announcedIp: process.env.ANNOUNCEMENT_IP,
                },
                // { ip: '127.0.0.1', announcedIp: '192.168.65.1' },
                // { ip: '172.17.0.1', announcedIp: undefined },
                // { ip: '127.0.0.1', announcedIp: '192.168.1.34' },
                // { ip: "192.168.42.68", announcedIp: null },
                // { ip: '10.10.23.101', announcedIp: null },
            ] as TransportListenIp[],
            initialAvailableOutgoingBitrate: 800000,
        },
    },
};

Ip is set to 0.0.0.0 and announcedIp is set to the public ip of the ec2 instance.

EDIT

Changed docker-compose to run the containers on host network_mode as shown below:

version: "3.9"

services:
  client:
    image: client_image_url
    container_name: client
    network_mode: host
    restart: always
  backend:
    image: backend_image_url
    container_name: backend
    env_file: .env
    network_mode: host
    restart: always
  nginx:
    image: nginx_network_mode
    depends_on:
      - client
      - backend
    network_mode: host
    restart: always

Ip is set to private ip of the ec2 instance and announcedIp is set to the public ip of the ec2 instance.

Now the transports.recv.connectionState moves to connecting state and after a while gets disconnected.

I am new to Webrtc and mediasoup. I am stuck with this error for quite some time. Any help would be appreciated. Thanks in advance.

4

1 回答 1

-1

尝试检查您是否在创建传输时使用了 ice 服务器 这是一个免费的 ice 服务器

{
    url: 'turn:numb.viagenie.ca',
    credential: 'muazkh',
    username: 'webrtc@live.com'
}

它是创建运输的选项之一

transport = device.createSendTransport({...options, iceServers : [{
    url: 'turn:numb.viagenie.ca',
    credential: 'muazkh',
    username: 'webrtc@live.com'
}]})

接收运输也是如此

于 2022-01-14T20:13:19.640 回答