ICE failed, PeerJS call started but no video/audio through - webrtc

I am trying to get a simple video chat working with PeerJS. I want to send audio between Firefox on a pc and Firefox on Android. I can get the call running (call.on) and I can view local video but for some reason the media just doesn't come through to the other user. Currently I am getting the error:
ICE failed, see about:webrtc for more details
I have a server which in its simple version is as such:
var ip = require('ip');
var PeerServer = require('peer').PeerServer;
var port = 9000;
var server = new PeerServer({port: port, allow_discovery: true});
Then I have two clients, one for the pc that makes the call:
var SERVER_IP = window.location.hostname;
var SERVER_PORT = 9000;
var localStream = "";
var peerID = "pc"
var peerConnectionID = "and"
var remoteVideo = document.querySelector('#rremote-video');
var localVideo = document.querySelector('#llocal-video');
var peer = new Peer(peerID, {host: SERVER_IP, port: SERVER_PORT});
var conn = peer.connect(peerConnectionID);
var getUserMedia = navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => localVideo.srcObject = stream)
.then(stream => localStream = stream)
.catch(e => console.log(e.name + ": "+ e.message));
waitForElement();
function waitForElement(){
if(localStream != ""){
conn.on('open', function(){
conn.send('hi from PC!');
});
peer.on('connection', function(conn) {
conn.on('data', function(data){
console.log(data);
});
});
console.log("we have a stream: "+localStream);
var call = peer.call(peerConnectionID, localStream);
console.log("Calling "+peerConnectionID);
call.on('stream', function(remotestream) {
console.log("Call on.");
remoteVideo.srcObject = remotestream;
});
}
else{
setTimeout(function(){
waitForElement();
},750);
}
}
And the one that answers the call is:
var SERVER_IP = window.location.hostname;
var SERVER_PORT = 9000;
var localStream = "";
var peerID = "and"
var peerConnectionID = "pc"
var remoteVideo = document.querySelector('#rremote-video');
var localVideo = document.querySelector('#llocal-video');
var remoteAudio = document.querySelector('#remote-audio');
var localAudio = document.querySelector('#local-audio');
var peer = new Peer(peerID, {host: SERVER_IP, port: SERVER_PORT});
var conn = peer.connect(peerConnectionID);
var getUserMedia = navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => localAudio.srcObject = stream)
.then(stream => localVideo.srcObject = stream)
.then(stream => localStream = stream)
.catch(e => console.log(e.name + ": "+ e.message));
waitForElement();
function waitForElement(){
if(localStream != ""){
conn.on('open', function(){
conn.send('hi from android!');
});
peer.on('connection', function(conn) {
conn.on('data', function(data){
console.log(data);
});
});
peer.on('call', function(call) {
console.log("Picking up call.");
call.answer(localStream);
call.on('stream', function(remotestream) {
console.log("Call on.");
remoteVideo.srcObject = remotestream;
});
});
}
else{
setTimeout(function(){
waitForElement();
},750);
}
}
I think it is some little tweak that I'm getting wrong, I have mainly followed instructions on PeerJS website: http://peerjs.com/ Please if anyone can see something that needs to change, any help is welcome!

Are you using https? Making calls to non-local machines is no longer allowed by the browsers.
To test this out, run both sets of code on your local machine. If you can do that connection, it means your code is ok.
To do a remote connection you will unfortunately need https. This means you will also need your own peerjs server (to run as https).
The other option is to use port forwarding to make one of the machines think it is talking to the localhost

It sounds like your ICE Candidates cannot communicate one to each other. You will have to use a STUN server and, if it still doesnt work, you will need a TURN server.
From PeerJS Documentation:
var peer = new Peer({
config: {'iceServers': [
{ url: 'stun:stun.l.google.com:19302' },
{ url: 'turn:homeo#turn.bistri.com:80', credential: 'homeo' }
]} /* Sample servers, please use appropriate ones */
});
This link will provide you a method to deploy your own TURN server.

