Просмотр исходного кода

Add initial settings panel to control what gets sent over the connection.

tags/blog-initial
Daniel Perelman 1 год назад
Родитель
Сommit
be31c45107
1 измененных файлов: 144 добавлений и 32 удалений
  1. +144
    -32
      camera/templates/index.html

+ 144
- 32
camera/templates/index.html Просмотреть файл

@@ -7,15 +7,66 @@
body.justVideo {
margin: 0;
overflow: hidden;
}
#selfView {
position: fixed;
right: 0;
bottom: 0;
border: 5px solid blue;
}
#unmute {
position: fixed;
top: 0;
width: 100%;
font-size: 4em;
}
form {
background: lightgray;
border: solid gold 5px;
display: inline-block;
display: table;
}
form label {
display: table-row;
}
#status {
clear: both;
}
</style>
</head>
<body>
<a id="qrcodelink" style="display:none;"><img id="qrcode" /></a>
<span id="status"></span>
<div id="videos" style="display:none;">
<video id="remoteView" width="100%" autoplay muted></video>
<video id="selfView" width="200" height="150" autoplay></video>
<form name="settings">
<label>
Recieve remote video:
<select name="client-video">
<option value="none">none</option>
<option value="environment" selected>rear camera</option>
<option value="user">front camera</option>
<option value="screen">screen share</option>
</select>
</label>
<label>
Recieve remote audio:
<input name="client-audio" type="checkbox" value="true" />
</label>
<label>
Transmit video:
<select name="host-video">
<option value="none">none</option>
<option value="screen">screen share</option>
</select>
</label>
<label>
Transmit audio:
<input name="host-audio" type="checkbox" value="true" />
</label>
</form>
<div id="status"></div>
<div id="videos">
<button id="unmute" style="display:none;">Unmute</button>
<video id="remoteView" width="100%" autoplay muted style="display:none;"></video>
<video id="selfView" width="200" height="150" autoplay muted style="display:none;"></video>
</div>
<script >
const create = (container, type) => container.appendChild(document.createElement(type));
@@ -25,9 +76,27 @@ body.justVideo {
const qrcode = document.getElementById("qrcode");
const qrcodelink = document.getElementById("qrcodelink");
const remoteView = document.getElementById("remoteView");
remoteView.style.display = 'none';
const selfView = document.getElementById("selfView");
const unmute = document.getElementById("unmute");
const form = document.forms["settings"];

out.innerText += "Loading...\n";

unmute.addEventListener("click", _ => {
remoteView.muted = false;
unmute.style.display = 'none';
});

var settings = undefined;
function readSettingsForm() {
const obj = {};
for (const el of form.elements) {
obj[el.name] = el.type == 'checkbox' ? el.checked : el.value;
el.disabled = true;
}
return obj;
}

function getRoomName() {
JSON.parse(document.getElementById('room-name').textContent);
}
@@ -53,6 +122,7 @@ body.justVideo {
} else {
roomName = roomName.substring(1);
qrcodelink.style.display = 'none';
form.style.display = 'none';
}

out.innerText += "Room: " + roomName + "\n";
@@ -91,6 +161,7 @@ body.justVideo {
remoteView.play();
out.innerText += "Set srcObject\n";
out.style.display = 'none';
form.style.display = 'none';
videos.style.display = '';
body.classList.add('justVideo');
};
@@ -98,15 +169,73 @@ body.justVideo {
return pc;
}

async function receiveMessage(e) {
if (pc === undefined) pc = createRTCPeerConnection();
// get a local stream, show it in a self-view and add it to be sent
async function startStreaming() {
const otherAudioSettings = isHost
? settings['client-audio']
: settings['host-audio'];
if (otherAudioSettings) {
unmute.style.display = '';
}

if (pc !== undefined) return;
pc = createRTCPeerConnection();

const videoSettings = isHost
? settings['host-video']
: settings['client-video'];
out.innerText += "videoSettings=" + videoSettings;
const audioSettings = isHost
? settings['host-audio']
: settings['client-audio'];
out.innerText += "audioSettings=" + audioSettings;

if (videoSettings == 'screen') alert('screen share unsupported');

const videoConstraints = videoSettings == 'none'
? false
: { advanced: [{facingMode: videoSettings}] };
out.innerText += "Created videoConstraints.\n";
const stream = await navigator.mediaDevices.getUserMedia({
audio: audioSettings,
video: videoConstraints
});
out.innerText += "Created stream.\n";
if (videoConstraints) {
selfView.srcObject = stream;
selfView.style.display = '';
}
for (const track of stream.getTracks()) {
out.innerText += "Added track.\n";
pc.addTrack(track, stream);
}
}
function startStartingWithErorrHandling() {
startStreaming()
.then(() => {
out.innerText += "startStreaming() finished.\n";
})
.catch(e => {
out.innerText += "startStreaming() errored: " + e.message + "\n";
});
}

async function receiveMessage(e) {
qrcode.style.display = 'none';
out.innerText += "In webSocket.onmessage...\n";
create(out, 'pre').innerText = e.data.split('\\r\\n').join('\r\n');
create(out, 'br');
const data = JSON.parse(e.data);
if (data.description) {
if (data.requestSettings) {
settings = readSettingsForm();
sendJson({
settings: settings
});
} else if (data.settings) {
settings = data.settings;
startStartingWithErorrHandling();
} else if (data.description) {
startStartingWithErorrHandling();
await pc.setRemoteDescription(data.description);
if (data.description.type == "offer") {
out.innerText += "Got an offer...\n";
@@ -116,6 +245,7 @@ body.justVideo {
});
}
} else if (data.candidate) {
startStartingWithErorrHandling();
out.innerText += "Adding ice candidate...\n";
await pc.addIceCandidate(data.candidate);
}
@@ -132,7 +262,10 @@ body.justVideo {
out.innerText += "Created WebSocket.\n";

webSocket.onclose = function(e) {
console.error('Web socket closed unexpectedly');
out.innerText += 'WebSocket closed unexpectedly: ' + e + '\n';
};
webSocket.onerror = function(e) {
out.innerText += 'WebSocket error: ' + e + '\n';
};

webSocket.onmessage = receiveMessage;
@@ -142,31 +275,10 @@ body.justVideo {

webSocket = createWebSocket();

// get a local stream, show it in a self-view and add it to be sent
async function startStreaming() {
pc = createRTCPeerConnection();

const videoConstraints = { advanced: [{facingMode: "environment"}] };
out.innerText += "Created videoConstraints.\n";
const stream = await navigator.mediaDevices.getUserMedia({ "audio": false, "video": videoConstraints });
out.innerText += "Created stream.\n";
selfView.srcObject = stream;
for (const track of stream.getTracks()) {
out.innerText += "Added track.\n";
pc.addTrack(track, stream);
}
}

if (!isHost) {
startStreaming()
.then(() => {
out.innerText += "startStreaming() finished.\n";
})
.catch(e => {
out.innerText += "startStreaming() errored: " + e.message + "\n";
})
;
webSocket.onopen = _ => sendJson({requestSettings: true});
}

out.innerText += "Finished <script> block.\n";
</script>
</body>


Загрузка…
Отмена
Сохранить