I've been using an electron/react boilerplate for my application, yet I find myself facing a dreaded empty white screen as the console spits the following error message at me repeatedly:
[31308:0413/104846.234:ERROR:CONSOLE(1)] "Extension server error: Operation failed: Permission denied", source: devtools://devtools/bundled/models/extensions/extensions.js (1)
This error suddenly popped up without much warning as it was working fine earlier, though I suspect it might have something to do with changes I made to the ipcRenderer.
Along with this, the following errors pop up in the console: https://gyazo.com/1c3e3f22f65fd6f7db0fd9549969581b
Here's my preload.ts:
contextBridge.exposeInMainWorld('electron', {
ipcRenderer: {
myPing() {
ipcRenderer.send('ipc-example', 'ping');
},
on(channel: string, func: (...args: unknown[]) => void) {
const validChannels = ['ipc-example'];
if (validChannels.includes(channel)) {
const subscription = (_event: IpcRendererEvent, ...args: unknown[]) =>
func(...args);
// Deliberately strip event as it includes `sender`
ipcRenderer.on(channel, subscription);
return () => ipcRenderer.removeListener(channel, subscription);
}
return undefined;
},
once(channel: string, func: (...args: unknown[]) => void) {
const validChannels = ['ipc-example'];
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`
ipcRenderer.once(channel, (_event, ...args) => func(...args));
}
},
},
});
And here's my main.ts:
/**
* This module executes inside of electron's main process. You can start
* electron renderer process from here and communicate with the other processes
* through IPC.
*
* When running `npm run build` or `npm run build:main`, this file is compiled to
* `./src/main.js` using webpack. This gives us some performance wins.
*/
import path from 'path';
import { app, BrowserWindow, shell, ipcMain } from 'electron';
import { autoUpdater } from 'electron-updater';
import log from 'electron-log';
import MenuBuilder from './components/containers/menu';
import { resolveHtmlPath } from './main/util';
export default class AppUpdater {
constructor() {
log.transports.file.level = 'info';
autoUpdater.logger = log;
autoUpdater.checkForUpdatesAndNotify();
}
}
let mainWindow: BrowserWindow | null = null;
ipcMain.on('ipc-example', async (event, arg) => {
const msgTemplate = (pingPong: string) => `IPC test: ${pingPong}`;
console.log(msgTemplate(arg));
event.reply('ipc-example', msgTemplate('pong'));
});
if (process.env.NODE_ENV === 'production') {
const sourceMapSupport = require('source-map-support');
sourceMapSupport.install();
}
const isDevelopment =
process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true';
if (isDevelopment) {
require('electron-debug')();
}
const installExtensions = async () => {
const installer = require('electron-devtools-installer');
const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
const extensions = ['REACT_DEVELOPER_TOOLS'];
return installer
.default(
extensions.map((name) => installer[name]),
forceDownload
)
.catch(console.log);
};
const createWindow = async () => {
if (isDevelopment) {
await installExtensions();
}
const RESOURCES_PATH = app.isPackaged
? path.join(process.resourcesPath, 'assets')
: path.join(__dirname, '../../assets');
const getAssetPath = (...paths: string[]): string => {
return path.join(RESOURCES_PATH, ...paths);
};
mainWindow = new BrowserWindow({
show: false,
width: 1024,
height: 728,
icon: getAssetPath('icon.png'),
webPreferences: {
contextIsolation: true,
preload: app.isPackaged
? path.join(__dirname, 'preload.js')
: path.join(__dirname, '../../.erb/dll/preload.js'),
},
});
mainWindow.loadURL(resolveHtmlPath('index.html'));
mainWindow.on('ready-to-show', () => {
if (!mainWindow) {
throw new Error('"mainWindow" is not defined');
}
if (process.env.START_MINIMIZED) {
mainWindow.minimize();
} else {
mainWindow.show();
}
});
mainWindow.on('closed', () => {
mainWindow = null;
});
const menuBuilder = new MenuBuilder(mainWindow);
menuBuilder.buildMenu();
// Open urls in the user's browser
mainWindow.webContents.setWindowOpenHandler((edata) => {
shell.openExternal(edata.url);
return { action: 'deny' };
});
// Remove this if your app does not use auto updates
// eslint-disable-next-line
new AppUpdater();
};
/**
* Add event listeners...
*/
app.on('window-all-closed', () => {
// Respect the OSX convention of having the application in memory even
// after all windows have been closed
if (process.platform !== 'darwin') {
app.quit();
}
});
app
.whenReady()
.then(() => {
createWindow();
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) createWindow();
});
})
.catch(console.log);
Does this error seem familiar to anyone? I've no clue how to go about solving this.
Related
I recently started writing Discordbots and just can't seem to get anywhere pushing the slash commands. I already have a handler file (pushSlash.js) but for some reason the commands are never loaded or I get an error in the console (mostly simply this: chalk.blue is not a function). My bot also doesn't get the badge that it supports slash commands.
Can anyone help me further?
Here is my code (pushSlash.js):
module.exports = (client) => {
const fs = require('fs');
const { PermissionsBitField } = require('discord.js');
const { Routes } = require('discord-api-types/v9');
const { REST } = require('#discordjs/rest');
const AsciiTable = require('ascii-table');
const table = new AsciiTable().setHeading('Slash Commands', 'Stats').setBorder('|', '=', "0", "0");
const TOKEN = process.env.BOT_TOKEN;
const CLIENT_ID = process.env.CLIENT_ID;
const rest = new REST({ version: '9' }).setToken(TOKEN);
import( 'chalk').then(chalk => {
const slashCommands = [];
fs.readdirSync('/home/container/src/slashCommands/').forEach(async dir => {
const files = fs.readdirSync(`/home/container/src/slashCommands/${dir}/`).filter(file => file.endsWith('.js'));
for(const file of files) {
const slashCommand = require(`/home/container/src/slashCommands/${dir}/${file}`);
slashCommands.push({
name: slashCommand.name,
description: slashCommand.description,
options: slashCommand.options ? slashCommand.options : null,
default_permission: slashCommand.default_permission ? slashCommand.default_permission : null,
default_member_permissions: slashCommand.default_member_permissions ? PermissionsBitField.resolve(slashCommand.default_member_permissions).toString() : null
});
if(slashCommand.name) {
client.slashCommands.set(slashCommand.name, slashCommand);
table.addRow(file.split('.js')[0], '✅');
} else {
table.addRow(file.split('.js')[0], '⛔');
}
}
});
console.log(chalk.blue(table.toString()));
(async () => {
try {
await rest.put(
process.env.GUILD_ID ?
Routes.applicationGuildCommands(CLIENT_ID, process.env.GUILD_ID) :
Routes.applicationCommands(CLIENT_ID),
{ body: slashCommands }
);
console.log(chalk.green('Successfully registered application commands.'));
} catch (error) {
console.log(error);
}
})();
});
};
I've already tried everything possible, but since I'm relatively new to discord.js, I don't know that much yet either.
Actually everything should work and exactly 2 different commands should be loaded, but I only get error messages or the handler was loaded on console but nothing is displayed on Discord.
first download chalk#4.1.2 with
npm install chalk#4.1.2
and import chalk normally.
const chalk = require('chalk')
There your code modified version:
module.exports = (client) => {
const fs = require('fs');
const { PermissionsBitField } = require('discord.js');
const { Routes } = require('discord-api-types/v9');
const { REST } = require('#discordjs/rest');
const AsciiTable = require('ascii-table');
const table = new AsciiTable().setHeading('Slash Commands', 'Stats').setBorder('|', '=', "0", "0");
const TOKEN = process.env.BOT_TOKEN;
const CLIENT_ID = process.env.CLIENT_ID;
const rest = new REST({ version: '9' }).setToken(TOKEN);
// Imported chalk normally
const chalk = require('chalk')
// removed `import( 'chalk').then(chalk => {})`
const slashCommands = [];
fs.readdirSync('/home/container/src/slashCommands/').forEach(async dir => {
const files = fs.readdirSync(`/home/container/src/slashCommands/${dir}/`).filter(file => file.endsWith('.js'));
for(const file of files) {
const slashCommand = require(`/home/container/src/slashCommands/${dir}/${file}`);
slashCommands.push({
name: slashCommand.name,
description: slashCommand.description,
options: slashCommand.options ? slashCommand.options : null,
default_permission: slashCommand.default_permission ? slashCommand.default_permission : null,
default_member_permissions: slashCommand.default_member_permissions ? PermissionsBitField.resolve(slashCommand.default_member_permissions).toString() : null
});
if(slashCommand.name) {
client.slashCommands.set(slashCommand.name, slashCommand);
table.addRow(file.split('.js')[0], '✅');
} else {
table.addRow(file.split('.js')[0], '⛔');
}
}
});
console.log(chalk.blue(table.toString()));
(async () => {
try {
await rest.put(
process.env.GUILD_ID ?
Routes.applicationGuildCommands(CLIENT_ID, process.env.GUILD_ID) :
Routes.applicationCommands(CLIENT_ID),
{ body: slashCommands }
);
console.log(chalk.green('Successfully registered application commands.'));
} catch (error) {
console.log(error);
}
})();
};
const { app, BrowserWindow, ipcMain, dialog, screen,Tray } = require('electron');
try {
require('electron-reloader')(module)
} catch (_) { }
const path = require('path')
let deeplinkingUrl;
let mainWindow;
const createWindow = () => {
let { width, height } = screen.getPrimaryDisplay().size
// Create the browser window.
mainWindow = new BrowserWindow({
width: width,
height: height,
minWidth: width,
minHeight: height,
productName: "abc",
copyright: "Copyright © 2022 ${author}",
// mac: {
// icon: "./img/abc_256x256px.ico"
// },
icon: __dirname + "/img/icon.ico",
// icon: "./img/abc_256x256px.ico",
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true,
contextIsolation: false,
devTools: false,
}
})
mainWindow.setClosable(false);
mainWindow.setMenuBarVisibility(false);
mainWindow.maximize();
mainWindow.setMovable(false);
mainWindow.setResizable(false);
if (process.platform == 'win32') {
// Keep only command line / deep linked arguments
deeplinkingUrl = process.argv.slice(1)
}
logEverywhere("createWindow# " + deeplinkingUrl)
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
//tray
let tray = null;
mainWindow.on('minimize', function (event) {
event.preventDefault();
mainWindow.hide();
tray = createTray();
});
mainWindow.on('restore', function (event) {
mainWindow.maximize();
mainWindow.show();
tray.destroy();
});
function createTray() {
let appIcon = new Tray(path.join(__dirname + "/img/icon.ico"));
appIcon.on('click', function (event) {
mainWindow.show();
});
appIcon.setToolTip('abc');
return appIcon;
}
}
app.whenReady().then(() => {
createWindow()
if (isDev && process.platform === 'win32') {
// Set the path of electron.exe and your app.
// These two additional parameters are only available on windows.
// Setting this is required to get this working in dev mode.
app.setAsDefaultProtocolClient('pro', process.execPath, [
resolve(process.argv[1])
]);
} else {
app.setAsDefaultProtocolClient('pro');
}
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
app.on('open-url', function (event, url) {
event.preventDefault();
deeplinkingUrl = url;})
})
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
app.quit();
return;
} else {
app.on('second-instance', (e, argv) => {
if (process.platform !== 'darwin') {
// Find the arg that is our custom protocol url and store it
deeplinkingUrl = argv.find((arg) => arg.startsWith('custom://'));
}
if (myWindow) {
if (myWindow.isMinimized()) myWindow.restore();
myWindow.focus();
}
});
}
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
function logEverywhere(s) {
console.log(s)
if (mainWindow && mainWindow.webContents) {
mainWindow.webContents.executeJavaScript(`console.log("${s}")`)
}
}
//to allow self signed certificate
app.on('certificate-error', (event, webContents, url, error, certificate, callback) => {
// Verification logic.
event.preventDefault()
callback(true)
})
ipcMain.handle('download', async (someArgument) => {
const result = await download(someArgument)
return result;
})
const download = async (data) => {
let value = 100;
console.log(data.name)
dialog.showSaveDialog({
title: 'Select the File Path to save',
defaultPath: path.join(__dirname, data.name + '.p12'),
buttonLabel: 'Save',
filters: [
{
name: 'Personal Information Exchnage',
extensions: ['.p12']
}
],
properties: []
}).then((path) => {
value = 1;
console.log('success')
mainWindow.webContents.send('success', path);
}).catch((value) => {
value = 2;
mainWindow.webContents.send('failed', path);
console.log('error')
});
return value;
}
This code throws some error when I type 'pro://something' in the browser.
Erorr description: Error launching app, unable to find Electron app at C:\Windows\system32\pro:\something
I have also tried some other code which opens my app but in a different window.
I want to open the App but in the existing window of my app.
I have an application built with react and electron, here is the issue that is occurring.
Sometimes when launching the application it will have an uncaught exception because of some IPC communication that failed.
I added a handler for this in my electron entry point file according to the documentation. However, when it relaunches it does not launch MY application. It simply displays some electron template window.
Here is the handler I'm using:
process.on("uncaughtException", function (err) {
//log the message and stack trace
log.warn("uncaught Exception: ", err);
//relaunch the app
app.relaunch({ args: [] });
app.exit(0);
handleLaunch(tray, window, store, __dirname);
});
The handleLaunch function is as such:
// Library Imports
const { app, BrowserWindow, dialog } = require("electron");
const { autoUpdater } = require("electron-updater");
const log = require("electron-log");
//Functions
const { createIpcBusBridge } = require("../ipc/createIpcBusBridge");
const { createWindow } = require("../window/createWindow");
const { createTray } = require("../tray/createTray");
const handleLaunch = (tray, window, store, directoryName) => {
const isDev = !app.isPackaged;
if (isDev === true) {
const reactDevToolsId = "fmkadmapgofadopljbjfkapdkoienihi";
const {
default: installExtension,
REDUX_DEVTOOLS,
} = require("electron-devtools-installer");
installExtension([REDUX_DEVTOOLS, reactDevToolsId])
.then((name) => console.log(`Added Extension: ${name}`))
.catch((err) => console.log("An error occurred: ", err));
}
log.info("CREATING WINDOW...........");
window = createWindow(directoryName, process, store, isDev);
if (tray !== undefined) {
tray.destroy();
}
tray = createTray(window, directoryName, process);
createIpcBusBridge();
app.on("activate", function () {
/*
On macOS it's common to re-create a window in the app when the
dock icon is clicked and there are no other windows open.
*/
if (BrowserWindow.getAllWindows().length === 0)
createWindow(window, tray, directoryName, process, store);
});
if (isDev === false) {
autoUpdater.on("update-available", (_event, releaseNotes, releaseName) => {
const dialogOpts = {
type: "info",
buttons: ["Ok"],
title: "Application Update",
message: process.platform === "win32" ? releaseNotes : releaseName,
detail: "A new version is being downloaded.",
};
dialog.showMessageBox(dialogOpts, (response) => {});
});
autoUpdater.on("update-downloaded", (_event, releaseNotes, releaseName) => {
const dialogOpts = {
type: "info",
buttons: ["Restart", "Later"],
title: "Application Update",
message: process.platform === "win32" ? releaseNotes : releaseName,
detail:
"A new version has been downloaded. Restart the application to apply the updates.",
};
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) autoUpdater.quitAndInstall();
});
});
}
};
module.exports = { handleLaunch };
Here is the createWindow function as requested by Kiran Maniya
// Library Imports
const { BrowserWindow, ipcMain } = require("electron");
const path = require("path");
const url = require("url");
const log = require("electron-log");
// Functions
const { handleResolutionPref } = require("./handleResolutionPref");
const { handlePositionPref } = require("./handlePositionPref");
const { maximizeWindow } = require("./maximizeWindow");
const { minimizeWindow } = require("./minimizeWindow");
const { closeWindow } = require("./closeWindow");
const createWindow = (directoryName, process, store, isDev) => {
try {
const [screenWidth, screenHeight] = handleResolutionPref(store);
const [screenXCoordinate, screenYCoordinate, isScreenPositionCustom] =
handlePositionPref(store);
let window = null;
const browserWindowOptions = {
width: screenWidth,
height: screenHeight,
frame: false,
fullscreenable: true,
resizable: true,
transparent: false,
webPreferences: {
preload: path.join(directoryName, "preload.bundle.js"),
contextIsolation: false,
nodeIntegration: true,
sandbox: false,
webSecurity: false,
},
icon: path.join(directoryName, "icon.ico"),
};
// Create the browser window.
if (isScreenPositionCustom === true) {
browserWindowOptions.x = screenXCoordinate;
browserWindowOptions.y = screenYCoordinate;
window = new BrowserWindow(browserWindowOptions);
} else {
window = new BrowserWindow(browserWindowOptions);
}
window.on("closed", () => (window = null));
if (isDev === true) {
window.loadURL("http://localhost:3000");
} else {
window.loadURL(
url.format({
pathname: path.join(directoryName, "index.html"),
protocol: "file:",
slashes: true,
})
);
}
// Handle window toggling for custom titlebar
ipcMain.on("windowMinimize", () => minimizeWindow(window));
ipcMain.on("windowMaximize", () => maximizeWindow(window));
ipcMain.on("windowClose", () => closeWindow(window));
// Open the DevTools.
// window.webContents.openDevTools()
return window;
} catch (error) {
log.info("CREATE WINDOW ERROR INSIDE FUNCTION: ", error);
}
};
module.exports = { createWindow };
Where am I going wrong here?
I have hosted a peer to peer meeting react app on netlify. I have used Peerjs for my video purpose. Everything is working as expected except the video. For some networks the video of the the remote person is working and for some others it is not working. I looked up and found out that it may be a STUN/TURN issue. I then implemented all the STUN/TURN servers in my code. However the video is still not getting setup in some cases. In some cases it is working fine, in others the video is not showing up. Herewith, I am attaching th code for the video and the link to the site.
import React,{useEffect,useState} from 'react';
import {io} from "socket.io-client";
import {useParams} from 'react-router-dom';
import {Grid} from "#material-ui/core";
import Peer from 'peerjs';
var connectionOptions = {
"force new connection" : true,
"reconnectionAttempts": "Infinity",
"timeout" : 10000,
"transports" : ["websocket"]
};
const Videobox = ({isVideoMute,isAudioMute}) => {
var myPeer = new Peer(
{
config: {'iceServers': [
{urls:'stun:stun01.sipphone.com'},
{urls:'stun:stun.ekiga.net'},
{urls:'stun:stun.fwdnet.net'},
{urls:'stun:stun.ideasip.com'},
{urls:'stun:stun.iptel.org'},
{urls:'stun:stun.rixtelecom.se'},
{urls:'stun:stun.schlund.de'},
{urls:'stun:stun.l.google.com:19302'},
{urls:'stun:stun1.l.google.com:19302'},
{urls:'stun:stun2.l.google.com:19302'},
{urls:'stun:stun3.l.google.com:19302'},
{urls:'stun:stun4.l.google.com:19302'},
{urls:'stun:stunserver.org'},
{urls:'stun:stun.softjoys.com'},
{urls:'stun:stun.voiparound.com'},
{urls:'stun:stun.voipbuster.com'},
{urls:'stun:stun.voipstunt.com'},
{urls:'stun:stun.voxgratia.org'},
{urls:'stun:stun.xten.com'},
{
urls: 'turn:numb.viagenie.ca',
credential: 'muazkh',
username: 'webrtc#live.com'
},
{
urls: 'turn:192.158.29.39:3478?transport=udp',
credential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
username: '28224511:1379330808'
},
{
urls: 'turn:192.158.29.39:3478?transport=tcp',
credential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
username: '28224511:1379330808'
}
]} /* Sample servers, please use appropriate ones */
}
);
const peers = {}
const [socket, setSocket] = useState()
const {id:videoId} = useParams();
const videoGrid = document.getElementById('video-grid')
useEffect(()=> {
const s=io("https://weconnectbackend.herokuapp.com",connectionOptions);
setSocket(s);
return () => {
s.disconnect();
}
},[])
// let myVideoStream;
const [myVideoStream, setmyVideoStream] = useState()
const muteUnmute = () => {
const enabled = myVideoStream.getAudioTracks()[0].enabled;
if (enabled) {
myVideoStream.getAudioTracks()[0].enabled = false;
//setUnmuteButton();
} else {
//setMuteButton();
myVideoStream.getAudioTracks()[0].enabled = true;
}
}
const playStop = () => {
//console.log('object')
let enabled = myVideoStream.getVideoTracks()[0].enabled;
if (enabled) {
myVideoStream.getVideoTracks()[0].enabled = false;
//setPlayVideo()
} else {
//setStopVideo()
myVideoStream.getVideoTracks()[0].enabled = true;
}
}
useEffect(() => {
if(myVideoStream)
playStop()
}, [isVideoMute])
useEffect(() => {
if(myVideoStream)
muteUnmute()
}, [isAudioMute])
useEffect(() => {
if(socket== null)
return;
myPeer.on('open',id=>{
socket.emit('join-room',videoId,id);
})
const myVideo = document.createElement('video')
myVideo.muted = true
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).then(stream => {
// myVideoStream = stream;
window.localStream=stream;
setmyVideoStream(stream);
console.log(myVideoStream,"myvideostream");
addVideoStream(myVideo, stream)
myPeer.on('call', call => {
call.answer(stream)
const video = document.createElement('video')
call.on('stream', userVideoStream => {
addVideoStream(video, userVideoStream)
})
})
socket.on('user-connected',userId =>{
connectToNewUser(userId, stream)
})
socket.on('user-disconnected', userId => {
if (peers[userId]) peers[userId].close()
})
})
}, [socket,videoId])
function addVideoStream(video, stream) {
video.srcObject = stream
video.addEventListener('loadedmetadata', () => {
video.play()
})
videoGrid.append(video)
}
function connectToNewUser(userId, stream) {
const call = myPeer.call(userId, stream)
const video = document.createElement('video')
call.on('stream', userVideoStream => {
addVideoStream(video, userVideoStream)
})
call.on('close', () => {
video.remove()
})
peers[userId] = call
}
return (
<div id="video-grid" className="videoStyleFromDiv">
{/* <Video srcObject={srcObject}/> */}
</div>
)
}
export default Videobox
Website Link
The TURN servers you are using have been out of commission for a couple of years in the case of the ones taken from https://www.html5rocks.com/en/tutorials/webrtc/infrastructure/
Copying credentials from random places is not how TURN works, you will need to run your own servers.
So I am using jssip 3.2.10 to make calls on a React project.
The server is setup on Asterisk and CentOS.
I can make calls where the call receiver hears me well, but I can't hear their audio, nor the waiting (traditional) beep noises it should make until the call is picked up.
It does work with some sipml5/asterisk udp online tests so I feel it's on my clients side issue. I tested it on Chrome and Firefox (both latest, with the same results).
My setup
I have a helper to connect called sip.js:
const JsSIP = require('jssip')
const GLOBAL = require('../globals')
function register(user, pass, cb) {
console.log('Registering to SIP')
JsSIP.debug.disable('JsSIP:*')
const address = GLOBAL.jssip_server + ':' + GLOBAL.jssip_port
let socket = new JsSIP.WebSocketInterface('ws://' + address + '/ws')
const configuration = {
sockets: [socket],
uri: 'sip:' + user + '#' + GLOBAL.jssip_server,
authorization_user: user,
password: pass,
connection_recovery_min_interval: 3,
register: true
}
let ua = new JsSIP.UA(configuration)
ua.start()
cb(ua)
}
export {
register
}
Then on my main component I do the following:
componentDidMount() {
if(GLOBAL.jssip) {
this.props.dispatch(connecting(true))
register('***', '***', (ua) => {
this.setState({ua: ua}, () => {
this.state.ua.on("registered", () => {
this.props.dispatch(connecting(false))
this.setState({critical: false})
})
this.state.ua.on("registrationFailed", () => {
this.props.dispatch(connecting(false))
this.setState({critical: true})
})
})
})
}
}
And when I try to make a call I do the following:
doCall(number) {
this.props.dispatch(placeCall(call))
if(GLOBAL.jssip) {
let eventHandlers = {
'connecting': (e) => {
console.log('call is in progress')
this.setState({sipStatus: "connecting"})
},
'progress': (e) => {
console.log('call is in progress')
this.setState({sipStatus: "progress"})
},
'failed': (e) => {
console.log('call failed with cause: ', e)
this.setState({sipStatus: "failed"})
},
'ended': (e) => {
console.log('call ended with cause: ', e)
this.setState({sipStatus: "ended"})
},
'confirmed': (e) => {
this.setState({sipStatus: "confirmed"})
}
}
let options = {
eventHandlers: eventHandlers,
mediaConstraints: { 'audio': true, 'video': false }
}
let session = this.state.ua.call('sip:'+number+'#'+GLOBAL.jssip_server, options)
}
}
Anyone has a clue on how to fix this?
Thanks to the answer here:
How to handle audio stream in JsSIP?
I found the solution, I needed to add to the file rendering the call:
<audio ref={(audio) => {this.audioElement = audio}} id="audio-element"></audio>
And changed doCall last bit to this:
this.setState({session: this.state.ua.call('sip:'+number+'#'+GLOBAL.jssip_server, options)}, () =>{
this.state.session.connection.addEventListener('addstream', (event: any) => {
this.audioElement.srcObject = event.stream
this.audioElement.play()
})
})