Skip to content

Commit

Permalink
add webrtc stream
Browse files Browse the repository at this point in the history
  • Loading branch information
bjsowa committed Feb 11, 2019
1 parent bad871c commit 0a1a242
Show file tree
Hide file tree
Showing 3 changed files with 222 additions and 1 deletion.
7 changes: 6 additions & 1 deletion tr_webui/www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,18 @@
</div>
<div class="col-md-10"></div>
</div>



<div class="stream-wrapper">
<video id="stream"/>
</div>

<script src="scripts/jquery-3.3.1.slim.min.js"></script>
<script src="scripts/bootstrap.min.js"></script>
<script src="scripts/bootstrap-slider.min.js"></script>
<script src="scripts/roslib.min.js"></script>
<script src="scripts/nipplejs.js"></script>
<script src="scripts/stream.js"></script>
<script src="scripts/webui.js"></script>
</body>
</html>
211 changes: 211 additions & 0 deletions tr_webui/www/scripts/stream.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
const Stream = function () {
this.protocol = location.protocol === "https:" ? "wss:" : "ws:";
this.hostname = document.location.hostname;
this.port = 8090;

this.url = this.protocol + '//' + this.hostname + ":" + this.port + '/stream/webrtc';

this.websocket = null;
this.peerConnection = null;
this.dataChannel = null;
this.remoteDesc = false;

this.iceCandidates = [];
};

Stream.prototype.start = function() {
console.log('[stream] Starting on:', this.url);

this.websocket = new WebSocket(this.url);

this.websocket.onopen = () => this.open();
this.websocket.onmessage = (event) => this.message(event);
this.websocket.onclose = (event) => this.close(event);
this.websocket.onerror = (event) => this.error(event);
}

Stream.prototype.createPeerConnection = function() {
let peerConnectionConf = {
"iceServers": [{
"urls": ["stun:" + this.hostname + ":3478"]
}]
};

this.peerConnection = new window.RTCPeerConnection(peerConnectionConf);

this.peerConnection.onicecandidate = (event) => {
if (event.candidate) {
let candidate = JSON.stringify({
sdpMLineIndex: event.candidate.sdpMLineIndex,
sdpMid: event.candidate.sdpMid,
candidate: event.candidate.candidate
});
let command = JSON.stringify({
what: "addicecandidate",
data: candidate
});
this.websocket.send(command);
} else {
console.log("[stream] End of candidates");
}
}


this.peerConnection.ontrack = (event) => {
console.log("[stream] remote stream added:", event.streams[0]);
let remoteVideoElement = document.getElementById('stream');
remoteVideoElement.srcObject = event.streams[0];
remoteVideoElement.play();
}

this.peerConnection.onremovestream = () => console.log('[stream] remove');

}

Stream.prototype.offer = function() {
this.createPeerConnection();
this.iceCandidates = [];
this.remoteDesc = false;
var command = {
what: "call",
options: {
force_hw_vcodec: true,
vformat: 30,
trickle_ice: true
}
};
this.websocket.send(JSON.stringify(command));
console.log("[stream] offer(), command=" + JSON.stringify(command));
}

Stream.prototype.open = function() {
this.offer();
console.log('[stream] state:', this.websocket.readyState);
}

Stream.prototype.addIceCandidates = function () {

this.iceCandidates.forEach((candidate) => {
this.peerConnection.addIceCandidate(candidate,
function() {
console.log("[stream] IceCandidate added: " + JSON.stringify(candidate));
},
function(error) {
console.error("[stream] addIceCandidate error: " + error);
}
);
});
this.iceCandidates = [];
}

Stream.prototype.message = function(event) {

var msg = JSON.parse(event.data);
var what = msg.what;
var data = msg.data;
console.log("[stream] message =" + what);

switch (what) {
case "offer":
this.peerConnection.setRemoteDescription(
new window.RTCSessionDescription(JSON.parse(data)),
() => this._onRemoteSdpSuccess(),
() => this._onRemoteSdpError()
);
break;

case "answer":
break;

case "message":
console.error('[stream]',msg.data);
break;

case "iceCandidate": // when trickle is enabled
if (!msg.data) {
console.log("[stream] Ice Gathering Complete");
break;
}
var elt = JSON.parse(msg.data);
let candidate = new RTCIceCandidate({
sdpMLineIndex: elt.sdpMLineIndex,
candidate: elt.candidate
});
this.iceCandidates.push(candidate);
if (this.remoteDesc) {
this.addIceCandidates();
}
break;


case "iceCandidates":
var candidates = JSON.parse(msg.data);
for (var i = 0; candidates && i < candidates.length; i++) {
var elt = candidates[i];
let candidate = new window.RTCIceCandidate({
sdpMLineIndex: elt.sdpMLineIndex,
candidate: elt.candidate
});
this.addIceCandidates();
}
if (remoteDesc){
addIceCandidates();
}
break;
}
}



Stream.prototype._onRemoteSdpSuccess = function() {
console.log('[stream] onRemoteSdpSucces()');
this.remoteDesc = true;
this.peerConnection.createAnswer((sessionDescription) => {
this.peerConnection.setLocalDescription(sessionDescription);
let request = JSON.stringify({
what: "answer",
data: JSON.stringify(sessionDescription)
});
console.log('[stream] sdp success', request);

this.websocket.send(request);

},
(error) => console.error(error), {
optional: [],
mandatory: {
OfferToReceiveAudio: true,
OfferToReceiveVideo: true
}
});
}

Stream.prototype._onRemoteSdpError = function(event) {
console.error('[stream] Failed to set remote description (unsupported codec on this browser?):', event);
this.stop();
}

Stream.prototype.close = function(event) {
if (this.peerConnection) {
this.peerConnection.close();
this.peerConnection = null;
}
}

Stream.prototype.error = function(event) {
console.error('[stream] error', event);
this.websocket.close();
}

Stream.prototype.stop = function() {
// stop_record();
document.getElementById('stream').src = '';

this.close();

if (this.websocket) {
this.websocket.close();
this.websocket = null;
}
console.info('[stream] Stop.')
}
5 changes: 5 additions & 0 deletions tr_webui/www/scripts/webui.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var batteryClient;
var cmdVelPub;
var servoPub;
var servoAngles;
var stream;

function initROS() {

Expand Down Expand Up @@ -130,6 +131,7 @@ function initSliders() {
});
$('#lin-slider').on("slide", function(slideEvt) {
speedLinear = slideEvt.value;
console.log(speedLinear);
});
speedLinear = 0.2

Expand Down Expand Up @@ -226,4 +228,7 @@ window.onload = function () {
});
}, 1000);

stream = new Stream();
window.onbeforeunload = () => stream.stop();
stream.start();
}

0 comments on commit 0a1a242

Please sign in to comment.