Skip to content

Instantly share code, notes, and snippets.

@peisuke
Created December 22, 2022 15:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peisuke/56430261971a982a238654d777ebc1f9 to your computer and use it in GitHub Desktop.
Save peisuke/56430261971a982a238654d777ebc1f9 to your computer and use it in GitHub Desktop.
<html>
<head>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script type="text/javascript" src="https://cdn.webrtc.ecl.ntt.com/skyway-latest.js"></script>
</head>
<body>
<div class="controller-container">
<button id="js-join-trigger">Join</button>
<button id="js-leave-trigger">Leave</button>
</div>
<div id="canvas"></div>
<div id="js-videos-container" class="videos-container">
<audio id="js-local-video"></audio>
</div>
<script>
const localVideo = document.getElementById('js-local-video');
const videosContainer = document.getElementById('js-videos-container');
const joinTrigger = document.getElementById('js-join-trigger');
const leaveTrigger = document.getElementById('js-leave-trigger');
const canvasElem = document.getElementById('canvas');
const Peer = window.Peer;
const peer = new Peer({key: "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxx"});
let room = null; // 部屋
let position = {"X": 300, "Y": 300}; // 自分の位置
let users = {}; // 他人の位置(キーはID)
let dragPosition = null
async function setup() {
canvas = createCanvas(600, 600);
canvas.parent(canvasElem);
// メディアを初期化しておく
localVideo.srcObject = await navigator.mediaDevices.getUserMedia({video: false, audio: true});
}
function mousePressed() {
dragPosition = {"positionX": position.X, "positionY": position.Y, "mouseX": mouseX, "mouseY": mouseY}
}
function mouseDragged() {
if (dragPosition !== null && mouseIsPressed) {
position.X = dragPosition.positionX + (mouseX - dragPosition.mouseX)
position.Y = dragPosition.positionY + (mouseY - dragPosition.mouseY)
}
}
function mouseReleased() {
dragPosition = null;
}
function sync() {
room.send({"X": position.X, "Y": position.Y});
const sigmoid = (x) => { return Math.exp(x) / (Math.exp(x) + 1) };
const remoteVideos = videosContainer.querySelectorAll('[data-peer-id]');
Array.from(remoteVideos)
.forEach(remoteVideo => {
id = remoteVideo.getAttribute("data-peer-id");
if (id in users)
remoteVideo.volume = sigmoid(10 - (dist(position.X, position.Y, users[id].X, users[id].Y) / 20));
});
setTimeout(sync, 100);
}
function draw() {
background(255, 255, 255);
noStroke();
fill(0);
for (const id in users)
ellipse(users[id].X, users[id].Y, 30, 30);
ellipse(position.X, position.Y, 50, 50);
}
// joinボタンを押すと入室
joinTrigger.addEventListener('click', () => {
// 部屋に入る
room = peer.joinRoom("room-name", {mode: 'sfu', stream: localVideo.srcObject});
// 部屋に入ったらスタート
room.on('open', () => {
setTimeout(sync, 100);
});
// 他の人のメディアを自分のvideoContainerに追加
room.on('stream', async stream => {
const remoteVideo = document.createElement('audio');
remoteVideo.srcObject = stream;
remoteVideo.setAttribute('data-peer-id', stream.peerId);
videosContainer.append(remoteVideo);
await remoteVideo.play().catch(console.error);
});
// 他の人の位置情報が受信されたら追加・更新
room.on('data', async (data) => { users[data.src] = data.data; });
// 他の人が抜けたら、ビデオを削除
room.on('peerLeave', peerId => {
const remoteVideo = videosContainer.querySelector(`[data-peer-id="${peerId}"]`);
remoteVideo.srcObject.getTracks().forEach(track => { track.stop(); });
remoteVideo.srcObject = null;
remoteVideo.remove();
delete users[peerId];
});
// 自信が抜ける場合は全てのビデオ情報を削除
room.once('close', () => {
const remoteVideos = videosContainer.querySelectorAll('[data-peer-id]');
Array.from(remoteVideos)
.forEach(remoteVideo => {
remoteVideo.srcObject.getTracks().forEach(track => track.stop());
remoteVideo.srcObject = null;
remoteVideo.remove();
});
});
// Leaveボタンを押したらルームから離れる
leaveTrigger.addEventListener('click', () => {
room.close();
users = {}
}, { once: true });
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment