You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
7.2 KiB
243 lines
7.2 KiB
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Roberto</title>
|
|
<!-- Bootstrap -->
|
|
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
|
|
<style>
|
|
body {
|
|
background: black;
|
|
}
|
|
#stream, #textoverlay {
|
|
position: absolute;
|
|
top: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
#controls_l {
|
|
position: absolute;
|
|
bottom: 75px;
|
|
left: 0;
|
|
width: 40%;
|
|
height: 33%;
|
|
pointer-events: all;
|
|
}
|
|
#controls_r {
|
|
position: absolute;
|
|
bottom: 75px;
|
|
right: 0;
|
|
width: 40%;
|
|
height: 33%;
|
|
pointer-events: all;
|
|
}
|
|
p {
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
#message {
|
|
position: absolute;
|
|
z-index: 1;
|
|
top: 20px;
|
|
right: 50px
|
|
}
|
|
.stats-box {
|
|
position: absolute;
|
|
right: 20px;
|
|
top: 100px;
|
|
color: white;
|
|
opacity: 0.6;
|
|
z-index: 1;
|
|
}
|
|
#textoverlay, .stats-box {
|
|
pointer-events: none;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Video Streaming Demonstration</h1>
|
|
{# <!--<img src="{{ url_for('frontend.video_feed') }}">--> #}
|
|
|
|
<div id="video">
|
|
<video id="stream" autoplay playsinline muted controls>Your browser does not support video</video>
|
|
<canvas id="textoverlay"></canvas>
|
|
<div id="controls_l"></div>
|
|
<div id="controls_r"></div>
|
|
</div>
|
|
<form id="message" method="POST" action='#'>
|
|
<input type="text" name="message_data" id="message_data" placeholder="Message">
|
|
<input type="submit" value="Send">
|
|
</form>
|
|
<div class="stats-box"></div>
|
|
|
|
<!--<h2 id="start">Press a button on your controller to start</h2>-->
|
|
|
|
<!-- jQuery and Bootstrap -->
|
|
<script src="{{ url_for('static', filename='js/jquery.min.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
|
|
|
|
<script src="{{ url_for('static', filename='js/socket.io.js') }}"></script>
|
|
<!--<script type="text/javascript" src="https://webrtc.github.io/adapter/adapter-latest.js"></script>-->
|
|
<script src="{{ url_for('static', filename='js/nipplejs.js') }}"></script>
|
|
|
|
<script type="text/javascript">
|
|
'use strict';
|
|
var html5VideoElement;
|
|
var wsUrl = "wss://" + window.location.hostname + ":" + window.location.port + "/webrtc";
|
|
var socket = io.connect(wsUrl, { autoConnect: false, transports: [ 'websocket' ] });
|
|
var webrtcPeerConnection;
|
|
var webrtcConfiguration;
|
|
var reportError;
|
|
|
|
|
|
function onLocalDescription(desc) {
|
|
console.log("Local description: " + JSON.stringify(desc));
|
|
webrtcPeerConnection.setLocalDescription(desc).then(function() {
|
|
socket.emit('message', { "type": "sdp", "data": webrtcPeerConnection.localDescription });
|
|
}).catch(reportError);
|
|
}
|
|
|
|
|
|
function onIncomingSDP(sdp) {
|
|
console.log("Incoming SDP: " + JSON.stringify(sdp));
|
|
webrtcPeerConnection.setRemoteDescription(sdp).catch(reportError);
|
|
webrtcPeerConnection.createAnswer().then(onLocalDescription).catch(reportError);
|
|
}
|
|
|
|
|
|
function onIncomingICE(ice) {
|
|
var candidate = new RTCIceCandidate(ice);
|
|
console.log("Incoming ICE: " + JSON.stringify(ice));
|
|
webrtcPeerConnection.addIceCandidate(candidate).catch(reportError);
|
|
}
|
|
|
|
|
|
function onAddRemoteStream(event) {
|
|
html5VideoElement.srcObject = event.streams[0];
|
|
}
|
|
|
|
|
|
function onIceCandidate(event) {
|
|
if (event.candidate == null)
|
|
return;
|
|
|
|
console.log("Sending ICE candidate out: " + JSON.stringify(event.candidate));
|
|
socket.emit('message', { "type": "ice", "data": event.candidate });
|
|
}
|
|
|
|
socket.on('connect', function(){
|
|
console.log("Connected...!", socket.connected)
|
|
});
|
|
|
|
socket.on('message', (data) => {
|
|
console.log("got message: ",data);
|
|
var msg;
|
|
|
|
try {
|
|
msg = JSON.parse(data);
|
|
} catch (e) {
|
|
console.log("ERROR parsing message");
|
|
return;
|
|
}
|
|
|
|
if (!webrtcPeerConnection) {
|
|
webrtcPeerConnection = new RTCPeerConnection(webrtcConfiguration);
|
|
webrtcPeerConnection.ontrack = onAddRemoteStream;
|
|
webrtcPeerConnection.onicecandidate = onIceCandidate;
|
|
}
|
|
|
|
switch (msg.type) {
|
|
case "sdp": onIncomingSDP(msg.data); break;
|
|
case "ice": onIncomingICE(msg.data); break;
|
|
default: break;
|
|
}
|
|
});
|
|
|
|
socket.on('data', (data) => {
|
|
console.log('Data received: ',data);
|
|
});
|
|
|
|
socket.on('battery', (data) => {
|
|
console.log('Data received: ',data);
|
|
var canvas = document.getElementById("textoverlay");
|
|
var ctx = canvas.getContext("2d");
|
|
ctx.font = "14px Arial";
|
|
ctx.fillStyle = "blue";
|
|
ctx.fillText(data, 3*canvas.width/4, 30);
|
|
});
|
|
|
|
function playStream(videoElement, hostname, port, path, configuration, reportErrorCB) {
|
|
var l = window.location;
|
|
var wsHost = (hostname != undefined) ? hostname : l.hostname;
|
|
var wsPort = (port != undefined) ? port : l.port;
|
|
var wsPath = (path != undefined) ? path : "webrtc";
|
|
if (wsPort)
|
|
wsPort = ":" + wsPort;
|
|
var wsUrl = "wss://" + wsHost + wsPort + "/" + wsPath;
|
|
|
|
html5VideoElement = videoElement;
|
|
webrtcConfiguration = configuration;
|
|
reportError = (reportErrorCB != undefined) ? reportErrorCB : function(text) {};
|
|
|
|
socket.connect();
|
|
}
|
|
|
|
window.onload = function() {
|
|
var vidstream = document.getElementById("stream");
|
|
var config = { 'iceServers': [{ 'urls': 'stun:stun.l.google.com:19302' }] };
|
|
playStream(vidstream, null, null, null, config, function (errmsg) { console.error(errmsg); });
|
|
|
|
var canvas = document.getElementById("textoverlay");
|
|
var ctx = canvas.getContext("2d");
|
|
ctx.font = "24px Arial";
|
|
ctx.fillStyle = "blue";
|
|
//ctx.fillText("Hello World", canvas.width/3, 30);
|
|
|
|
$('form#message').submit(function(event) {
|
|
gp_socket.emit('text', {data: $('#message_data').val()});
|
|
$('#message_data').val("");
|
|
return false;
|
|
});
|
|
};
|
|
|
|
|
|
function getConnectionStats() {
|
|
if (webrtcPeerConnection) {
|
|
webrtcPeerConnection.getStats(null).then(stats => {
|
|
var statsOutput = "";
|
|
|
|
stats.forEach(report => {
|
|
if (report.type === "inbound-rtp" && report.kind === "video") {
|
|
Object.keys(report).forEach(statName => {
|
|
statsOutput += `<strong>${statName}:</strong> ${report[statName]}<br>\n`;
|
|
});
|
|
}
|
|
});
|
|
|
|
document.querySelector(".stats-box").innerHTML = statsOutput;
|
|
});
|
|
}
|
|
}
|
|
|
|
var statsInterval = window.setInterval(getConnectionStats, 1000);
|
|
|
|
setInterval(function(){
|
|
if (socket.connected) {
|
|
socket.emit('ping_message', { "type": "ping" });
|
|
}
|
|
}, 10000);
|
|
|
|
socket.on('ping_message', (data) => {
|
|
console.log('ping received: ',data);
|
|
});
|
|
|
|
</script>
|
|
|
|
<script src="{{ url_for('frontend.gamepad_js') }}"></script>
|
|
|
|
</body>
|
|
</html>
|
|
|