Related

INSERT INTO Error: SQLITE_ERROR: no such table: comments

I'm setting up a server for a project that I've been trying to develop on my own, and using SQLite and Node.js as the database type and server platform, respectively. I'm relatively new to backend development, and I am trying to set up a POST request from the frontend of the webpage to the backend so whatever the user submits will store in "comments.db", a file in the server which will store all the username and data (specifically the user ID and data).
In the past, I've tried renaming the database differently, and moving the database into several different subfiles, but I always yield the same error on submission.
The following is my code for my node.js file:
var os = require( 'os' );
const interfaces = os.networkInterfaces();
const addresses = [];
var getMacAddress;
var request = require('request');
var express = require('express');
var sqlite3 = require('sqlite3');
var bodyParser = require('body-parser');
var ip = require("ip");
var address = ip.address();
var db = new sqlite3.Database('comments.db');
var app = express();
app.use(express.static(__dirname));
app.use(bodyParser.urlencoded({extended: false}));
app.get('/comments', function(request, response){
// response.send('Hello Worlds');
response.send("Hello my name is aestheticnoodle and you have reached a wrong");
});
app.get('/comments', function(request, response){
console.log('GET request received at /alpha');
db.all('SELECT * FROM comments', function(err, rows){
if(err){
console.log("Error");
} else {
response.send(rows);
//pass rows back to the client
}
});
});
//runs once a user submits a comment
app.post('/comments', function(request, response){
db.run('INSERT INTO comments VALUES (?, ?)', ["aestheticnoodle" ,request.body.action], function(err, rows){
if(err){
console.log(request.body.action);
console.log("INSERT INTO " + err);
} else {
response.status(200).redirect('chat.html');
}
});
});
app.listen(3000, function(){
console.log("Server is running on port 3000");
});
var admin = require("firebase-admin");
var firebaseConfig = {
apiKey: "baseapp",
authDomain: "fire",
databaseURL: "inthe,
projectId: "data",
storageBucket: "",
messagingSenderId: "private",
appId: "some2"
};
admin.initializeApp(firebaseConfig);
var headers = {
'App-Id': 'someappid',
'App-Key': 'someappkey',
'Content-Type': 'application/json'
};
var dataString = '{"text": "test run.."}';
var options = {
url: 'https://somesite.com/v2/parse',
method: 'POST',
headers: headers,
body: dataString
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
}
request(options, callback);
and the error is as follows:
C:\Users\achu1\Music\projectsummer2019\cybeRx>node nodeRequest.js
Server is running on port 3000
undefined
INSERT INTO Error: SQLITE_ERROR: no such table: comments
here is the javascript snippet where I try to insert html in the interface of a chat bot:
var string = "What seems to be the problem you have been experiencing? Use one of the keywords, per SymptomList the complete list of symptoms."
document.getElementById("chat").innerHTML += '<form action = "/comments" method = "POST">'+ "<div id = \"botLog\" class = \"chatting\">" + string + '<textarea rows = "15" name = "comment"> Write stuff here' + '</textarea>'+ '<br><br><input type = "submit" value = "SUBMIT"/></form>' + "</div><br>";
as you can see, I attempted to connect my database and my html file running in the localhost by making a POST method form into my comment.db file, which is actually in my directory.
https://imgur.com/a/pdGAVhm
why does the node say that there is no such database to execute the POST command, and how do I resolve this problem so my textbox data saves to the database?

Node Escpos print image on second try

