Compare commits

...

3 Commits

Author SHA1 Message Date
c823f7578c LH-265: Update client 2022-11-29 13:27:33 +02:00
6cc14cdf30 LH-265: Update documentation and README.md 2022-11-29 13:27:12 +02:00
4bb23def42 Update server 2022-11-29 11:32:03 +02:00
3 changed files with 64 additions and 111 deletions

View File

@ -22,17 +22,20 @@
2. Run the `npm start:prod` command to start the server in production mode. 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 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 - The web client can be accessed using the /sfu path
ex: http://localhost:3000/sfu/?assetId=1&&accountId=1&producer=true&assetName=Adi&assetType=linx 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 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 accountId = account id of the unit on which you are doing the test
producer = it will always be true because you are the producer 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) (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 assetName = asset name of the unit on which you are doing the test
assetType = asset type 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 ### 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`

View File

@ -20373,7 +20373,6 @@ console.log('[URL] ASSET_ID', ASSET_ID, '| ACCOUNT_ID', ACCOUNT_ID, '| callId',
console.log('🟩 config', config) console.log('🟩 config', config)
let socket, hub let socket, hub
let doIHaveAudio = false
let device let device
let rtpCapabilities let rtpCapabilities
let producerTransport let producerTransport
@ -20488,8 +20487,6 @@ const streamSuccess = (stream) => {
videoParams = { videoParams = {
track: videoTrack, track: videoTrack,
// codec : device.rtpCapabilities.codecs.find((codec) => codec.mimeType.toLowerCase() === 'video/vp9'),
// codec : 'video/vp9',
...videoParams ...videoParams
} }
@ -20500,14 +20497,6 @@ const streamSuccess = (stream) => {
console.log('[streamSuccess] videoParams', videoParams, ' | audioParams', audioParams); console.log('[streamSuccess] videoParams', videoParams, ' | audioParams', audioParams);
goConnect() goConnect()
// console.log('[streamSuccess]');
// localVideo.srcObject = stream
// const track = stream.getVideoTracks()[0]
// videoParams = {
// track,
// ...videoParams
// }
// goConnect()
} }
const getLocalStream = () => { const getLocalStream = () => {
@ -20527,23 +20516,9 @@ const getLocalStream = () => {
navigator.permissions.query( navigator.permissions.query(
{ name: 'microphone' } { name: 'microphone' }
).then(function(permissionStatus) { ).then((permissionStatus) =>{
console.log('🟨 [PERMISSION] permissionStatus', permissionStatus); // granted, denied, prompt
console.log('🟨 [PERMISSION] onchange1', permissionStatus.state); // granted, denied, prompt // It will block the code from execution and display "Permission denied" if we don't have microphone permissions
// If he has entered before, the saved access is already saved
if (permissionStatus === 'grated') {
doIHaveAudio = true;
}
// If it is the first time client enter and give permission
permissionStatus.onchange = function() {
console.log('🟨 [PERMISSION] onchange2', this.state);
if (this.state === 'grated') {
// doIHaveAudio = true;
}
}
}) })
} }
@ -20562,7 +20537,6 @@ const goCreateTransport = () => {
// server side to send/recive media // server side to send/recive media
const createDevice = async () => { const createDevice = async () => {
try { try {
console.log('[createDevice] 1 device', device);
device = new mediasoupClient.Device() device = new mediasoupClient.Device()
// https://mediasoup.org/documentation/v3/mediasoup-client/api/#device-load // https://mediasoup.org/documentation/v3/mediasoup-client/api/#device-load
@ -20573,7 +20547,7 @@ const createDevice = async () => {
}) })
console.log('Device RTP Capabilities', device.rtpCapabilities) console.log('Device RTP Capabilities', device.rtpCapabilities)
console.log('[createDevice] 2 device', device); console.log('[createDevice] device', device);
// once the device loads, create transport // once the device loads, create transport
goCreateTransport() goCreateTransport()
@ -20645,7 +20619,7 @@ const createSendTransport = () => {
console.log('[produce] parameters', parameters) console.log('[produce] parameters', parameters)
try { try {
// tell the server to create a Producer // Tell the server to create a Producer
// with the following parameters and produce // with the following parameters and produce
// and expect back a server side producer id // and expect back a server side producer id
// see server's socket.on('transport-produce', ...) // see server's socket.on('transport-produce', ...)
@ -20671,14 +20645,16 @@ const connectSendTransport = async () => {
console.log('[connectSendTransport] producerTransport'); console.log('[connectSendTransport] producerTransport');
// we now call produce() to instruct the producer transport // We now call produce() to instruct the producer transport
// to send media to the Router // to send media to the Router
// https://mediasoup.org/documentation/v3/mediasoup-client/api/#transport-produce // https://mediasoup.org/documentation/v3/mediasoup-client/api/#transport-produce
// this action will trigger the 'connect' and 'produce' events above // this action will trigger the 'connect' and 'produce' events above
console.log('videoParams', videoParams); // Produce video
producerVideo = await producerTransport.produce(videoParams) producerVideo = await producerTransport.produce(videoParams)
console.log('videoParams', videoParams);
console.log('producerVideo', producerVideo); console.log('producerVideo', producerVideo);
producerVideo.on('trackended', () => { producerVideo.on('trackended', () => {
console.log('track ended') console.log('track ended')
// close video track // close video track
@ -20689,21 +20665,20 @@ const connectSendTransport = async () => {
// close video track // close video track
}) })
// Video is mandatory, but audio may not be included // Produce audio
// if (doIHaveAudio) { producerAudio = await producerTransport.produce(audioParams)
console.log('audioParams', audioParams); console.log('audioParams', audioParams);
producerAudio = await producerTransport.produce(audioParams) console.log('producerAudio', producerAudio);
console.log('producerAudio', producerAudio);
producerAudio.on('trackended', () => { producerAudio.on('trackended', () => {
console.log('track ended') console.log('track ended')
// close video track // close audio track
}) })
producerAudio.on('transportclose', () => { producerAudio.on('transportclose', () => {
console.log('transport ended') console.log('transport ended')
// close video track // close audio track
}) })
// }
const answer = { const answer = {
origin_asset_id: ASSET_ID, origin_asset_id: ASSET_ID,
@ -20713,7 +20688,7 @@ const connectSendTransport = async () => {
origin_asset_type_name: ASSET_TYPE, origin_asset_type_name: ASSET_TYPE,
origin_asset_name: ASSET_NAME, origin_asset_name: ASSET_NAME,
video_call_id: callId, video_call_id: callId,
answer: 'accepted', // answer: 'rejected' answer: 'accepted', // answer: accepted/rejected
}; };
console.log('SEND answer', answer); console.log('SEND answer', answer);
@ -20729,7 +20704,7 @@ const connectSendTransport = async () => {
const createRecvTransport = async () => { const createRecvTransport = async () => {
console.log('createRecvTransport'); console.log('createRecvTransport');
// see server's socket.on('consume', sender?, ...) // See server's socket.on('consume', sender?, ...)
// this is a call from Consumer, so sender = false // this is a call from Consumer, so sender = false
await socket.emit('createWebRtcTransport', { sender: false, callId }, ({ params }) => { await socket.emit('createWebRtcTransport', { sender: false, callId }, ({ params }) => {
// The server sends back params needed // The server sends back params needed
@ -20741,13 +20716,13 @@ const createRecvTransport = async () => {
console.log('[createRecvTransport] params', params) console.log('[createRecvTransport] params', params)
// creates a new WebRTC Transport to receive media // Creates a new WebRTC Transport to receive media
// based on server's consumer transport params // based on server's consumer transport params
// https://mediasoup.org/documentation/v3/mediasoup-client/api/#device-createRecvTransport // https://mediasoup.org/documentation/v3/mediasoup-client/api/#device-createRecvTransport
consumerTransport = device.createRecvTransport(params) consumerTransport = device.createRecvTransport(params)
// https://mediasoup.org/documentation/v3/communication-between-client-and-server/#producing-media // https://mediasoup.org/documentation/v3/communication-between-client-and-server/#producing-media
// this event is raised when a first call to transport.produce() is made // This event is raised when a first call to transport.produce() is made
// see connectRecvTransport() below // see connectRecvTransport() below
consumerTransport.on('connect', async ({ dtlsParameters }, callback, errback) => { consumerTransport.on('connect', async ({ dtlsParameters }, callback, errback) => {
try { try {
@ -20781,7 +20756,7 @@ const resetCallSettings = () => {
const connectRecvTransport = async () => { const connectRecvTransport = async () => {
console.log('connectRecvTransport'); console.log('connectRecvTransport');
// for consumer, we need to tell the server first // For consumer, we need to tell the server first
// to create a consumer based on the rtpCapabilities and consume // to create a consumer based on the rtpCapabilities and consume
// if the router can consume, it will send back a set of params as below // if the router can consume, it will send back a set of params as below
await socket.emit('consume', { await socket.emit('consume', {
@ -20793,7 +20768,7 @@ const connectRecvTransport = async () => {
return return
} }
// then consume with the local consumer transport // Then consume with the local consumer transport
// which creates a consumer // which creates a consumer
consumer = await consumerTransport.consume({ consumer = await consumerTransport.consume({
id: params.id, id: params.id,

View File

@ -15,7 +15,6 @@ console.log('[URL] ASSET_ID', ASSET_ID, '| ACCOUNT_ID', ACCOUNT_ID, '| callId',
console.log('🟩 config', config) console.log('🟩 config', config)
let socket, hub let socket, hub
let doIHaveAudio = false
let device let device
let rtpCapabilities let rtpCapabilities
let producerTransport let producerTransport
@ -130,8 +129,6 @@ const streamSuccess = (stream) => {
videoParams = { videoParams = {
track: videoTrack, track: videoTrack,
// codec : device.rtpCapabilities.codecs.find((codec) => codec.mimeType.toLowerCase() === 'video/vp9'),
// codec : 'video/vp9',
...videoParams ...videoParams
} }
@ -142,14 +139,6 @@ const streamSuccess = (stream) => {
console.log('[streamSuccess] videoParams', videoParams, ' | audioParams', audioParams); console.log('[streamSuccess] videoParams', videoParams, ' | audioParams', audioParams);
goConnect() goConnect()
// console.log('[streamSuccess]');
// localVideo.srcObject = stream
// const track = stream.getVideoTracks()[0]
// videoParams = {
// track,
// ...videoParams
// }
// goConnect()
} }
const getLocalStream = () => { const getLocalStream = () => {
@ -169,23 +158,9 @@ const getLocalStream = () => {
navigator.permissions.query( navigator.permissions.query(
{ name: 'microphone' } { name: 'microphone' }
).then(function(permissionStatus) { ).then((permissionStatus) =>{
console.log('🟨 [PERMISSION] permissionStatus', permissionStatus); // granted, denied, prompt
console.log('🟨 [PERMISSION] onchange1', permissionStatus.state); // granted, denied, prompt // It will block the code from execution and display "Permission denied" if we don't have microphone permissions
// If he has entered before, the saved access is already saved
if (permissionStatus === 'grated') {
doIHaveAudio = true;
}
// If it is the first time client enter and give permission
permissionStatus.onchange = function() {
console.log('🟨 [PERMISSION] onchange2', this.state);
if (this.state === 'grated') {
// doIHaveAudio = true;
}
}
}) })
} }
@ -204,7 +179,6 @@ const goCreateTransport = () => {
// server side to send/recive media // server side to send/recive media
const createDevice = async () => { const createDevice = async () => {
try { try {
console.log('[createDevice] 1 device', device);
device = new mediasoupClient.Device() device = new mediasoupClient.Device()
// https://mediasoup.org/documentation/v3/mediasoup-client/api/#device-load // https://mediasoup.org/documentation/v3/mediasoup-client/api/#device-load
@ -215,7 +189,7 @@ const createDevice = async () => {
}) })
console.log('Device RTP Capabilities', device.rtpCapabilities) console.log('Device RTP Capabilities', device.rtpCapabilities)
console.log('[createDevice] 2 device', device); console.log('[createDevice] device', device);
// once the device loads, create transport // once the device loads, create transport
goCreateTransport() goCreateTransport()
@ -287,7 +261,7 @@ const createSendTransport = () => {
console.log('[produce] parameters', parameters) console.log('[produce] parameters', parameters)
try { try {
// tell the server to create a Producer // Tell the server to create a Producer
// with the following parameters and produce // with the following parameters and produce
// and expect back a server side producer id // and expect back a server side producer id
// see server's socket.on('transport-produce', ...) // see server's socket.on('transport-produce', ...)
@ -313,14 +287,16 @@ const connectSendTransport = async () => {
console.log('[connectSendTransport] producerTransport'); console.log('[connectSendTransport] producerTransport');
// we now call produce() to instruct the producer transport // We now call produce() to instruct the producer transport
// to send media to the Router // to send media to the Router
// https://mediasoup.org/documentation/v3/mediasoup-client/api/#transport-produce // https://mediasoup.org/documentation/v3/mediasoup-client/api/#transport-produce
// this action will trigger the 'connect' and 'produce' events above // this action will trigger the 'connect' and 'produce' events above
console.log('videoParams', videoParams); // Produce video
producerVideo = await producerTransport.produce(videoParams) producerVideo = await producerTransport.produce(videoParams)
console.log('videoParams', videoParams);
console.log('producerVideo', producerVideo); console.log('producerVideo', producerVideo);
producerVideo.on('trackended', () => { producerVideo.on('trackended', () => {
console.log('track ended') console.log('track ended')
// close video track // close video track
@ -331,21 +307,20 @@ const connectSendTransport = async () => {
// close video track // close video track
}) })
// Video is mandatory, but audio may not be included // Produce audio
// if (doIHaveAudio) { producerAudio = await producerTransport.produce(audioParams)
console.log('audioParams', audioParams); console.log('audioParams', audioParams);
producerAudio = await producerTransport.produce(audioParams) console.log('producerAudio', producerAudio);
console.log('producerAudio', producerAudio);
producerAudio.on('trackended', () => { producerAudio.on('trackended', () => {
console.log('track ended') console.log('track ended')
// close video track // close audio track
}) })
producerAudio.on('transportclose', () => { producerAudio.on('transportclose', () => {
console.log('transport ended') console.log('transport ended')
// close video track // close audio track
}) })
// }
const answer = { const answer = {
origin_asset_id: ASSET_ID, origin_asset_id: ASSET_ID,
@ -355,7 +330,7 @@ const connectSendTransport = async () => {
origin_asset_type_name: ASSET_TYPE, origin_asset_type_name: ASSET_TYPE,
origin_asset_name: ASSET_NAME, origin_asset_name: ASSET_NAME,
video_call_id: callId, video_call_id: callId,
answer: 'accepted', // answer: 'rejected' answer: 'accepted', // answer: accepted/rejected
}; };
console.log('SEND answer', answer); console.log('SEND answer', answer);
@ -371,7 +346,7 @@ const connectSendTransport = async () => {
const createRecvTransport = async () => { const createRecvTransport = async () => {
console.log('createRecvTransport'); console.log('createRecvTransport');
// see server's socket.on('consume', sender?, ...) // See server's socket.on('consume', sender?, ...)
// this is a call from Consumer, so sender = false // this is a call from Consumer, so sender = false
await socket.emit('createWebRtcTransport', { sender: false, callId }, ({ params }) => { await socket.emit('createWebRtcTransport', { sender: false, callId }, ({ params }) => {
// The server sends back params needed // The server sends back params needed
@ -383,13 +358,13 @@ const createRecvTransport = async () => {
console.log('[createRecvTransport] params', params) console.log('[createRecvTransport] params', params)
// creates a new WebRTC Transport to receive media // Creates a new WebRTC Transport to receive media
// based on server's consumer transport params // based on server's consumer transport params
// https://mediasoup.org/documentation/v3/mediasoup-client/api/#device-createRecvTransport // https://mediasoup.org/documentation/v3/mediasoup-client/api/#device-createRecvTransport
consumerTransport = device.createRecvTransport(params) consumerTransport = device.createRecvTransport(params)
// https://mediasoup.org/documentation/v3/communication-between-client-and-server/#producing-media // https://mediasoup.org/documentation/v3/communication-between-client-and-server/#producing-media
// this event is raised when a first call to transport.produce() is made // This event is raised when a first call to transport.produce() is made
// see connectRecvTransport() below // see connectRecvTransport() below
consumerTransport.on('connect', async ({ dtlsParameters }, callback, errback) => { consumerTransport.on('connect', async ({ dtlsParameters }, callback, errback) => {
try { try {
@ -423,7 +398,7 @@ const resetCallSettings = () => {
const connectRecvTransport = async () => { const connectRecvTransport = async () => {
console.log('connectRecvTransport'); console.log('connectRecvTransport');
// for consumer, we need to tell the server first // For consumer, we need to tell the server first
// to create a consumer based on the rtpCapabilities and consume // to create a consumer based on the rtpCapabilities and consume
// if the router can consume, it will send back a set of params as below // if the router can consume, it will send back a set of params as below
await socket.emit('consume', { await socket.emit('consume', {
@ -435,7 +410,7 @@ const connectRecvTransport = async () => {
return return
} }
// then consume with the local consumer transport // Then consume with the local consumer transport
// which creates a consumer // which creates a consumer
consumer = await consumerTransport.consume({ consumer = await consumerTransport.consume({
id: params.id, id: params.id,