Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117747891
performancetestbench.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
6 KB
Referenced Files
None
Subscribers
None
performancetestbench.js
View Options
process
.
env
.
DEBUG
=
''
const
assert
=
require
(
'assert'
);
let
request
=
require
(
'supertest'
)
const
io
=
require
(
"socket.io-client"
);
const
child_process
=
require
(
"child_process"
);
const
udp
=
require
(
'dgram'
);
const
Roles
=
require
(
'../lib/userRoles'
);
let
recvUdpSocket
let
recvRtcpUdpSocket
let
app
let
processes
=
[];
let
rtpParameters
=
{
codecs
:
[
{
mimeType
:
"video/H264"
,
payloadType
:
125
,
clockRate
:
90000
,
parameters
:
{
"level-asymmetry-allowed"
:
1
,
"packetization-mode"
:
1
,
"profile-level-id"
:
"42e01f"
,
},
},
],
}
function
startFFMPEGStream
(
peers
,
ssrc
)
{
const
cmdProgram
=
"ffmpeg"
;
//Build a video stream per producer
const
streams
=
peers
.
map
((
peer
)
=>
`[select=v:f=rtp:ssrc=
${
ssrc
}
:payload_type=125]rtp://127.0.0.1:
${
peer
.
senderTransportInfo
.
port
}
?rtcpport=
${
peer
.
senderTransportInfo
.
rtcpPort
}
`
);
const
cmdArgStr
=
[
"-i /dev/video0"
,
//We are streaming from the webcam (a looping videofile would be an alternative)
`-c:v h264`
,
//The codec
"-map 0:v:0"
,
"-f tee"
,
//This option allows us to read the source once, encode once, and then output multiple streams
streams
.
join
(
'|'
).
trim
()
].
join
(
" "
).
trim
();
console
.
log
(
`Run command:
${
cmdProgram
}
${
cmdArgStr
}
`
);
let
recProcess
=
child_process
.
spawn
(
cmdProgram
,
cmdArgStr
.
split
(
/\s+/
));
recProcess
.
on
(
"error"
,
(
err
)
=>
{
console
.
error
(
"Recording process error:"
,
err
);
});
recProcess
.
on
(
"exit"
,
(
code
,
signal
)
=>
{
console
.
log
(
"Recording process exit, code: %d, signal: %s"
,
code
,
signal
);
recProcess
=
null
;
});
// FFmpeg writes its logs to stderr
recProcess
.
stderr
.
on
(
"data"
,
(
chunk
)
=>
{
chunk
.
toString
()
.
split
(
/\r?\n/g
)
.
filter
(
Boolean
)
// Filter out empty strings
.
forEach
((
line
)
=>
{
// console.log(line);
});
});
return
recProcess
;
}
async
function
sendRequest
(
socket
,
method
,
data
=
null
)
{
return
await
new
Promise
((
resolve
,
/*reject*/
)
=>
{
socket
.
emit
(
'request'
,
{
method
:
method
,
data
:
data
},
(
error
,
response
)
=>
{
assert
(
!
error
)
resolve
(
response
)
}
)
})
}
async
function
createPeer
(
roomId
,
request
,
receiverPort
,
receiverRtcpPort
)
{
let
signalingSocket
await
request
.
post
(
`/meetmedia/api/sessions/
${
roomId
}
/connection`
)
.
send
({
role
:
Roles
.
PUBLISHER
|
Roles
.
SUBSCRIBER
|
Roles
.
MODERATOR
})
.
expect
(
200
)
.
then
(
async
(
res
)
=>
{
let
data
=
res
.
body
;
const
signalingUrl
=
data
[
'token'
];
signalingSocket
=
io
(
signalingUrl
,
{
path
:
'/meetmedia/signaling'
,
transports
:
[
"websocket"
],
rejectUnauthorized
:
false
});
let
roomReady
=
new
Promise
((
resolve
,
/*reject*/
)
=>
{
signalingSocket
.
once
(
'notification'
,
(
reason
)
=>
{
// console.warn("Received notification", reason)
if
(
reason
[
'method'
]
==
'roomReady'
)
{
resolve
();
}
});
})
signalingSocket
.
connect
();
await
roomReady
})
.
catch
(
err
=>
{
console
.
warn
(
err
);
throw
err
})
//Necessary later for the server to resume the consumer,
//once we join with another peer
signalingSocket
.
on
(
'request'
,
async
(
reason
,
cb
)
=>
{
// console.warn("Received request", reason)
if
(
reason
[
'method'
]
==
'newConsumer'
)
{
cb
();
}
});
//Join
await
sendRequest
(
signalingSocket
,
'join'
,
{
nickname
:
"nickname"
,
rtpCapabilities
:
rtpParameters
})
//Create sending transport
const
senderTransportInfo
=
await
sendRequest
(
signalingSocket
,
'createPlainTransport'
,
{
producing
:
true
,
consuming
:
false
,
})
//Create consuming transport
const
consumerTransportInfo
=
await
sendRequest
(
signalingSocket
,
'createPlainTransport'
,
{
producing
:
false
,
consuming
:
true
,
})
await
sendRequest
(
signalingSocket
,
'connectPlainTransport'
,
{
transportId
:
consumerTransportInfo
.
id
,
ip
:
'127.0.0.1'
,
port
:
receiverPort
,
rtcpPort
:
receiverRtcpPort
,
})
//Create sending producer
await
sendRequest
(
signalingSocket
,
'produce'
,
{
transportId
:
senderTransportInfo
.
id
,
kind
:
'video'
,
rtpParameters
:
{
codecs
:
[
{
mimeType
:
"video/H264"
,
payloadType
:
125
,
clockRate
:
90000
,
parameters
:
{
"level-asymmetry-allowed"
:
1
,
"packetization-mode"
:
1
,
"profile-level-id"
:
"42e01f"
,
},
},
],
encodings
:
[{
ssrc
:
2222
}]
},
appData
:
{
source
:
'webcam'
}
})
return
{
senderTransportInfo
,
consumerTransportInfo
,
signalingSocket
};
}
before
(
function
(
done
)
{
process
.
env
.
SSL_CERT
=
"../../docker/certs/kolab.hosted.com.cert"
process
.
env
.
SSL_KEY
=
"../../docker/certs/kolab.hosted.com.key"
process
.
env
.
REDIS_IP
=
"none"
process
.
env
.
MEDIASOUP_NUM_WORKERS
=
3
process
.
env
.
ROUTER_SCALE_SIZE
=
3
app
=
require
(
'../server.js'
)
request
=
request
(
app
);
recvUdpSocket
=
udp
.
createSocket
(
'udp4'
);
recvUdpSocket
.
on
(
'message'
,
function
(
msg
,
info
){
// console.warn("Received message", msg, info)
});
recvRtcpUdpSocket
=
udp
.
createSocket
(
'udp4'
);
recvRtcpUdpSocket
.
on
(
'message'
,
function
(
msg
,
info
){
// console.warn("Received RTCP message", msg, info)
});
app
.
on
(
"ready"
,
function
(){
done
();
});
});
describe
(
'Testbench'
,
function
()
{
const
roomId
=
"room1"
;
let
peers
=
[];
it
(
'prepare udp sockets'
,
async
()
=>
{
await
new
Promise
(
resolve
=>
recvUdpSocket
.
bind
(
22222
,
'127.0.0.1'
,
resolve
));
await
new
Promise
(
resolve
=>
recvRtcpUdpSocket
.
bind
(
22223
,
'127.0.0.1'
,
resolve
));
});
it
(
'create peers'
,
async
()
=>
{
for
(
var
i
=
0
;
i
<
20
;
i
++
)
{
peers
.
push
(
await
createPeer
(
roomId
,
request
,
recvUdpSocket
.
address
().
port
,
recvRtcpUdpSocket
.
address
().
port
))
}
});
it
(
'start ffmpg stream'
,
async
()
=>
{
processes
.
push
(
startFFMPEGStream
(
peers
,
2222
))
});
it
(
'wait forever'
,
async
()
=>
{
setInterval
(
function
(){
sendRequest
(
peers
[
0
].
signalingSocket
,
'dumpStats'
,
{})
},
5000
)
const
promise
=
new
Promise
((
res
,
_rej
)
=>
{});
return
promise
;
})
});
after
(
function
()
{
for
(
const
process
of
processes
)
{
process
.
kill
()
}
process
.
exit
();
})
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 4, 12:39 AM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18821733
Default Alt Text
performancetestbench.js (6 KB)
Attached To
Mode
rK kolab
Attached
Detach File
Event Timeline