Hello i am creating an express service that prints to a pos printer at http request. The problem is that my solution does not print images on the first print but it does at the second and so on.
I am using https://github.com/song940/node-escpos
Here is my server.js
var print = require('./print')
var express = require('express')
var cors = require('cors')
var bodyParser = require('body-parser');
var app = express();
var corsOptions = {
origin: '*',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
app.get('/print', cors(corsOptions), (req, res) => {
print.demoPrint();
return res.send(req.body);
});
app.listen(3000, () => {
console.log('Express server is started')
});
Here is my print.js
const escpos = require('escpos');
const device = new escpos.USB(0x1504,0x003d);
const options = { encoding: "GB18030"};
const printer = new escpos.Printer(device);
const fs = require('fs')
const printSettings = JSON.parse(fs.readFileSync('printConfig.json', 'utf8'));
exports.demoPrint = () => {
device.open(function() {
printSettings.forEach((currentLine) => {
if(currentLine.printType === "text") {
console.log("PRINTING TEXT");
printer
.font(currentLine.font)
.align(currentLine.align)
.style('bu')
.size(currentLine.size, currentLine.size)
.text(currentLine.text)
}
else if(currentLine.printType === "image") {
escpos.Image.load(currentLine.path, (image) => {
console.log("PRINTING IMAGE");
printer
.align(currentLine.align)
.size(currentLine.size, currentLine.size)
.image(image)
});
}
else if(currentLine.printType === "barcode") {
console.log("PRINTING BARCODE");
printer
.align(currentLine.align)
.barcode(currentLine.text, 'CODE39', {
height: 64,
font: 'B'
});
}
});
printer
.text('\n')
.text('\n')
.cut()
.close();
});
};
Since this hasn't been answered yet I will provide the solution that worked for me. The problem was that the images were starting to load on the first time I submitted a request. By the second time I submitted a request the images were already loaded and were successfully printed.
I solved the problem by a adding a check that would not allow to print until the images were loaded.

How to publish a message to rabbitmq using Mocha framework

Hi i'm unable to figure out how to connect to rabbitmq using Mocha & chai framework.
I've installed rabbitmq & erlang on my local & trying to connect to rabbitmq by starting the server on local.
The code i'm using is as below:
var chai = require('chai');
var chaiHttp = require('chai-http');
var request = chai.request;
var should = chai.should();
var expect = chai.expect;
var assert = chai.assert;
var supertest = require('supertest');
var fs = require('fs');
var amqp = require('amqplib/callback_api');
//Plugin for HTTP, etc.
chai.use(chaiHttp);
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
describe("Testing RabbitMQ : ", function () {
it("Send a message : ", function (done) {
amqp.connect('amqp://localhost:15672/', function (err, conn) {
conn.createChannel(function (err, ch) {
var q = 'hello';
ch.assertQueue(q, { durable: false });
// Note: on Node 6 Buffer.from(msg) should be used
ch.sendToQueue(q, new Buffer('Hello World!'));
console.log(" [x] Sent 'Hello World!'");
});
setTimeout(function () { conn.close(); process.exit(0) }, 500);
});
done();
});
it("Receive a message", function (done) {
amqp.connect('amqp://localhost:15672/', function (err, conn) {
conn.createChannel(function (err, ch) {
var q = 'hello';
ch.assertQueue(q, { durable: false });
console.log(" [*] Waiting for messages in %s. To exit press CTRL+C", q);
ch.consume(q, function (msg) {
console.log(" [x] Received %s", msg.content.toString());
}, { noAck: true });
});
});
done();
});
})
So is there any other way to connect to rabbitmq & publish a message?
I've tried with amqp library, any sample code for connecting to rabbitmq will be helpful.
Can anyone make me understand how to connect to a specific queue to send a message, where the message can be published.
Any help would be really appreciated. Thank you.
You are specifying the wrong port. The default amqp port is 5672. If you are not changing the default port then you don't need to specify the port in amqp server url. That is instead of amqp://localhost:15672/, you can simply specify the url as amqp://localhost. I would like to give a working program for How to publish a message to rabbitmq using Mocha framework?.
I run the RabbitMQ server in my system using docker
docker run -d --hostname rabbit1 --name rabbit1 -e RABBITMQ_ERLANG_COOKIE=rabbitcluster -p 30000:5672 -p 30001:15672 rabbitmq:management
Then
// test.js
var chai = require('chai')
var amqp = require('amqplib/callback_api');
var chaiHttp = require('chai-http')
var should = chai.should()
chai.use(chaiHttp);
var config={
protocol: 'amqp',
hostname: 'localhost',
port: 30000,
username: 'guest',
password: 'guest',
}
var q="ex.queue";
var msg = "Hello World!";
describe('Testing RabbitMQ',function(){
it('Sending Message to RabbitMQ Server',function(done){
amqp.connect(config, function(err, conn) {
if(err){
console.log("connection error");
return;
}
conn.createConfirmChannel(function(err, ch) {
if(err){
return;
}
ch.assertQueue(q, {durable: true});
ch.sendToQueue(q, new Buffer(msg), {persistent: true},
function(err){
if(err){
console.log("msg resend err==>",err);
return;
}
else{
console.log(" [x] reSent '%s'", msg);
}
});
});
done();
setTimeout(function() { conn.close();}, 500);
});
});
});

webRTC ReferenceError: webkitRTCPeerConnection is not defined

I am study about learning WebRTC book and create a demo 4 chapter. I am gating an error in console:
ReferenceError: webkitRTCPeerConnection is not defined
and not understand what can I confi the "iceServers":
Here is my javascript code
function hasUserMedia(){
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
return !!navigator.getUserMedia;
}
function hasRTCPeerConnection() {
window.RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
return !!window.RTCPeerConnection;
}
//This function will create our RTCPeerConnection objects, set up the SDP offer and response, and find the ICE candidates for both peers. page 48
function startPeerConnection(stream) {
var configuration = {
// Uncomment this code to add custom iceServers
"iceServers": [{ "url": "stun:stun.1.google.com:19302" }]
};
yourConnection = new webkitRTCPeerConnection(configuration);
theirConnection = new webkitRTCPeerConnection(configuration);
// Setup stream listening
yourConnection.addStream(stream);
theirConnection.onaddstream = function (e) {
theirVideo.src = window.URL.createObjectURL(e.stream);
};
// Setup ice handling
yourConnection.onicecandidate = function (event) {
if (event.candidate){
theirConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
}
};
theirConnection.onicecandidate = function (event) {
if (event.candidate) {
yourConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
}
};
// Begin the offer
yourConnection.createOffer(function (offer) {
yourConnection.setLocalDescription(offer);
theirConnection.setRemoteDescription(offer);
theirConnection.createAnswer(function (offer) {
theirConnection.setLocalDescription(offer);
yourConnection.setRemoteDescription(offer);
});
});
}
var yourVideo = document.querySelector("#yours"),
theirVideo = document.querySelector("#theirs"),
yourConnection, theirConnection;
if (hasUserMedia()) {
navigator.getUserMedia({ video: true, audio: false }, function (stream) {
yourVideo.src = window.URL.createObjectURL(stream);
if (hasRTCPeerConnection()) {
startPeerConnection(stream);
} else {
alert("Sorry, your browser does not support WebRTC.");
}
}, function (error) {
console.log(error);
}
);
} else {
alert("Sorry, your browser does not support WebRTC.");
}
and it output like this..
Please let me know why my video not working properly? Please help me to do this
learning WebRTC
Change:
yourConnection = new webkitRTCPeerConnection(configuration);
into:
yourConnection = new RTCPeerConnection(configuration);
as webkitRTCPeerConnection is for Chrome browsers, and the code already defines window.RTCPeerConnection in hasRTCPeerConnection so that it works for most browsers (inclusing Firefox that you are using).
[EDIT]
Your logic is not correct in this program. You are creating both connections like this:
yourConnection = new webkitRTCPeerConnection(configuration);
theirConnection = new webkitRTCPeerConnection(configuration);
This is not logical. Your program is one peer of a 2-peers connection. You need to setup your connection only. Also, you need some kind of messaging server to transmit SDP messages between the two peers. This is not the role of the ICE server.
Your ICE configuration is fine. You are using a public Google STUN server to handle the streaming and the public IP discovery necessary for establishing the WebRTC connection.

DOMException: Failed to set remote offer sdp: Called in wrong state: STATE_SENTOFFER

I am trying to make a video calling web application using webRTC. I am using angularjs and express.io
I am getting this error:
DOMException: Failed to set remote offer sdp: Called in wrong state: STATE_SENTOFFER
Some of my code is:
// in controller (socket is already defined in controller)
var videolocal = document.getElementById('videolocal');
var videoremote = document.getElementById('videoremote');
var streamlocal = null;
var pc = null;
window.URL = window.URL || window.webkitURL;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var configuration = {'iceServers': [
// {'url': 'stun:stun.services.mozilla.com'},
{'url': 'stun:stun.l.google.com:19302'}
]};
// run start(true) to initiate a call
$scope.start = function() {
console.log('start');
// get the local stream, show it in the local video element and send it
navigator.getUserMedia({ "audio": true, "video": true }, function (stream) {
videolocal.src = URL.createObjectURL(stream);
pc = new RTCPeerConnection(configuration);
pc.addStream(stream);
// once remote stream arrives, show it in the remote video element
pc.onaddstream = function (evt) {
console.log('onaddstream');
videoremote.src = URL.createObjectURL(evt.stream);
};
// send any ice candidates to the other peer
pc.onicecandidate = function (evt) {
console.log('onicecandidate');
if(evt.candidate){
socket.emit('video_call',{user:2, type: 'candidate', candidate: evt.candidate});
}
};
// create an offer
pc.createOffer(function (offer) {
socket.emit('video_call', {user:2, type: "offer", offer: offer});
pc.setLocalDescription(offer);
}, function (error) {
alert("Error when creating an offer");
});
}, function () {alert('error in start')});
}
$scope.start();
socket.on('video_call', function (data) {
console.log(data);
//when somebody sends us an offer
function handleOffer(offer) {
// this line is giving error
pc.setRemoteDescription(new RTCSessionDescription(offer), function(){alert('success')}, function(e){ console.log(e); alert(e)});
//create an answer to an offer
pc.createAnswer(function (answer) {
pc.setLocalDescription(answer);
socket.emit('video_call', {user:2, type: "answer", answer: answer});
}, function (error) {
console.log(error);
alert("Error when creating an answer");
});
};
//when we got an answer from a remote user
function handleAnswer(answer) {
pc.setRemoteDescription(new RTCSessionDescription(answer));
};
//when we got an ice candidate from a remote user
function handleCandidate(candidate) {
pc.addIceCandidate(new RTCIceCandidate(candidate));
};
switch(data['type']) {
case "offer":
handleOffer(data["offer"]);
break;
case "answer":
handleAnswer(data['answer']);
break;
//when a remote peer sends an ice candidate to us
case "candidate":
handleCandidate(data['candidate']);
break;
default:
break;
}
});
On server:
// this function is called on video_call event
video_call: function (data) {
var id = data.user;
// if user is active
// users is dict of users (user_id as key)
if(Object.keys(users).indexOf(id.toString()) > -1){
// for each device of the user
users[id].forEach(function(user_socket){
console.log(data);
user_socket.emit('video_call', data);
});
}
}
Please can anyone tell what is wrong with this code. The local stream is capturing properly. I am using chromium browser.
Data on server:
I think the problem is that in your handleOffer() function you need to create another PeerConnection and call setRemoteDescription() on that pc.
var remote_pc = new RTCPeerConnection(configuration)
remote_pc.setRemoteDescription(new RTCSessionDescription(offer), ...) {
remote_pc.createAnswer()
}
This is what I have in my code.
EDIT: In the official link you can go to chapter 11.7 and check the steps after 15 (when the offer is sent and the other peer receives it).