Skip to content

Commit

Permalink
[mirotalksfu] - add room duration
Browse files Browse the repository at this point in the history
  • Loading branch information
miroslavpejic85 committed Jan 3, 2025
1 parent 0c1dad2 commit b5d4a42
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 34 deletions.
1 change: 1 addition & 0 deletions app/api/join/join.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ async function getJoin() {
screen: true,
hide: false,
notify: true,
duration: 'unlimited',
token: {
username: 'username',
password: 'password',
Expand Down
3 changes: 2 additions & 1 deletion app/api/join/join.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

$API_KEY_SECRET = "mirotalksfu_default_secret";
$MIROTALK_URL = "https://sfu.mirotalk.com/api/v1/join";
// $MIROTALK_URL = "http://localhost:3010/api/v1/join";
//$MIROTALK_URL = "http://localhost:3010/api/v1/join";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $MIROTALK_URL);
Expand All @@ -25,6 +25,7 @@
"screen" => true,
"hide" => false,
"notify" => true,
"duration" => "unlimited",
"token" => array(
"username" => "username",
"password" => "password",
Expand Down
1 change: 1 addition & 0 deletions app/api/join/join.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"screen": "true",
"hide": "false",
"notify": "true",
"duration": "unlimited",
"token": {
"username": "username",
"password": "password",
Expand Down
2 changes: 1 addition & 1 deletion app/api/join/join.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ MIROTALK_URL="https://sfu.mirotalk.com/api/v1/join"
curl $MIROTALK_URL \
--header "authorization: $API_KEY_SECRET" \
--header "Content-Type: application/json" \
--data '{"room":"test","roomPassword":"false","name":"mirotalksfu","audio":"true","video":"true","screen":"false","hide":"false","notify":"true","token":{"username":"username","password":"password","presenter":"true", "expire":"1h"}}' \
--data '{"room":"test","roomPassword":"false","name":"mirotalksfu","audio":"true","video":"true","screen":"false","hide":"false","notify":"true","duration":"unlimited","token":{"username":"username","password":"password","presenter":"true", "expire":"1h"}}' \
--request POST
3 changes: 3 additions & 0 deletions app/api/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ definitions:
notify:
type: boolean
default: false
duration:
type: string
default: 'unlimited'
token:
$ref: '#/definitions/TokenRequest'
TokenRequest:
Expand Down
9 changes: 4 additions & 5 deletions app/src/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ dev dependencies: {
* @license For commercial or closed source, contact us at [email protected] or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - [email protected]
* @version 1.6.74
* @version 1.6.75
*
*/

Expand Down Expand Up @@ -513,12 +513,11 @@ function startServer() {

log.debug('Direct Join', req.query);

// http://localhost:3010/join?room=test&roomPassword=0&name=mirotalksfu&audio=1&video=1&screen=0&hide=0&notify=1
// http://localhost:3010/join?room=test&roomPassword=0&name=mirotalksfu&audio=1&video=1&screen=0&hide=0&notify=1&duration=00:00:20
// http://localhost:3010/join?room=test&roomPassword=0&name=mirotalksfu&audio=1&video=1&screen=0&hide=0&notify=0&token=token

const { room, roomPassword, name, audio, video, screen, hide, notify, token, isPresenter } = checkXSS(
req.query,
);
const { room, roomPassword, name, audio, video, screen, hide, notify, duration, token, isPresenter } =
checkXSS(req.query);

if (!room) {
log.warn('/join/params room empty', room);
Expand Down
4 changes: 3 additions & 1 deletion app/src/ServerApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ module.exports = class ServerApi {

getJoinURL(data) {
// Get data
const { room, roomPassword, name, audio, video, screen, hide, notify, token } = data;
const { room, roomPassword, name, audio, video, screen, hide, notify, duration, token } = data;

const roomValue = room || uuidV4();
const nameValue = name || 'User-' + this.getRandomNumber();
Expand All @@ -78,6 +78,7 @@ module.exports = class ServerApi {
const screenValue = screen || false;
const hideValue = hide || false;
const notifyValue = notify || false;
const durationValue = duration || 'unlimited';
const jwtToken = token ? '&token=' + this.getToken(token) : '';

const joinURL =
Expand All @@ -92,6 +93,7 @@ module.exports = class ServerApi {
`&screen=${screenValue}` +
`&hide=${hideValue}` +
`&notify=${notifyValue}` +
`&duration=${durationValue}` +
jwtToken;

return joinURL;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mirotalksfu",
"version": "1.6.74",
"version": "1.6.75",
"description": "WebRTC SFU browser-based video calls",
"main": "Server.js",
"scripts": {
Expand Down
97 changes: 75 additions & 22 deletions public/js/Room.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ if (location.href.substr(0, 5) !== 'https') location.href = 'https' + location.h
* @license For commercial or closed source, contact us at [email protected] or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - [email protected]
* @version 1.6.74
* @version 1.6.75
*
*/

Expand Down Expand Up @@ -191,6 +191,7 @@ let chatMessagesId = 0;

let room_id = getRoomId();
let room_password = getRoomPassword();
let room_duration = getRoomDuration();
let peer_name = getPeerName();
let peer_uuid = getPeerUUID();
let peer_token = getPeerToken();
Expand Down Expand Up @@ -440,13 +441,21 @@ function setTippy(elem, content, placement, allowHTML = false) {
}
}

// ####################################################
// HELPERS
// ####################################################

function getQueryParam(param) {
const urlParams = new URLSearchParams(window.location.search);
return filterXSS(urlParams.get(param));
}

// ####################################################
// GET ROOM ID
// ####################################################

function getRoomId() {
let qs = new URLSearchParams(window.location.search);
let queryRoomId = filterXSS(qs.get('room'));
let queryRoomId = getQueryParam('room');
let roomId = queryRoomId ? queryRoomId : location.pathname.substring(6);
if (roomId == '') {
roomId = makeId(12);
Expand Down Expand Up @@ -732,12 +741,11 @@ function hasVideoTrack(mediaStream) {
}

// ####################################################
// API CHECK
// QUERY PARAMS CHECK
// ####################################################

function getScreen() {
let qs = new URLSearchParams(window.location.search);
let screen = filterXSS(qs.get('screen'));
let screen = getQueryParam('screen');
if (screen) {
screen = screen.toLowerCase();
let queryScreen = screen === '1' || screen === 'true';
Expand All @@ -751,8 +759,7 @@ function getScreen() {
}

function getNotify() {
let qs = new URLSearchParams(window.location.search);
let notify = filterXSS(qs.get('notify'));
let notify = getQueryParam('notify');
if (notify) {
notify = notify.toLowerCase();
let queryNotify = notify === '1' || notify === 'true';
Expand All @@ -767,8 +774,7 @@ function getNotify() {
}

function getHideMeActive() {
let qs = new URLSearchParams(window.location.search);
let hide = filterXSS(qs.get('hide'));
let hide = getQueryParam('hide');
let queryHideMe = false;
if (hide) {
hide = hide.toLowerCase();
Expand All @@ -779,8 +785,7 @@ function getHideMeActive() {
}

function isPeerPresenter() {
let qs = new URLSearchParams(window.location.search);
let presenter = filterXSS(qs.get('isPresenter'));
let presenter = getQueryParam('isPresenter');
if (presenter) {
presenter = presenter.toLowerCase();
let queryPresenter = presenter === '1' || presenter === 'true';
Expand All @@ -794,8 +799,7 @@ function isPeerPresenter() {
}

function getPeerName() {
const qs = new URLSearchParams(window.location.search);
const name = filterXSS(qs.get('name'));
const name = getQueryParam('name');
if (isHtml(name)) {
console.log('Direct join', { name: 'Invalid name' });
return 'Invalid name';
Expand All @@ -815,8 +819,7 @@ function getPeerUUID() {

function getPeerToken() {
if (window.sessionStorage.peer_token) return window.sessionStorage.peer_token;
let qs = new URLSearchParams(window.location.search);
let token = filterXSS(qs.get('token'));
let token = getQueryParam('token');
let queryToken = false;
if (token) {
queryToken = token;
Expand All @@ -826,8 +829,7 @@ function getPeerToken() {
}

function getRoomPassword() {
let qs = new URLSearchParams(window.location.search);
let roomPassword = filterXSS(qs.get('roomPassword'));
let roomPassword = getQueryParam('roomPassword');
if (roomPassword) {
let queryNoRoomPassword = roomPassword === '0' || roomPassword === 'false';
if (queryNoRoomPassword) {
Expand All @@ -839,6 +841,58 @@ function getRoomPassword() {
return false;
}

function getRoomDuration() {
const roomDuration = getQueryParam('duration');

if (isValidDuration(roomDuration)) {
if (roomDuration === 'unlimited') {
console.log('The room has no time limit');
return roomDuration;
}
const timeLimit = timeToMilliseconds(roomDuration);
setTimeout(() => {
Swal.fire({
title: 'Time Limit Reached',
text: 'The room has reached its time limit and will close shortly',
icon: 'warning',
timer: 6000, // 6 seconds
timerProgressBar: true,
showConfirmButton: false,
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
},
willClose: () => {
openURL('/');
},
});
}, timeLimit);

console.log('Direct join', { duration: roomDuration, timeLimit: timeLimit });
return roomDuration;
}
}

function timeToMilliseconds(timeString) {
const [hours, minutes, seconds] = timeString.split(':').map(Number);
return (hours * 3600 + minutes * 60 + seconds) * 1000;
}

function isValidDuration(duration) {
if (duration === 'unlimited') return true;

// Check if the format is HH:MM:SS
const regex = /^(\d{2}):(\d{2}):(\d{2})$/;
const match = duration.match(regex);
if (!match) return false;
const [hours, minutes, seconds] = match.slice(1).map(Number);
// Validate ranges: hours, minutes, and seconds
if (hours < 0 || minutes < 0 || minutes > 59 || seconds < 0 || seconds > 59) {
return false;
}
return true;
}

// ####################################################
// INIT CONFIG
// ####################################################
Expand Down Expand Up @@ -1155,9 +1209,8 @@ function initVideoContainerShow(show = true) {
}

function checkMedia() {
let qs = new URLSearchParams(window.location.search);
let audio = filterXSS(qs.get('audio'));
let video = filterXSS(qs.get('video'));
let audio = getQueryParam('audio');
let video = getQueryParam('video');
if (audio) {
audio = audio.toLowerCase();
let queryPeerAudio = audio === '1' || audio === 'true';
Expand Down Expand Up @@ -4619,7 +4672,7 @@ function showAbout() {
imageUrl: image.about,
customClass: { image: 'img-about' },
position: 'center',
title: 'WebRTC SFU v1.6.74',
title: 'WebRTC SFU v1.6.75',
html: `
<br />
<div id="about">
Expand Down
2 changes: 1 addition & 1 deletion public/js/RoomClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* @license For commercial or closed source, contact us at [email protected] or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - [email protected]
* @version 1.6.74
* @version 1.6.75
*
*/

Expand Down
5 changes: 3 additions & 2 deletions tests/test-ServerAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,15 @@ describe('test-ServerAPI', () => {
screen: false,
hide: false,
notify: false,
duration: '00:30:00',
token: { username: 'user', password: 'pass', presenter: true, expire: '1h' },
};

const tokenStub = sinon.stub(serverApi, 'getToken').returns('testToken');

const result = serverApi.getJoinURL(data);
result.should.equal(
'https://example.com/join?room=room1&roomPassword=password123&name=John%20Doe&audio=true&video=false&screen=false&hide=false&notify=false&token=testToken',
'https://example.com/join?room=room1&roomPassword=password123&name=John%20Doe&audio=true&video=false&screen=false&hide=false&notify=false&duration=00:30:00&token=testToken',
);

tokenStub.restore();
Expand All @@ -202,7 +203,7 @@ describe('test-ServerAPI', () => {

const result = serverApi.getJoinURL({});
result.should.equal(
'https://example.com/join?room=room1&roomPassword=false&name=User-123456&audio=false&video=false&screen=false&hide=false&notify=false',
'https://example.com/join?room=room1&roomPassword=false&name=User-123456&audio=false&video=false&screen=false&hide=false&notify=false&duration=unlimited',
);
});
});
Expand Down

0 comments on commit b5d4a42

Please sign in to comment.