Compare commits

..

14 Commits

Author SHA1 Message Date
c247afdbe3 updated procedure 2025-03-21 14:14:40 +02:00
755df1ec5a Merge pull request 'LINXD-2850: Add handler on icestatechange failed/disconnected to send 'connection-failed' event to participants' (#39) from LINXD-2850-connection-failed-handler into develop
Reviewed-on: #39
Reviewed-by: Cristi Ene <cristi.ene@safemobile.com>
2025-03-12 15:22:30 +00:00
cd91d40dd0 LINXD-2850: Added image in doc 2025-03-12 09:56:09 +02:00
642dba8dac LINXD-2850: Add handler on icestatechange failed/disconnected to send 'connection-failed' event to participants 2025-03-12 09:31:36 +02:00
4f044555ba Merge pull request 'Update node version in Dockerfile' (#38) from update-build into develop
Reviewed-on: #38
2025-03-07 09:35:02 +00:00
230d5b6bce Merge branch 'develop' into update-build 2025-03-07 09:34:33 +00:00
73c7700ded Update node version in Dockerfile 2025-03-07 11:33:47 +02:00
9e66772b53 Merge pull request 'update-build' (#37) from update-build into develop
Reviewed-on: #37
2025-03-07 09:14:06 +00:00
5ef66af3f8 Update build.sh 2025-03-07 11:12:56 +02:00
1b29d43580 Update build.sh 2025-03-07 11:12:12 +02:00
dd5af12c7c Merge pull request 'LINXD-2842-log-protocol-change' (#36) from LINXD-2842-log-protocol-change into develop
Reviewed-on: #36
Reviewed-by: Cristi Ene <cristi.ene@safemobile.com>
2025-03-05 21:40:24 +00:00
af21774d17 LINXD-2842: Update mediasoup version; Add handler for icestatechange; Add env PREFER_TCP; Add 3s ICE consent timeout 2025-03-05 23:37:35 +02:00
fc250c248e LINXD-2842: Update README 2025-03-04 17:01:54 +02:00
fc39d5bead LINXD-2842: Log message when protocol is changed 2025-03-03 22:30:41 +02:00
8 changed files with 1184 additions and 54 deletions

3
.env
View File

@ -7,4 +7,5 @@ SERVER_CERT="./server/ssl/cert.pem"
SERVER_KEY="./server/ssl/key.pem"
ENABLE_UDP=true
ENABLE_TCP=true
PREFER_UDP=true
PREFER_UDP=true
PREFER_TCP=false

View File

@ -5,7 +5,7 @@ WORKDIR /app
RUN apt-get update && \
apt-get install -y build-essential pip net-tools iputils-ping iproute2 curl
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash -
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
RUN apt-get install -y nodejs
COPY . /app/

View File

@ -1,5 +1,22 @@
# Video server
### Running Docker
Output from history. Customize with your own container identifier
```Bash
docker build -t linx-video .
docker ps
docker stop ad5
docker rm ad5
docker run -it -d --restart always -p 3000:3000/tcp -p 2000-2200:2000-2200/tcp -p 2000-2200:2000-2200/udp linx-video
docker logs 736 -f
cat .env
docker logs 736 -f
```
### Generating certificates
##### To generate SSL certificates you must:
@ -38,22 +55,22 @@
##### To start in production mode you must:
1. Install the dependencies `npm install`.
2. Run the `npm start:prod` command to start the server in production mode.
(To connect to the terminal, use `pm2 log video-server`)
(To connect to the terminal, use `pm2 log video-server`)
### Web client
- The server will start by default on port 3000, and the ssl certificates will have to be configured
- The web client can be accessed using the /sfu path
ex: https://HOST/sfu/?assetId=1&&accountId=1&producer=true&dest_asset_id=75&assetName=Adi
assetId = asset id of the unit on which you are doing the test
accountId = account id of the unit on which you are doing the test
producer = it will always be true because you are the producer
(it's possible to put false, but then you have to have another client with producer true)
assetName = asset name of the unit on which you are doing the test
dest_asset_id= the addressee with whom the call is made
ex: https://HOST/sfu/?assetId=1&&accountId=1&producer=true&dest_asset_id=75&assetName=Adi
assetId = asset id of the unit on which you are doing the test
accountId = account id of the unit on which you are doing the test
producer = it will always be true because you are the producer
(it's possible to put false, but then you have to have another client with producer true)
assetName = asset name of the unit on which you are doing the test
dest_asset_id= the addressee with whom the call is made
- To make a call using this client, you need a microphone and permission to use it
- For any changes related to the client, the command `npm run watch' will have to be used to generate the bundle.js used by the web client
### Demo project
The demo project used initially and then modified for our needs `https://github.com/jamalag/mediasoup2`
The demo project used initially and then modified for our needs `https://github.com/jamalag/mediasoup2`

40
app.js
View File

@ -12,6 +12,11 @@ try {
console.log('https support is disabled!');
}
const mediasoup = require('mediasoup');
const isUdpEnabled = process.env.ENABLE_UDP === 'true';
const isTcpEnabled = process.env.ENABLE_TCP === 'true';
const isUdpPreferred = process.env.PREFER_UDP === 'true';
const isTcpPreferred = process.env.PREFER_TCP === 'true';
let currentConnectionType = isUdpPreferred ? 'udp' : 'tcp';
let worker;
/**
@ -537,6 +542,15 @@ const isInitiator = (callId, socketId) => {
return videoCalls[callId]?.initiatorSocket?.id === socketId;
};
const emitToParticipants = (callId, event, message) => {
try {
videoCalls[callId].receiverSocket.emit(event, message);
videoCalls[callId].initiatorSocket.emit(event, message);
} catch (error) {
console.error(`[emitToParticipants] | ERROR | callId: ${callId} | error: ${error.message}`);
}
}
/*
- Called from at event 'createWebRtcTransport' and assigned to the consumer or producer transport
- It will return parameters, these are required for the client to create the RecvTransport
@ -555,14 +569,34 @@ const createWebRtcTransportLayer = async (callId, callback) => {
announcedIp: process.env.ANNOUNCED_IP, // Announced IPv4 or IPv6 (useful when running mediasoup behind NAT with private IP).
},
],
enableUdp: process.env.ENABLE_UDP === 'true',
enableTcp: process.env.ENABLE_TCP === 'true',
preferUdp: process.env.PREFER_UDP === 'true',
enableUdp: isUdpEnabled,
enableTcp: isTcpEnabled,
preferUdp: isUdpPreferred,
preferTcp: isTcpPreferred,
iceConsentTimeout: 3
};
// https://mediasoup.org/documentation/v3/mediasoup/api/#router-createWebRtcTransport
let transport = await videoCalls[callId].router.createWebRtcTransport(webRtcTransport_options);
// `iceselectedtuplechange`: Fires when ICE switches transport (e.g., UDP → TCP).
transport.on('iceselectedtuplechange', (selectedTuple) => {
const { protocol } = selectedTuple;
if (currentConnectionType !== protocol) {
console.warn(`⚠️ ${currentConnectionType.toUpperCase()} blocked! Switching to ${protocol.toUpperCase()} for callId: ${callId}`);
currentConnectionType = protocol;
}
});
// `icestatechange`: Fires when ICE connection state changes (e.g., new, connected, failed).
transport.on('icestatechange', (iceState) => {
console.log(`[ICE STATE CHANGE] callId: ${callId} | State: ${iceState}`);
if (iceState === 'failed' || iceState === 'disconnected') {
console.warn(`⚠️ ICE failure detected for callId: ${callId}! Possible UDP blockage.`);
emitToParticipants(callId, 'connection-failed', { callId });
}
});
// Handler for when DTLS(Datagram Transport Layer Security) changes
transport.on('dtlsstatechange', (dtlsState) => {
console.log(`transport | dtlsstatechange | calldId ${callId} | dtlsState ${dtlsState}`);

View File

@ -51,11 +51,11 @@ if [ -d "node_modules" ]; then
fi
# Install dependencies
#npm install
npm install
## PROJECT NEEDS
echo "Building app... from $(git rev-parse --abbrev-ref HEAD)"
#npm run-script build
npm run-script build
cp -r {.env,app.js,package.json,server,public,doc,Dockerfile} dist/
#cp -r ./* dist/

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

1150
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@
"@types/express": "^4.17.13",
"dotenv": "^16.0.1",
"express": "^4.18.1",
"mediasoup": "^3.10.4",
"mediasoup": "^3.15.5",
"mediasoup-client": "^3.6.54",
"parcel": "^2.7.0",
"socket.io": "^2.0.3",
@ -29,4 +29,4 @@
"ts-node-dev": "^2.0.0",
"watchify": "^4.0.0"
}
}
}