Xirsys WebRTC can't find sdp object
up vote
0
down vote
favorite
I'm trying to test an example provided by Xirsys where I can proceed with signaling using only PHP. The ice servers / token and host seems to work perfectly, but when trying to connect it returns "uncaught: Typeerror: cannot read property 'sdp' of null. The object it doesn't seem null, not sure what is happening here.
Follow my code:
<html>
<head>
<title>PHP Xirsys</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div class="panel" id="video-wrapper">
<style>
video {
background: #cccccc;
width: 200px;
}
</style>
<div class="col">
<div>
your message: <input type="text" id="newMessage" disabled />
<button id="sendButton" onclick="send()" disabled>send</button>
</div>
<div id="messages"></div>
</div>
<div id="videos">
<video autoplay="true" id="localVideo"></video>
</div>
<div>
username: <input type="text" id="username" />
<button id="connectButton" onclick="connect()">connect</button>
</div>
<script>
var token;
var socket;
var ice;
var pcs = {};
var localUsername;
function displayMessage(message) {
$('#messages')[0].innerHTML += message + "<br>";
}
window.onload = () => {
$.post("getice.php", null, r => onIce(r));
}
function onIce(r) {
ice = JSON.parse(r).v;
navigator.mediaDevices.getUserMedia({audio: true, video: true}).then(stream => onGetMedia(stream));
}
function connect() {
localUsername = $('#username')[0].value;
$.post("gettoken.php", {username: localUsername}, r => getHost(r));
}
function getHost(r) {
token = JSON.parse(r).v;
$.post("gethost.php", {username: localUsername}, r => openSocket(r));
}
function openSocket(r) {
var host = JSON.parse(r).v;
socket = new WebSocket(host + "/v2/" + token);
socket.addEventListener("message", onSocketMessage);
}
function onSocketMessage(evt) {
var data = JSON.parse(evt.data);
var option;
var pc;
switch (data.m.o) {
case "peers":
var users = data.p.users;
for(i = 0; i < users.length; i++) {
displayMessage("user in chat:" + users[i]);
}
break;
case "peer_connected":
var f = data.m.f.split("/");
var joining = f[f.length-1];
displayMessage("new user joined: " + joining)
callPeer(joining);
break;
case "message":
switch(data.p.msg.type) {
case "offer":
var desc = new RTCSessionDescription(data.p.msg);
var f = data.m.f.split("/");
var sender = f[f.length-1];
pc = createNewPeerConnection(sender);
pc.setRemoteDescription(desc);
pc.createAnswer().then(d => onCreateAnswer(d,sender));
break;
case "answer":
var desc = new RTCSessionDescription(data.p.msg);
var f = data.m.f.split("/");
var sender = f[f.length-1];
pcs[sender].pc.setRemoteDescription(desc);
break;
case "candidate":
var f = data.m.f.split("/");
var sender = f[f.length-1];
var candidate = new RTCIceCandidate(data.p.msg);
pcs[sender].pc.addIceCandidate(candidate);
break;
}
}
}
function callPeer(peer) {
var pc = createNewPeerConnection(peer);
var dataChannel = pc.createDataChannel("data");
pcs[peer].dc = dataChannel;
setDataChannelHandlers(dataChannel);
pc.createOffer().then(d => onCreateOffer(d, peer));
}
function onCreateOffer(d, peer) {
pcs[peer].pc.setLocalDescription(d);
var pkt = {t: "u", m: {f: "appchannel/" + localUsername, o: "message", t: peer}, p: {msg:d}};
socket.send(JSON.stringify(pkt));
}
function onCreateAnswer(d, peer) {
pcs[peer].pc.setLocalDescription(d);
var pkt = {t: "u", m: {f: "appchannel/" + localUsername, o: "message", t: peer}, p: {msg:d}};
socket.send(JSON.stringify(pkt));
}
function onIceCandidate(evt) {
var remoteUsername = getUsernameByRemoteDescription(evt.target.remoteDescription.sdp);
var candidate = evt.candidate;
if (candidate != null && remoteUsername != null) {
var cPkt = {type: "candidate",
candidate: candidate.candidate,
sdpMid: candidate.sdpMid,
sdpMLineIndex: candidate.sdpMLineIndex
};
var pkt = {
t: "u",
m: {
f: "appchannel/" + localUsername,
o: "message",
t: remoteUsername
},
p: {msg:cPkt}
}
socket.send(JSON.stringify(pkt));
}
}
function setDataChannelHandlers(dc) {
dc.onmessage = evt => onDataMessage(evt);
dc.onopen = evt => onDataChannelOpen(evt);
}
function onDataChannelOpen(evt) {
$("#newMessage")[0].disabled = false;
$("#sendButton")[0].disabled = false;
}
function onDataChannel(evt) {
var dataChannel = evt.channel;
var keys = Object.keys(pcs);
var comp;
var localDescription;
var remoteDescription;
for(var i = 0; i < keys.length; i++) {
comp = pcs[keys[i]];
if(evt.currentTarget.localDescription.sdp == comp.pc.localDescription.sdp) {
comp.dc = dataChannel;
}
}
setDataChannelHandlers(dataChannel);
}
function send() {
var messageElement = $('#newMessage')[0];
displayMessage("you said: " + messageElement.value);
var message = {f: localUsername, msg: messageElement.value};
messageElement.value = "";
var dataChannel;
var keys = Object.keys(pcs);
var comp;
for(var i = 0; i < keys.length; i++) {
comp = pcs[keys[i]];
dataChannel = comp.dc;
dataChannel.send(JSON.stringify(message));
}
}
function onDataMessage(evt) {
var messageObj = JSON.parse(evt.data);
displayMessage(messageObj.f + " said: " + messageObj.msg);
}
function createNewPeerConnection(username){
var pc = new RTCPeerConnection(ice);
pc.addStream(localStream);
pc.onaddstream = evt => onAddStream(evt);
pc.ondatachannel = evt => onDataChannel(evt);
pc.onicecandidate = candidate => onIceCandidate(candidate);
pcs[username] = {pc: pc, dc: null, s: null, v: null};
return pc;
}
function getUsernameByRemoteDescription(sdp) {
var keys = Object.keys(pcs);
var pc;
for(var i = 0; i < keys.length; i++) {
pc = pcs[keys[i]].pc;
if(pc.remoteDescription.sdp == sdp) {
return keys[i];
}
}
return null;
}
function onGetMedia(stream) {
var vid = $("#localVideo")[0];
vid.srcObject = stream;
localStream = stream;
}
function onAddStream(evt) {
var pc = evt.target;
var stream = evt.stream;
var peer = getUsernameByRemoteDescription(pc.remoteDescription.sdp);
pcs[peer].s = stream;
var v = addNewVideo(stream);
pcs[peer].v = v;
}
function addNewVideo(stream) {
var vid = document.createElement("video");
$("#videos")[0].appendChild(vid);
vid.srcObject = stream;
return vid;
}
</script>
</div>
</body>
</html>
getice.php
<?php
$curl = curl_init();
curl_setopt_array( $curl, array (
CURLOPT_URL =>
"https://global.xirsys.net/_turn/appchannel/",
CURLOPT_USERPWD => "account:key",
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_RETURNTRANSFER => 1
));
$resp = curl_exec($curl);
print $resp;
curl_close($curl);
?>
gettoken.php
$data = array( 'k' => $_POST["username"], 'expire' => 45, 'depth' => 10 );
$qs = http_build_query($data);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://global.xirsys.net/_token/appchannel?'.$qs,
CURLOPT_USERPWD => "account:key",
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_CUSTOMREQUEST => 'PUT'
));
$resp = curl_exec($curl);
curl_close($curl);
echo($resp);
gethost.php
$data = array( 'k' => $_POST["username"], 'type' => 'signal' );
$qs = http_build_query($data);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://global.xirsys.net/_host?'.$qs,
CURLOPT_USERPWD => "account:key",
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_CUSTOMREQUEST => 'GET'
));
$resp = curl_exec($curl);
curl_close($curl);
echo($resp);
Edit: errors -> on Chrome / Firefox
javascript php webrtc xirsys
add a comment |
up vote
0
down vote
favorite
I'm trying to test an example provided by Xirsys where I can proceed with signaling using only PHP. The ice servers / token and host seems to work perfectly, but when trying to connect it returns "uncaught: Typeerror: cannot read property 'sdp' of null. The object it doesn't seem null, not sure what is happening here.
Follow my code:
<html>
<head>
<title>PHP Xirsys</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div class="panel" id="video-wrapper">
<style>
video {
background: #cccccc;
width: 200px;
}
</style>
<div class="col">
<div>
your message: <input type="text" id="newMessage" disabled />
<button id="sendButton" onclick="send()" disabled>send</button>
</div>
<div id="messages"></div>
</div>
<div id="videos">
<video autoplay="true" id="localVideo"></video>
</div>
<div>
username: <input type="text" id="username" />
<button id="connectButton" onclick="connect()">connect</button>
</div>
<script>
var token;
var socket;
var ice;
var pcs = {};
var localUsername;
function displayMessage(message) {
$('#messages')[0].innerHTML += message + "<br>";
}
window.onload = () => {
$.post("getice.php", null, r => onIce(r));
}
function onIce(r) {
ice = JSON.parse(r).v;
navigator.mediaDevices.getUserMedia({audio: true, video: true}).then(stream => onGetMedia(stream));
}
function connect() {
localUsername = $('#username')[0].value;
$.post("gettoken.php", {username: localUsername}, r => getHost(r));
}
function getHost(r) {
token = JSON.parse(r).v;
$.post("gethost.php", {username: localUsername}, r => openSocket(r));
}
function openSocket(r) {
var host = JSON.parse(r).v;
socket = new WebSocket(host + "/v2/" + token);
socket.addEventListener("message", onSocketMessage);
}
function onSocketMessage(evt) {
var data = JSON.parse(evt.data);
var option;
var pc;
switch (data.m.o) {
case "peers":
var users = data.p.users;
for(i = 0; i < users.length; i++) {
displayMessage("user in chat:" + users[i]);
}
break;
case "peer_connected":
var f = data.m.f.split("/");
var joining = f[f.length-1];
displayMessage("new user joined: " + joining)
callPeer(joining);
break;
case "message":
switch(data.p.msg.type) {
case "offer":
var desc = new RTCSessionDescription(data.p.msg);
var f = data.m.f.split("/");
var sender = f[f.length-1];
pc = createNewPeerConnection(sender);
pc.setRemoteDescription(desc);
pc.createAnswer().then(d => onCreateAnswer(d,sender));
break;
case "answer":
var desc = new RTCSessionDescription(data.p.msg);
var f = data.m.f.split("/");
var sender = f[f.length-1];
pcs[sender].pc.setRemoteDescription(desc);
break;
case "candidate":
var f = data.m.f.split("/");
var sender = f[f.length-1];
var candidate = new RTCIceCandidate(data.p.msg);
pcs[sender].pc.addIceCandidate(candidate);
break;
}
}
}
function callPeer(peer) {
var pc = createNewPeerConnection(peer);
var dataChannel = pc.createDataChannel("data");
pcs[peer].dc = dataChannel;
setDataChannelHandlers(dataChannel);
pc.createOffer().then(d => onCreateOffer(d, peer));
}
function onCreateOffer(d, peer) {
pcs[peer].pc.setLocalDescription(d);
var pkt = {t: "u", m: {f: "appchannel/" + localUsername, o: "message", t: peer}, p: {msg:d}};
socket.send(JSON.stringify(pkt));
}
function onCreateAnswer(d, peer) {
pcs[peer].pc.setLocalDescription(d);
var pkt = {t: "u", m: {f: "appchannel/" + localUsername, o: "message", t: peer}, p: {msg:d}};
socket.send(JSON.stringify(pkt));
}
function onIceCandidate(evt) {
var remoteUsername = getUsernameByRemoteDescription(evt.target.remoteDescription.sdp);
var candidate = evt.candidate;
if (candidate != null && remoteUsername != null) {
var cPkt = {type: "candidate",
candidate: candidate.candidate,
sdpMid: candidate.sdpMid,
sdpMLineIndex: candidate.sdpMLineIndex
};
var pkt = {
t: "u",
m: {
f: "appchannel/" + localUsername,
o: "message",
t: remoteUsername
},
p: {msg:cPkt}
}
socket.send(JSON.stringify(pkt));
}
}
function setDataChannelHandlers(dc) {
dc.onmessage = evt => onDataMessage(evt);
dc.onopen = evt => onDataChannelOpen(evt);
}
function onDataChannelOpen(evt) {
$("#newMessage")[0].disabled = false;
$("#sendButton")[0].disabled = false;
}
function onDataChannel(evt) {
var dataChannel = evt.channel;
var keys = Object.keys(pcs);
var comp;
var localDescription;
var remoteDescription;
for(var i = 0; i < keys.length; i++) {
comp = pcs[keys[i]];
if(evt.currentTarget.localDescription.sdp == comp.pc.localDescription.sdp) {
comp.dc = dataChannel;
}
}
setDataChannelHandlers(dataChannel);
}
function send() {
var messageElement = $('#newMessage')[0];
displayMessage("you said: " + messageElement.value);
var message = {f: localUsername, msg: messageElement.value};
messageElement.value = "";
var dataChannel;
var keys = Object.keys(pcs);
var comp;
for(var i = 0; i < keys.length; i++) {
comp = pcs[keys[i]];
dataChannel = comp.dc;
dataChannel.send(JSON.stringify(message));
}
}
function onDataMessage(evt) {
var messageObj = JSON.parse(evt.data);
displayMessage(messageObj.f + " said: " + messageObj.msg);
}
function createNewPeerConnection(username){
var pc = new RTCPeerConnection(ice);
pc.addStream(localStream);
pc.onaddstream = evt => onAddStream(evt);
pc.ondatachannel = evt => onDataChannel(evt);
pc.onicecandidate = candidate => onIceCandidate(candidate);
pcs[username] = {pc: pc, dc: null, s: null, v: null};
return pc;
}
function getUsernameByRemoteDescription(sdp) {
var keys = Object.keys(pcs);
var pc;
for(var i = 0; i < keys.length; i++) {
pc = pcs[keys[i]].pc;
if(pc.remoteDescription.sdp == sdp) {
return keys[i];
}
}
return null;
}
function onGetMedia(stream) {
var vid = $("#localVideo")[0];
vid.srcObject = stream;
localStream = stream;
}
function onAddStream(evt) {
var pc = evt.target;
var stream = evt.stream;
var peer = getUsernameByRemoteDescription(pc.remoteDescription.sdp);
pcs[peer].s = stream;
var v = addNewVideo(stream);
pcs[peer].v = v;
}
function addNewVideo(stream) {
var vid = document.createElement("video");
$("#videos")[0].appendChild(vid);
vid.srcObject = stream;
return vid;
}
</script>
</div>
</body>
</html>
getice.php
<?php
$curl = curl_init();
curl_setopt_array( $curl, array (
CURLOPT_URL =>
"https://global.xirsys.net/_turn/appchannel/",
CURLOPT_USERPWD => "account:key",
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_RETURNTRANSFER => 1
));
$resp = curl_exec($curl);
print $resp;
curl_close($curl);
?>
gettoken.php
$data = array( 'k' => $_POST["username"], 'expire' => 45, 'depth' => 10 );
$qs = http_build_query($data);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://global.xirsys.net/_token/appchannel?'.$qs,
CURLOPT_USERPWD => "account:key",
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_CUSTOMREQUEST => 'PUT'
));
$resp = curl_exec($curl);
curl_close($curl);
echo($resp);
gethost.php
$data = array( 'k' => $_POST["username"], 'type' => 'signal' );
$qs = http_build_query($data);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://global.xirsys.net/_host?'.$qs,
CURLOPT_USERPWD => "account:key",
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_CUSTOMREQUEST => 'GET'
));
$resp = curl_exec($curl);
curl_close($curl);
echo($resp);
Edit: errors -> on Chrome / Firefox
javascript php webrtc xirsys
You're going to have to try to narrow this down a bit... we don't have any way of reproducing this issue.
– Brad
Nov 22 at 2:32
You are right @Brad, actually, I'm a bit lost, I'm not sure how to summarize this... With an account and keys, you will be able to run the code on your side. Is that helps?
– Igor O
Nov 22 at 3:02
1
No, that doesn't help. Figure out whatevt.target
is, ensure it's what you expect, figure out whyremoteDescription
is null, narrow this problem down.
– Brad
Nov 22 at 3:04
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I'm trying to test an example provided by Xirsys where I can proceed with signaling using only PHP. The ice servers / token and host seems to work perfectly, but when trying to connect it returns "uncaught: Typeerror: cannot read property 'sdp' of null. The object it doesn't seem null, not sure what is happening here.
Follow my code:
<html>
<head>
<title>PHP Xirsys</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div class="panel" id="video-wrapper">
<style>
video {
background: #cccccc;
width: 200px;
}
</style>
<div class="col">
<div>
your message: <input type="text" id="newMessage" disabled />
<button id="sendButton" onclick="send()" disabled>send</button>
</div>
<div id="messages"></div>
</div>
<div id="videos">
<video autoplay="true" id="localVideo"></video>
</div>
<div>
username: <input type="text" id="username" />
<button id="connectButton" onclick="connect()">connect</button>
</div>
<script>
var token;
var socket;
var ice;
var pcs = {};
var localUsername;
function displayMessage(message) {
$('#messages')[0].innerHTML += message + "<br>";
}
window.onload = () => {
$.post("getice.php", null, r => onIce(r));
}
function onIce(r) {
ice = JSON.parse(r).v;
navigator.mediaDevices.getUserMedia({audio: true, video: true}).then(stream => onGetMedia(stream));
}
function connect() {
localUsername = $('#username')[0].value;
$.post("gettoken.php", {username: localUsername}, r => getHost(r));
}
function getHost(r) {
token = JSON.parse(r).v;
$.post("gethost.php", {username: localUsername}, r => openSocket(r));
}
function openSocket(r) {
var host = JSON.parse(r).v;
socket = new WebSocket(host + "/v2/" + token);
socket.addEventListener("message", onSocketMessage);
}
function onSocketMessage(evt) {
var data = JSON.parse(evt.data);
var option;
var pc;
switch (data.m.o) {
case "peers":
var users = data.p.users;
for(i = 0; i < users.length; i++) {
displayMessage("user in chat:" + users[i]);
}
break;
case "peer_connected":
var f = data.m.f.split("/");
var joining = f[f.length-1];
displayMessage("new user joined: " + joining)
callPeer(joining);
break;
case "message":
switch(data.p.msg.type) {
case "offer":
var desc = new RTCSessionDescription(data.p.msg);
var f = data.m.f.split("/");
var sender = f[f.length-1];
pc = createNewPeerConnection(sender);
pc.setRemoteDescription(desc);
pc.createAnswer().then(d => onCreateAnswer(d,sender));
break;
case "answer":
var desc = new RTCSessionDescription(data.p.msg);
var f = data.m.f.split("/");
var sender = f[f.length-1];
pcs[sender].pc.setRemoteDescription(desc);
break;
case "candidate":
var f = data.m.f.split("/");
var sender = f[f.length-1];
var candidate = new RTCIceCandidate(data.p.msg);
pcs[sender].pc.addIceCandidate(candidate);
break;
}
}
}
function callPeer(peer) {
var pc = createNewPeerConnection(peer);
var dataChannel = pc.createDataChannel("data");
pcs[peer].dc = dataChannel;
setDataChannelHandlers(dataChannel);
pc.createOffer().then(d => onCreateOffer(d, peer));
}
function onCreateOffer(d, peer) {
pcs[peer].pc.setLocalDescription(d);
var pkt = {t: "u", m: {f: "appchannel/" + localUsername, o: "message", t: peer}, p: {msg:d}};
socket.send(JSON.stringify(pkt));
}
function onCreateAnswer(d, peer) {
pcs[peer].pc.setLocalDescription(d);
var pkt = {t: "u", m: {f: "appchannel/" + localUsername, o: "message", t: peer}, p: {msg:d}};
socket.send(JSON.stringify(pkt));
}
function onIceCandidate(evt) {
var remoteUsername = getUsernameByRemoteDescription(evt.target.remoteDescription.sdp);
var candidate = evt.candidate;
if (candidate != null && remoteUsername != null) {
var cPkt = {type: "candidate",
candidate: candidate.candidate,
sdpMid: candidate.sdpMid,
sdpMLineIndex: candidate.sdpMLineIndex
};
var pkt = {
t: "u",
m: {
f: "appchannel/" + localUsername,
o: "message",
t: remoteUsername
},
p: {msg:cPkt}
}
socket.send(JSON.stringify(pkt));
}
}
function setDataChannelHandlers(dc) {
dc.onmessage = evt => onDataMessage(evt);
dc.onopen = evt => onDataChannelOpen(evt);
}
function onDataChannelOpen(evt) {
$("#newMessage")[0].disabled = false;
$("#sendButton")[0].disabled = false;
}
function onDataChannel(evt) {
var dataChannel = evt.channel;
var keys = Object.keys(pcs);
var comp;
var localDescription;
var remoteDescription;
for(var i = 0; i < keys.length; i++) {
comp = pcs[keys[i]];
if(evt.currentTarget.localDescription.sdp == comp.pc.localDescription.sdp) {
comp.dc = dataChannel;
}
}
setDataChannelHandlers(dataChannel);
}
function send() {
var messageElement = $('#newMessage')[0];
displayMessage("you said: " + messageElement.value);
var message = {f: localUsername, msg: messageElement.value};
messageElement.value = "";
var dataChannel;
var keys = Object.keys(pcs);
var comp;
for(var i = 0; i < keys.length; i++) {
comp = pcs[keys[i]];
dataChannel = comp.dc;
dataChannel.send(JSON.stringify(message));
}
}
function onDataMessage(evt) {
var messageObj = JSON.parse(evt.data);
displayMessage(messageObj.f + " said: " + messageObj.msg);
}
function createNewPeerConnection(username){
var pc = new RTCPeerConnection(ice);
pc.addStream(localStream);
pc.onaddstream = evt => onAddStream(evt);
pc.ondatachannel = evt => onDataChannel(evt);
pc.onicecandidate = candidate => onIceCandidate(candidate);
pcs[username] = {pc: pc, dc: null, s: null, v: null};
return pc;
}
function getUsernameByRemoteDescription(sdp) {
var keys = Object.keys(pcs);
var pc;
for(var i = 0; i < keys.length; i++) {
pc = pcs[keys[i]].pc;
if(pc.remoteDescription.sdp == sdp) {
return keys[i];
}
}
return null;
}
function onGetMedia(stream) {
var vid = $("#localVideo")[0];
vid.srcObject = stream;
localStream = stream;
}
function onAddStream(evt) {
var pc = evt.target;
var stream = evt.stream;
var peer = getUsernameByRemoteDescription(pc.remoteDescription.sdp);
pcs[peer].s = stream;
var v = addNewVideo(stream);
pcs[peer].v = v;
}
function addNewVideo(stream) {
var vid = document.createElement("video");
$("#videos")[0].appendChild(vid);
vid.srcObject = stream;
return vid;
}
</script>
</div>
</body>
</html>
getice.php
<?php
$curl = curl_init();
curl_setopt_array( $curl, array (
CURLOPT_URL =>
"https://global.xirsys.net/_turn/appchannel/",
CURLOPT_USERPWD => "account:key",
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_RETURNTRANSFER => 1
));
$resp = curl_exec($curl);
print $resp;
curl_close($curl);
?>
gettoken.php
$data = array( 'k' => $_POST["username"], 'expire' => 45, 'depth' => 10 );
$qs = http_build_query($data);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://global.xirsys.net/_token/appchannel?'.$qs,
CURLOPT_USERPWD => "account:key",
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_CUSTOMREQUEST => 'PUT'
));
$resp = curl_exec($curl);
curl_close($curl);
echo($resp);
gethost.php
$data = array( 'k' => $_POST["username"], 'type' => 'signal' );
$qs = http_build_query($data);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://global.xirsys.net/_host?'.$qs,
CURLOPT_USERPWD => "account:key",
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_CUSTOMREQUEST => 'GET'
));
$resp = curl_exec($curl);
curl_close($curl);
echo($resp);
Edit: errors -> on Chrome / Firefox
javascript php webrtc xirsys
I'm trying to test an example provided by Xirsys where I can proceed with signaling using only PHP. The ice servers / token and host seems to work perfectly, but when trying to connect it returns "uncaught: Typeerror: cannot read property 'sdp' of null. The object it doesn't seem null, not sure what is happening here.
Follow my code:
<html>
<head>
<title>PHP Xirsys</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div class="panel" id="video-wrapper">
<style>
video {
background: #cccccc;
width: 200px;
}
</style>
<div class="col">
<div>
your message: <input type="text" id="newMessage" disabled />
<button id="sendButton" onclick="send()" disabled>send</button>
</div>
<div id="messages"></div>
</div>
<div id="videos">
<video autoplay="true" id="localVideo"></video>
</div>
<div>
username: <input type="text" id="username" />
<button id="connectButton" onclick="connect()">connect</button>
</div>
<script>
var token;
var socket;
var ice;
var pcs = {};
var localUsername;
function displayMessage(message) {
$('#messages')[0].innerHTML += message + "<br>";
}
window.onload = () => {
$.post("getice.php", null, r => onIce(r));
}
function onIce(r) {
ice = JSON.parse(r).v;
navigator.mediaDevices.getUserMedia({audio: true, video: true}).then(stream => onGetMedia(stream));
}
function connect() {
localUsername = $('#username')[0].value;
$.post("gettoken.php", {username: localUsername}, r => getHost(r));
}
function getHost(r) {
token = JSON.parse(r).v;
$.post("gethost.php", {username: localUsername}, r => openSocket(r));
}
function openSocket(r) {
var host = JSON.parse(r).v;
socket = new WebSocket(host + "/v2/" + token);
socket.addEventListener("message", onSocketMessage);
}
function onSocketMessage(evt) {
var data = JSON.parse(evt.data);
var option;
var pc;
switch (data.m.o) {
case "peers":
var users = data.p.users;
for(i = 0; i < users.length; i++) {
displayMessage("user in chat:" + users[i]);
}
break;
case "peer_connected":
var f = data.m.f.split("/");
var joining = f[f.length-1];
displayMessage("new user joined: " + joining)
callPeer(joining);
break;
case "message":
switch(data.p.msg.type) {
case "offer":
var desc = new RTCSessionDescription(data.p.msg);
var f = data.m.f.split("/");
var sender = f[f.length-1];
pc = createNewPeerConnection(sender);
pc.setRemoteDescription(desc);
pc.createAnswer().then(d => onCreateAnswer(d,sender));
break;
case "answer":
var desc = new RTCSessionDescription(data.p.msg);
var f = data.m.f.split("/");
var sender = f[f.length-1];
pcs[sender].pc.setRemoteDescription(desc);
break;
case "candidate":
var f = data.m.f.split("/");
var sender = f[f.length-1];
var candidate = new RTCIceCandidate(data.p.msg);
pcs[sender].pc.addIceCandidate(candidate);
break;
}
}
}
function callPeer(peer) {
var pc = createNewPeerConnection(peer);
var dataChannel = pc.createDataChannel("data");
pcs[peer].dc = dataChannel;
setDataChannelHandlers(dataChannel);
pc.createOffer().then(d => onCreateOffer(d, peer));
}
function onCreateOffer(d, peer) {
pcs[peer].pc.setLocalDescription(d);
var pkt = {t: "u", m: {f: "appchannel/" + localUsername, o: "message", t: peer}, p: {msg:d}};
socket.send(JSON.stringify(pkt));
}
function onCreateAnswer(d, peer) {
pcs[peer].pc.setLocalDescription(d);
var pkt = {t: "u", m: {f: "appchannel/" + localUsername, o: "message", t: peer}, p: {msg:d}};
socket.send(JSON.stringify(pkt));
}
function onIceCandidate(evt) {
var remoteUsername = getUsernameByRemoteDescription(evt.target.remoteDescription.sdp);
var candidate = evt.candidate;
if (candidate != null && remoteUsername != null) {
var cPkt = {type: "candidate",
candidate: candidate.candidate,
sdpMid: candidate.sdpMid,
sdpMLineIndex: candidate.sdpMLineIndex
};
var pkt = {
t: "u",
m: {
f: "appchannel/" + localUsername,
o: "message",
t: remoteUsername
},
p: {msg:cPkt}
}
socket.send(JSON.stringify(pkt));
}
}
function setDataChannelHandlers(dc) {
dc.onmessage = evt => onDataMessage(evt);
dc.onopen = evt => onDataChannelOpen(evt);
}
function onDataChannelOpen(evt) {
$("#newMessage")[0].disabled = false;
$("#sendButton")[0].disabled = false;
}
function onDataChannel(evt) {
var dataChannel = evt.channel;
var keys = Object.keys(pcs);
var comp;
var localDescription;
var remoteDescription;
for(var i = 0; i < keys.length; i++) {
comp = pcs[keys[i]];
if(evt.currentTarget.localDescription.sdp == comp.pc.localDescription.sdp) {
comp.dc = dataChannel;
}
}
setDataChannelHandlers(dataChannel);
}
function send() {
var messageElement = $('#newMessage')[0];
displayMessage("you said: " + messageElement.value);
var message = {f: localUsername, msg: messageElement.value};
messageElement.value = "";
var dataChannel;
var keys = Object.keys(pcs);
var comp;
for(var i = 0; i < keys.length; i++) {
comp = pcs[keys[i]];
dataChannel = comp.dc;
dataChannel.send(JSON.stringify(message));
}
}
function onDataMessage(evt) {
var messageObj = JSON.parse(evt.data);
displayMessage(messageObj.f + " said: " + messageObj.msg);
}
function createNewPeerConnection(username){
var pc = new RTCPeerConnection(ice);
pc.addStream(localStream);
pc.onaddstream = evt => onAddStream(evt);
pc.ondatachannel = evt => onDataChannel(evt);
pc.onicecandidate = candidate => onIceCandidate(candidate);
pcs[username] = {pc: pc, dc: null, s: null, v: null};
return pc;
}
function getUsernameByRemoteDescription(sdp) {
var keys = Object.keys(pcs);
var pc;
for(var i = 0; i < keys.length; i++) {
pc = pcs[keys[i]].pc;
if(pc.remoteDescription.sdp == sdp) {
return keys[i];
}
}
return null;
}
function onGetMedia(stream) {
var vid = $("#localVideo")[0];
vid.srcObject = stream;
localStream = stream;
}
function onAddStream(evt) {
var pc = evt.target;
var stream = evt.stream;
var peer = getUsernameByRemoteDescription(pc.remoteDescription.sdp);
pcs[peer].s = stream;
var v = addNewVideo(stream);
pcs[peer].v = v;
}
function addNewVideo(stream) {
var vid = document.createElement("video");
$("#videos")[0].appendChild(vid);
vid.srcObject = stream;
return vid;
}
</script>
</div>
</body>
</html>
getice.php
<?php
$curl = curl_init();
curl_setopt_array( $curl, array (
CURLOPT_URL =>
"https://global.xirsys.net/_turn/appchannel/",
CURLOPT_USERPWD => "account:key",
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_RETURNTRANSFER => 1
));
$resp = curl_exec($curl);
print $resp;
curl_close($curl);
?>
gettoken.php
$data = array( 'k' => $_POST["username"], 'expire' => 45, 'depth' => 10 );
$qs = http_build_query($data);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://global.xirsys.net/_token/appchannel?'.$qs,
CURLOPT_USERPWD => "account:key",
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_CUSTOMREQUEST => 'PUT'
));
$resp = curl_exec($curl);
curl_close($curl);
echo($resp);
gethost.php
$data = array( 'k' => $_POST["username"], 'type' => 'signal' );
$qs = http_build_query($data);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://global.xirsys.net/_host?'.$qs,
CURLOPT_USERPWD => "account:key",
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
CURLOPT_CUSTOMREQUEST => 'GET'
));
$resp = curl_exec($curl);
curl_close($curl);
echo($resp);
Edit: errors -> on Chrome / Firefox
javascript php webrtc xirsys
javascript php webrtc xirsys
edited Nov 22 at 2:28
asked Nov 22 at 1:54
Igor O
232415
232415
You're going to have to try to narrow this down a bit... we don't have any way of reproducing this issue.
– Brad
Nov 22 at 2:32
You are right @Brad, actually, I'm a bit lost, I'm not sure how to summarize this... With an account and keys, you will be able to run the code on your side. Is that helps?
– Igor O
Nov 22 at 3:02
1
No, that doesn't help. Figure out whatevt.target
is, ensure it's what you expect, figure out whyremoteDescription
is null, narrow this problem down.
– Brad
Nov 22 at 3:04
add a comment |
You're going to have to try to narrow this down a bit... we don't have any way of reproducing this issue.
– Brad
Nov 22 at 2:32
You are right @Brad, actually, I'm a bit lost, I'm not sure how to summarize this... With an account and keys, you will be able to run the code on your side. Is that helps?
– Igor O
Nov 22 at 3:02
1
No, that doesn't help. Figure out whatevt.target
is, ensure it's what you expect, figure out whyremoteDescription
is null, narrow this problem down.
– Brad
Nov 22 at 3:04
You're going to have to try to narrow this down a bit... we don't have any way of reproducing this issue.
– Brad
Nov 22 at 2:32
You're going to have to try to narrow this down a bit... we don't have any way of reproducing this issue.
– Brad
Nov 22 at 2:32
You are right @Brad, actually, I'm a bit lost, I'm not sure how to summarize this... With an account and keys, you will be able to run the code on your side. Is that helps?
– Igor O
Nov 22 at 3:02
You are right @Brad, actually, I'm a bit lost, I'm not sure how to summarize this... With an account and keys, you will be able to run the code on your side. Is that helps?
– Igor O
Nov 22 at 3:02
1
1
No, that doesn't help. Figure out what
evt.target
is, ensure it's what you expect, figure out why remoteDescription
is null, narrow this problem down.– Brad
Nov 22 at 3:04
No, that doesn't help. Figure out what
evt.target
is, ensure it's what you expect, figure out why remoteDescription
is null, narrow this problem down.– Brad
Nov 22 at 3:04
add a comment |
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53422849%2fxirsys-webrtc-cant-find-sdp-object%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You're going to have to try to narrow this down a bit... we don't have any way of reproducing this issue.
– Brad
Nov 22 at 2:32
You are right @Brad, actually, I'm a bit lost, I'm not sure how to summarize this... With an account and keys, you will be able to run the code on your side. Is that helps?
– Igor O
Nov 22 at 3:02
1
No, that doesn't help. Figure out what
evt.target
is, ensure it's what you expect, figure out whyremoteDescription
is null, narrow this problem down.– Brad
Nov 22 at 3:04