Files
go2rtc/www/webrtc.html
T
Sergey Krashevich e71ed5e7eb feat(icons): add favicon and apple-touch-icon links across all pages
Added favicon, apple-touch-icon, and related meta tags to all HTML pages to ensure consistent branding and improve user experience on various platforms.
2024-05-09 06:30:14 +03:00

115 lines
4.3 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="apple-touch-icon" sizes="180x180" href="https://alexxit.github.io/go2rtc/icons/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="https://alexxit.github.io/go2rtc/icons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="https://alexxit.github.io/go2rtc/icons/favicon-16x16.png">
<link rel="manifest" href="https://alexxit.github.io/go2rtc/icons/site.webmanifest">
<link rel="mask-icon" href="https://alexxit.github.io/go2rtc/icons/safari-pinned-tab.svg" color="#5bbad5">
<link rel="shortcut icon" href="https://alexxit.github.io/go2rtc/icons/favicon.ico">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="msapplication-config" content="https://alexxit.github.io/go2rtc/icons/browserconfig.xml">
<title>go2rtc - WebRTC</title>
<style>
body {
background-color: black;
margin: 0;
padding: 0;
}
html, body, video {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<video id="video" autoplay controls playsinline muted></video>
<script>
async function PeerConnection(media) {
const pc = new RTCPeerConnection({
iceServers: [{urls: 'stun:stun.l.google.com:19302'}]
});
const localTracks = [];
if (/camera|microphone/.test(media)) {
const tracks = await getMediaTracks('user', {
video: media.indexOf('camera') >= 0,
audio: media.indexOf('microphone') >= 0,
});
tracks.forEach(track => {
pc.addTransceiver(track, {direction: 'sendonly'});
if (track.kind === 'video') localTracks.push(track);
});
}
if (media.indexOf('display') >= 0) {
const tracks = await getMediaTracks('display', {
video: true,
audio: media.indexOf('speaker') >= 0,
});
tracks.forEach(track => {
pc.addTransceiver(track, {direction: 'sendonly'});
if (track.kind === 'video') localTracks.push(track);
});
}
if (/video|audio/.test(media)) {
const tracks = ['video', 'audio']
.filter(kind => media.indexOf(kind) >= 0)
.map(kind => pc.addTransceiver(kind, {direction: 'recvonly'}).receiver.track);
localTracks.push(...tracks);
}
document.getElementById('video').srcObject = new MediaStream(localTracks);
return pc;
}
async function getMediaTracks(media, constraints) {
try {
const stream = media === 'user'
? await navigator.mediaDevices.getUserMedia(constraints)
: await navigator.mediaDevices.getDisplayMedia(constraints);
return stream.getTracks();
} catch (e) {
console.warn(e);
return [];
}
}
async function connect(media) {
const pc = await PeerConnection(media);
const url = new URL('api/ws' + location.search, location.href);
const ws = new WebSocket('ws' + url.toString().substring(4));
ws.addEventListener('open', () => {
pc.addEventListener('icecandidate', ev => {
if (!ev.candidate) return;
const msg = {type: 'webrtc/candidate', value: ev.candidate.candidate};
ws.send(JSON.stringify(msg));
});
pc.createOffer().then(offer => pc.setLocalDescription(offer)).then(() => {
const msg = {type: 'webrtc/offer', value: pc.localDescription.sdp};
ws.send(JSON.stringify(msg));
});
});
ws.addEventListener('message', ev => {
const msg = JSON.parse(ev.data);
if (msg.type === 'webrtc/candidate') {
pc.addIceCandidate({candidate: msg.value, sdpMid: '0'});
} else if (msg.type === 'webrtc/answer') {
pc.setRemoteDescription({type: 'answer', sdp: msg.value});
}
});
}
const media = new URLSearchParams(location.search).get('media');
connect(media || 'video+audio');
</script>
</body>
</html>