This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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