worker is not creating

import express from ‘express’

const app = express()

import https from ‘httpolyglot’
import fs from ‘fs’
import path from ‘path’
const __dirname = path.resolve()

import { Server } from ‘socket.io
import mediasoup from ‘mediasoup’

app.get(‘/’, (req, res) => {
res.send(‘Hello from mediasoup app!’)
})

app.use(‘/sfu’, express.static(path.join(__dirname, ‘public’)))

// SSL cert for HTTPS access
const options = {
key: fs.readFileSync(‘./server/ssl/key.pem’, ‘utf-8’),
cert: fs.readFileSync(‘./server/ssl/cert.pem’, ‘utf-8’)
}

const httpsServer = https.createServer(options, app)
httpsServer.listen(3000, () => {
console.log('listening on port: ’ + 3000)
})

const io = new Server(httpsServer)

const peers = io.of(‘/mediasoup’)

peers.on(‘connection’, async socket => {
console.log(socket.id)
socket.emit(‘connection-success’, {
socketId: socket.id
})
})

let worker

const createWorker = async () => {

worker = await mediasoup.createWorker({
  rtcMinPort: 2000,
  rtcMaxPort: 2020,
})
console.log(`worker pid ${worker.pid}`)

worker.on('died', error => {
  // This implies something serious happened, so kill the application
  console.error('mediasoup worker has died')
  setTimeout(() => process.exit(1), 2000) // exit in 2 seconds
})

return worker

}

worker=createWorker()

in last line on calling createWorker (), i am getting the following error

C:\Users\Acer\Desktop\New folder\example1>node app.js
listening on port: 3000
C:\Users\Acer\Desktop\New folder\example1\node_modules\mediasoup\node\lib\Worker.js:146
this.emit(‘@failure’, new Error([pid:${this.#pid}, code:${code}, signal:${signal}]));
^

Error: [pid:8488, code:3221225477, signal:null]
at ChildProcess. (C:\Users\Acer\Desktop\New folder\example1\node_modules\mediasoup\node\lib\Worker.js:146:43)
at ChildProcess.emit (node:events:519:28)
at ChildProcess._handle.onexit (node:internal/child_process:294:12)

Node.js v21.6.2

hi bro
please see exmaples exactly and document you can create better.

this is my code
create mediasoup.comfig.ts

import * as mediasoup from 'mediasoup';

import os from 'os';
import * as dotenv from 'dotenv';

dotenv.config();

const { MEDIASOUP_LISTEN_IP,
    MEDIASOUP_ANNOUNCED_IP,
    MEDIASOUP_MIN_PORT,
    MEDIASOUP_MAX_PORT, } = process.env;

interface MediasoupConfig {
    numWorkers: number;
    workerSettings: {
        dtlsCertificateFile?: string;
        dtlsPrivateKeyFile?: string;
        logLevel: mediasoup.types.WorkerLogLevel;
        logTags: mediasoup.types.WorkerLogTag[];
    };
    routerOptions: mediasoup.types.RouterOptions;
    webRtcServerOptions: mediasoup.types.WebRtcServerOptions;
    webRtcTransportOptions: mediasoup.types.WebRtcTransportOptions;
    plainTransportOptions: mediasoup.types.PlainTransportOptions;
}

const address: mediasoup.types.TransportListenInfo[] = [];



(async () => {
    const myinterfaces = os.networkInterfaces();

    for (let interfacei in myinterfaces) {
        for (let interfeceinfo of myinterfaces[interfacei]) {
            if (!interfeceinfo.internal) {
                if (interfeceinfo.family === "IPv4") {
                    address.push({
                        protocol: "udp",
                        ip: "0.0.0.0",
                        announcedAddress: interfeceinfo.address,
                        // port: 4000,
                    })
                    address.push({
                        protocol: "tcp",
                        ip: "0.0.0.0",
                        announcedAddress: interfeceinfo.address,
                        // port: 4000,
                    })

                }
                // else  if (interfeceinfo.family === "IPv6") {
                //     address.push({
                //         protocol: "udp",
                //         ip: interfeceinfo.address,
                //         announcedAddress: "142.132.152.236"
                //     })
                // }
            }
            console.log("alllllll inteface addresss");

            console.log(interfeceinfo);
        }
    }

})()
console.log("addredss");
console.log(address);





const mediasoupConfiges: MediasoupConfig = {
    // Number of mediasoup workers to launch on CPU exist.
    numWorkers: Object.keys(os.cpus()).length,
    // mediasoup WorkerSettings.
    // See https://mediasoup.org/documentation/v3/mediasoup/api/#WorkerSettings
    workerSettings: {
        logLevel: "debug",
        logTags: ['info', 'ice', 'dtls', 'rtp', 'srtp', 'rtcp', 'rtx', 'bwe', 'score', 'simulcast', 'svc', 'sctp'],
        dtlsCertificateFile: "",
        dtlsPrivateKeyFile: "",
    },
    // mediasoup Router options.
    // See https://mediasoup.org/documentation/v3/mediasoup/api/#RouterOptions
    routerOptions: {
        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/VP9', clockRate: 90000, parameters: { 'profile-id': 2, '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 } }
        ]
    },

    webRtcServerOptions: {
        listenInfos: [...address,
        ],
    },
    // mediasoup WebRtcTransport options for WebRTC endpoints (mediasoup-client,
    // libmediasoupclient).
    // See https://mediasoup.org/documentation/v3/mediasoup/api/#WebRtcTransportOptions
    webRtcTransportOptions: {
        // listenInfos is not needed since webRtcServer is used.
        // However passing MEDIASOUP_USE_WEBRTC_SERVER=false will change it.
        listenInfos: [
            {
                protocol: 'udp',
                ip: MEDIASOUP_LISTEN_IP || '0.0.0.0',
                announcedAddress: MEDIASOUP_ANNOUNCED_IP,
                portRange: {
                    min: Number(MEDIASOUP_MIN_PORT) || 40000,
                    max: Number(MEDIASOUP_MAX_PORT) || 49999
                }
            },
            {
                protocol: 'tcp',
                ip: MEDIASOUP_LISTEN_IP || '0.0.0.0',
                announcedAddress: MEDIASOUP_ANNOUNCED_IP,
                portRange: {
                    min: Number(MEDIASOUP_MIN_PORT) || 40000,
                    max: Number(MEDIASOUP_MAX_PORT) || 49999
                }
            }
        ],
        initialAvailableOutgoingBitrate: 1000000,
        maxSctpMessageSize: 262144,
        enableUdp: true,
        // enableTcp: true,
        preferUdp: true,

    },

    plainTransportOptions: {
        listenInfo: {
            protocol: 'udp',
            ip: MEDIASOUP_LISTEN_IP || '0.0.0.0',
            announcedAddress: MEDIASOUP_ANNOUNCED_IP,
            portRange: {
                min: Number(MEDIASOUP_MIN_PORT) || 40000,
                max: Number(MEDIASOUP_MAX_PORT) || 49999
            }
        },
        maxSctpMessageSize: 262144
    }
}


export default mediasoupConfiges;


dont forget env file

then in main node js file use this config

index.ts

let worker: mediasoup.types.Worker;

let router: mediasoup.types.Router;

let webRtcServer: mediasoup.types.WebRtcServer;

async function startMediaSoup() {
    mediasoup.createWorker(mediasoupConfiges.workerSettings).then(worderCreated => {
        worker = worderCreated;
        console.log("created worker");

        worderCreated.createWebRtcServer(mediasoupConfiges.webRtcServerOptions).then(webServerCreated => {
            webRtcServer = webServerCreated;
            worderCreated.appData.webRtcServer = webRtcServer;
            console.log("created webRtcServer");

        }).catch(err => {
            console.log("error in create webServer");
            console.log(err);
        });

        worderCreated.createRouter(mediasoupConfiges.routerOptions).then(routerCreated => {
            router = routerCreated;
            console.log("created router");

        }).catch(err => {
            console.log("error in create router");
            console.log(err);

        });

    }).catch(err => {
        console.log("error in create worker");
        console.log(err);

    })

    worker.on("died", () => {
        console.error('mediasoup worker died, exiting in 2 seconds... [pid:%d]', worker.pid);
    })
}


io.on('connection', async (socket: Socket) => {
//all your code 

}


startMediaSoup().then(() => {
    console.log("mediasoupConfiges.webRtcServerOptions.listenInfos");
   
    console.log("mediasoupConfiges.webRtcTransportOptions.listenInfos");


}).catch(error => {
    console.log("error startMediaSoup");
    console.log(error);
})

app.listen(3000, (): void => {
    console.log('node server listening on port 3000');
});

for me ceate worker and router (has a bug .not important)
node 20
mediasoup v3

thanks hasan for replying and providing the codes,

i have set up the mediasoup and it’s working fine , but i am facing
difficulty in deploying this, specifically realting ports and .env
file it would be great if you can provide some help

this is my docker image bhadula01/vid-conferencing-sfu:latest
i am new to this so i am facing alot of problems in it

hi bro.
Dear, while you use docker image use should setup with kubernate.
it’s is very important to know about ports in containers because you can implement mediaosup on container but don’t work you must use kubernate with some important points that you must in regard.
I implemented before (two month ago) on azure cloud with this points. I forgot some points
1: hostnetwork:true (very inportnat)(this is set pod ip the same with node ip and maped them)
2: create service for kubernate (this is map ip and port to the pods)
3: open range port in inbound for nodes and set priority on 1000 (this cause searchable for mediasoup wertc transport to connect)

for vertical and horizontal scaling you must know about kuberante. and loadbalancer for cloud virtual machine.

now. I use cloud server it is very easy for our to implement mediasoup bacause we can clone our git repository and instanll and use without and problem with ports and other things related to kuberante until finish base of project after that can migrate to docker and kubernate

for use env file different in docker and server
if use docker must set at env envromnet and automaticly set at code
but if use in cloud server use this

create env file like this .env

then add your const like

PORT=5000

ACCESS_TOKEN_LIFE=2m

REFRESH_TOKEN_LIFE=30d

accesss in code with

const { REFRESH_TOKEN_LIFE,ACCESS_TOKEN_LIFE,PORT } = process.env;

Thanks hassan ,
Finally I was able to deploy it, once again thanks to you

But now I am facing problem with announced ip ,I have set it up as host public IP but still users can’t share their vid to others , rest things are working fine with dtls parameters and rest code

I need the public IP address to set it as announced ip but I am unable to do so, do you have any idea ,how can I do it

public ip the same ipv4 in host
if you deploy on docker the code that I send to you , if that code on server or cloud server get public ip automatically if that code on docker it will get node ip or loadbalancer ip that dosen’t work.
you must deploy on server like cloud server that is easy

sorry for disturbing you again but this is getting really confusing for me and i am at very last to set this up, it will be great help if you could just make changes to this code for announced ip being automatically detected on uploading on render,
i have tried using render’s public url as the announced ip but that was of no use,

i will be highly grateful to you

import express from ‘express’
const app = express()
const port = 3000;

app.use(express.json());

import fs from ‘fs’
import path from ‘path’
const __dirname = path.resolve()
import http from ‘http’;
import { Server } from ‘socket.io
import mediasoup from ‘mediasoup’

app.use(express.static(path.join(__dirname)));

app.get(‘/’, (req, res) => {
res.sendFile(path.join(__dirname,‘home.html’));
});

app.get(‘/room/:roomNumber’, (req, res) => {
res.sendFile(path.join(__dirname, ‘room.html’));
});

const httpsServer = http.createServer( app)
httpsServer.listen(port, () => {
console.log('listening on port: ’ + ( port))
})

const io = new Server(httpsServer)

// socket.io namespace (could represent a room?)
const connections = io.of(‘/mediasoup’)

let worker
let rooms = {} // { roomName1: { Router, rooms: [ sicketId1, … ] }, …}
let peers = {} // { socketId1: { roomName1, socket, transports = [id1, id2,] }, producers = [id1, id2,] }, consumers = [id1, id2,], peerDetails }, …}
let transports = // [ { socketId1, roomName1, transport, consumer }, … ]
let producers = // [ { socketId1, roomName1, producer, }, … ]
let consumers = // [ { socketId1, roomName1, consumer, }, … ]

const createWorker = async () => {
worker = await mediasoup.createWorker({
rtcMinPort:2000,
rtcMaxPort:2050,
})
console.log(worker pid ${worker.pid})

worker.on(‘died’, error => {
// This implies something serious happened, so kill the application
console.error(‘mediasoup worker has died’)
setTimeout(() => process.exit(1), 2000) // exit in 2 seconds
})

return worker
}

// We create a Worker as soon as our application starts
worker = createWorker()

const mediaCodecs = [
{
kind: ‘audio’,
mimeType: ‘audio/opus’,
clockRate: 48000,
channels: 2,
},
{
kind: ‘video’,
mimeType: ‘video/VP8’,
clockRate: 90000,
parameters: {
‘x-google-start-bitrate’: 1000,
},
},
]

connections.on(‘connection’, async socket => {
console.log(socket.id)
socket.emit(‘connection-success’, {
socketId: socket.id,
})

const removeItems = (items, socketId, type) => {
items.forEach(item => {
if (item.socketId === socket.id) {
item[type].close()
}
})
items = items.filter(item => item.socketId !== socket.id)

return items
}

socket.on(‘disconnect’, () => {
console.log(‘peer disconnected’);

const peer = peers[socket.id];
if (peer) {
consumers = removeItems(consumers, socket.id, ‘consumer’);
producers = removeItems(producers, socket.id, ‘producer’);
transports = removeItems(transports, socket.id, ‘transport’);

const { roomName } = peer;

rooms[roomName] = {
router: rooms[roomName].router,
peers: rooms[roomName].peers.filter(socketId => socketId !== socket.id)
};

delete peers[socket.id];
} else {
console.log(‘Socket ID not found in peers’);
}
});

socket.on(‘joinRoom’, async ({ roomName }, callback) => {

const router1 = await createRoom(roomName, socket.id)

peers[socket.id] = {
socket,
roomName,
transports: ,
producers: ,
consumers: ,
peerDetails: {
name: ‘’,
isAdmin: false,
}
}

const rtpCapabilities = router1.rtpCapabilities

callback({ rtpCapabilities })
})

const createRoom = async (roomName, socketId) => {

let router1
let peers =
if (rooms[roomName]) {
router1 = rooms[roomName].router
peers = rooms[roomName].peers ||
} else {
router1 = await worker.createRouter({ mediaCodecs, })
}

console.log(Router ID: ${router1.id}, peers.length)

rooms[roomName] = {
router: router1,
peers: […peers, socketId],
}

return router1
}

// Client emits a request to create server side Transport
// We need to differentiate between the producer and consumer transports
socket.on(‘createWebRtcTransport’, async ({ consumer }, callback) => {
// get Room Name from Peer’s properties
const roomName = peers[socket.id].roomName

// get Router (Room) object this peer is in based on RoomName
const router = rooms[roomName].router

createWebRtcTransport(router).then(
transport => {
callback({
params: {
id: transport.id,
iceParameters: transport.iceParameters,
iceCandidates: transport.iceCandidates,
dtlsParameters: transport.dtlsParameters,
}
})

// add transport to Peer’s properties
addTransport(transport, roomName, consumer)
},
error => {
console.log(error)
})
})

const addTransport = (transport, roomName, consumer) => {

transports = [
…transports,
{ socketId: socket.id, transport, roomName, consumer, }
]

peers[socket.id] = {
…peers[socket.id],
transports: [
…peers[socket.id].transports,
transport.id,
]
}
}

const addProducer = (producer, roomName) => {
producers = [
…producers,
{ socketId: socket.id, producer, roomName, }
]

peers[socket.id] = {
…peers[socket.id],
producers: [
…peers[socket.id].producers,
producer.id,
]
}
}

const addConsumer = (consumer, roomName) => {
// add the consumer to the consumers list
consumers = [
…consumers,
{ socketId: socket.id, consumer, roomName, }
]

// add the consumer id to the peers list
peers[socket.id] = {
…peers[socket.id],
consumers: [
…peers[socket.id].consumers,
consumer.id,
]
}
}

socket.on(‘getProducers’, callback => {
//return all producer transports
const { roomName } = peers[socket.id]

let producerList =
producers.forEach(producerData => {
if (producerData.socketId !== socket.id && producerData.roomName === roomName) {
producerList = […producerList, producerData.producer.id]
}
})

// return the producer list back to the client
callback(producerList)
})

const informConsumers = (roomName, socketId, id) => {
console.log(just joined, id ${id} ${roomName}, ${socketId})
// A new producer just joined
// let all consumers to consume this producer
producers.forEach(producerData => {
if (producerData.socketId !== socketId && producerData.roomName === roomName) {
const producerSocket = peers[producerData.socketId].socket
// use socket to send producer id to producer
producerSocket.emit(‘new-producer’, { producerId: id })
}
})
}

const getTransport = (socketId) => {
const [producerTransport] = transports.filter(transport => transport.socketId === socketId && !transport.consumer)
return producerTransport.transport
}

// see client’s socket.emit(‘transport-connect’, …)
socket.on(‘transport-connect’, ({ dtlsParameters }) => {
console.log('DTLS PARAMS… ', { dtlsParameters })

getTransport(socket.id).connect({ dtlsParameters })
})

// see client’s socket.emit(‘transport-produce’, …)
socket.on(‘transport-produce’, async ({ kind, rtpParameters, appData }, callback) => {
// call produce based on the prameters from the client
const producer = await getTransport(socket.id).produce({
kind,
rtpParameters,
})

// add producer to the producers array
const { roomName } = peers[socket.id]

addProducer(producer, roomName)

informConsumers(roomName, socket.id, producer.id)

console.log('Producer ID: ', producer.id, producer.kind)

producer.on(‘transportclose’, () => {
console.log('transport for this producer closed ')
producer.close()
})

// Send back to the client the Producer’s id
callback({
id: producer.id,
producersExist: producers.length>1 ? true : false
})
})

// see client’s socket.emit(‘transport-recv-connect’, …)
socket.on(‘transport-recv-connect’, async ({ dtlsParameters, serverConsumerTransportId }) => {
console.log(DTLS PARAMS: ${dtlsParameters})
const consumerTransport = transports.find(transportData => (
transportData.consumer && transportData.transport.id == serverConsumerTransportId
)).transport
await consumerTransport.connect({ dtlsParameters })
})

socket.on(‘consume’, async ({ rtpCapabilities, remoteProducerId, serverConsumerTransportId }, callback) => {
try {

const { roomName } = peers[socket.id]
const router = rooms[roomName].router
let consumerTransport = transports.find(transportData => (
transportData.consumer && transportData.transport.id == serverConsumerTransportId
)).transport

// check if the router can consume the specified producer
if (router.canConsume({
producerId: remoteProducerId,
rtpCapabilities
})) {
// transport can now consume and return a consumer
const consumer = await consumerTransport.consume({
producerId: remoteProducerId,
rtpCapabilities,
paused: true,
})

consumer.on(‘transportclose’, () => {
console.log(‘transport close from consumer’)
})

consumer.on(‘producerclose’, () => {
console.log(‘producer of consumer closed’)
socket.emit(‘producer-closed’, { remoteProducerId })

consumerTransport.close()
transports = transports.filter(transportData => transportData.transport.id !== consumerTransport.id)
consumer.close()
consumers = consumers.filter(consumerData => consumerData.consumer.id !== consumer.id)
})

addConsumer(consumer, roomName)

// from the consumer extract the following params
// to send back to the Client
const params = {
id: consumer.id,
producerId: remoteProducerId,
kind: consumer.kind,
rtpParameters: consumer.rtpParameters,
serverConsumerId: consumer.id,
}

// send the parameters to the client
callback({ params })
}
} catch (error) {
console.log(error.message)
callback({
params: {
error: error
}
})
}
})

socket.on(‘consumer-resume’, async ({ serverConsumerId }) => {
console.log(‘consumer resume’)
const { consumer } = consumers.find(consumerData => consumerData.consumer.id === serverConsumerId)
await consumer.resume()
})
})

const createWebRtcTransport = async (router) => {
return new Promise(async (resolve, reject) => {
try {
// https://mediasoup.org/documentation/v3/mediasoup/api/#WebRtcTransportOptions
const webRtcTransport_options = {
listenIps: [
{
ip: ‘0.0.0.0’, // replace with relevant IP address
announcedIp: ‘192.168.1.7’,
}
],
enableUdp: true,
enableTcp: true,
preferUdp: true,
}

// https://mediasoup.org/documentation/v3/mediasoup/api/#router-createWebRtcTransport
let transport = await router.createWebRtcTransport(webRtcTransport_options)
console.log(transport id: ${transport.id})

transport.on(‘dtlsstatechange’, dtlsState => {
if (dtlsState === ‘closed’) {
transport.close()
}
})

transport.on(‘close’, () => {
console.log(‘transport closed’)
})

resolve(transport)

} catch (error) {
reject(error)
}
})
}

hi this is simple example . you can use it and test.

thanks a lot brother , I will be grateful to you

1 Like