Stable index.js
This commit is contained in:
parent
41b7a052ab
commit
3d8fb16d70
|
@ -5,6 +5,7 @@ html,body{
|
|||
body{
|
||||
background-color: #141414;
|
||||
overflow: hidden;
|
||||
font-family: system-ui;
|
||||
}
|
||||
*{
|
||||
box-sizing: border-box;
|
||||
|
@ -73,6 +74,7 @@ video{
|
|||
top: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.tool-container > .tools{
|
||||
margin: auto;
|
||||
|
@ -98,3 +100,43 @@ video{
|
|||
line-height: 2;
|
||||
}
|
||||
|
||||
.tool-container > .namer{
|
||||
flex: 0 0 auto;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
color: white;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
line-height: 2;
|
||||
margin: 10px;
|
||||
width: max-content;
|
||||
padding: 0 10px;
|
||||
|
||||
.avatar {
|
||||
display: flex;
|
||||
& > *{
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tool-container > .progress{
|
||||
margin-top: auto;
|
||||
margin-bottom: 10px;
|
||||
width: 250px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
height: 5px;
|
||||
border-radius: 5px;
|
||||
background-color: white;
|
||||
overflow: auto;
|
||||
|
||||
& .progress-box {
|
||||
height: 5px;
|
||||
width: 50%;
|
||||
background-color: red;
|
||||
transition: width 0.05s linear;
|
||||
}
|
||||
}
|
162
public/index.js
162
public/index.js
|
@ -1,3 +1,4 @@
|
|||
const url = new URL(window.location);
|
||||
/**
|
||||
* @type {import("./MWSE/index").default}
|
||||
*/
|
||||
|
@ -6,6 +7,14 @@ let mwse;
|
|||
* @type {string}
|
||||
*/
|
||||
let mySocketId;
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
let myIPAddress;
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
let myNumber;
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
|
@ -33,19 +42,11 @@ function connect()
|
|||
mwse = new MWSE({
|
||||
endpoint: "wss://ws.saqut.com"
|
||||
});
|
||||
|
||||
MWSE.rtc.defaultICEServers = [{
|
||||
urls: "turn:20.166.82.187:3478",
|
||||
username: "turnserver",
|
||||
credential: "turnserver"
|
||||
},{
|
||||
urls: "stun:stun.l.google.com:19302"
|
||||
}];
|
||||
|
||||
mwse.scope(beginEngine);
|
||||
}
|
||||
|
||||
|
||||
let peername = url.searchParams.get("user");
|
||||
|
||||
let interact = false;
|
||||
|
||||
|
@ -64,23 +65,31 @@ document.addEventListener("click",()=>{
|
|||
*/
|
||||
let activeVideo;
|
||||
|
||||
function templateVideo(name, stream,infinitedMute)
|
||||
function templateVideo(name, stream,infinitedMute, peername)
|
||||
{
|
||||
let t = new DOMParser().parseFromString(`
|
||||
<div class="frame">
|
||||
<video autoplay playsinline muted data-name="${name}">
|
||||
<div class="frame" data-name="${name}">
|
||||
<video autoplay playsinline muted>
|
||||
|
||||
</video>
|
||||
<!--div class="tool-container">
|
||||
<div class="tools">
|
||||
<button>
|
||||
<i class="material-icons">home</i>
|
||||
</button>
|
||||
<button>
|
||||
<i class="material-icons">close</i>
|
||||
</button>
|
||||
<div class="tool-container">
|
||||
<div class="namer">
|
||||
<div class="avatar">
|
||||
<i class="material-icons">account_circle</i>
|
||||
</div>
|
||||
<div class="name">
|
||||
${peername ?? "User"}
|
||||
</div>
|
||||
</div>
|
||||
</div--->
|
||||
<div class="tools">
|
||||
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-box">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,"text/html");
|
||||
|
||||
|
@ -93,14 +102,17 @@ function templateVideo(name, stream,infinitedMute)
|
|||
i.muted = 1;
|
||||
i.classList.add("soundon");
|
||||
}
|
||||
if(stream) i.srcObject = stream;
|
||||
if(stream){
|
||||
i.srcObject = stream;
|
||||
bindAudioLevel(stream, t.querySelector(".progress-box"));
|
||||
}
|
||||
return t.querySelector("div");
|
||||
}
|
||||
function addVideoList(name, stream, peer, infinitedMute)
|
||||
function addVideoList(name, stream, peer, infinitedMute, name)
|
||||
{
|
||||
if(!videoContainer.querySelector(`[name="${name}"]`))
|
||||
{
|
||||
let video = templateVideo(name, stream, infinitedMute);
|
||||
let video = templateVideo(name, stream, infinitedMute, name);
|
||||
video.dataset.user = peer.socketId;
|
||||
videoContainer.appendChild(video);
|
||||
}
|
||||
|
@ -111,10 +123,6 @@ function removeVideoList(name)
|
|||
if(videoContainer.querySelector(`[data-user="${name}"]`))
|
||||
{
|
||||
let k = videoContainer.querySelector(`[data-user="${name}"]`);
|
||||
if(k.dataset.user == activeVideo?.dataset.user || !activeVideo)
|
||||
{
|
||||
activePeer = null;
|
||||
}
|
||||
k.remove();
|
||||
}
|
||||
}
|
||||
|
@ -124,8 +132,8 @@ async function beginEngine()
|
|||
let me = mwse.peer("me");
|
||||
me.disablePairAuth();
|
||||
mySocketId = me.socketId;
|
||||
|
||||
let url = new URL(window.location);
|
||||
myIPAddress = await mwse.virtualPressure.allocAPIPAddress();
|
||||
myNumber = await mwse.virtualPressure.allocAPNumber();
|
||||
roomid = url.searchParams.get("room");
|
||||
|
||||
if(!!roomid == 0)
|
||||
|
@ -178,7 +186,8 @@ async function startOutgoingWebcam()
|
|||
{ width: { exact: 240 } }
|
||||
],
|
||||
facingMode: "user"
|
||||
}
|
||||
},
|
||||
audio: true
|
||||
});
|
||||
outgoingStream = mediaStream;
|
||||
}
|
||||
|
@ -199,47 +208,62 @@ async function connectRoom()
|
|||
notifyActionInvite: false,
|
||||
notifyActionJoined: true
|
||||
});
|
||||
|
||||
await mwse.peer('me').info.set("name", peername);
|
||||
|
||||
await room.createRoom();
|
||||
|
||||
room.on("join", peer => IncomingPeer(peer,true));
|
||||
room.on("join", peer => IncomingPeer(peer, true));
|
||||
room.on("eject", peer => OutgoingPeer(peer));
|
||||
|
||||
for (const peer of await room.fetchPeers()) {
|
||||
if(peer.socketId != mwse.peer('me').socketId){
|
||||
IncomingPeer(peer,false)
|
||||
}
|
||||
IncomingPeer(peer)
|
||||
}
|
||||
|
||||
addVideoList("My Webcam",outgoingStream, mwse.peer("me"), true)
|
||||
addVideoList("My Webcam",outgoingStream, mwse.peer("me"), true, peername);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {import("./MWSE/Peer").default} peer
|
||||
*/
|
||||
function IncomingPeer(peer,activeConnect)
|
||||
async function IncomingPeer(peer,activeConnect)
|
||||
{
|
||||
await peer.info.fetch();
|
||||
|
||||
peer.createRTC({
|
||||
iceCandidatePoolSize: 0
|
||||
},[{
|
||||
urls: "turn:20.166.82.187:3478",
|
||||
username: "turnserver",
|
||||
credential: "turnserver"
|
||||
},{
|
||||
urls: "stun:stun.l.google.com:19302"
|
||||
}]);
|
||||
|
||||
if(activeConnect)
|
||||
{
|
||||
peer.rtc.connect();
|
||||
}
|
||||
peer.rtc.rtc.turboBitrate = 0;
|
||||
peer.rtc.on('connected',() => {
|
||||
console.log("Connected");
|
||||
if(!activeConnect)
|
||||
{
|
||||
peer.rtc.sendStream(outgoingStream, "Webcam", {});
|
||||
activePeers[peer.socketId] = peer.rtc.rtc;
|
||||
}
|
||||
});
|
||||
peer.rtc.on('disconnected',() => {
|
||||
console.log("Disconnected");
|
||||
removeVideoList(peer.streamY, peer);
|
||||
removeVideoList(peer.socketId, peer);
|
||||
delete activePeers[peer.socketId];
|
||||
});
|
||||
peer.rtc.on("stream:added", ({stream,name}) => {
|
||||
peer.streamY = peer.socketId + " | " + name + " - " + stream.id;
|
||||
addVideoList(peer.socketId + " | " + name + " - " + stream.id,stream, peer);
|
||||
addVideoList(
|
||||
peer.socketId,
|
||||
stream,
|
||||
peer,
|
||||
void 0,
|
||||
peer.info.get("name")
|
||||
);
|
||||
if(activeConnect)
|
||||
{
|
||||
peer.rtc.sendStream(outgoingStream, "Webcam", {});
|
||||
|
@ -252,12 +276,11 @@ function IncomingPeer(peer,activeConnect)
|
|||
function OutgoingPeer(peer)
|
||||
{
|
||||
removeVideoList(peer.socketId, peer);
|
||||
delete activePeers[peer.socketId];
|
||||
}
|
||||
|
||||
let relative;
|
||||
|
||||
|
||||
|
||||
setInterval(() => {
|
||||
for(const [,peerRtc] of Object.entries(activePeers))
|
||||
{
|
||||
|
@ -275,4 +298,51 @@ setInterval(() => {
|
|||
}
|
||||
}
|
||||
}
|
||||
},1000);
|
||||
},1000);
|
||||
|
||||
function bindAudioLevel(stream, element, options = {}) {
|
||||
const {
|
||||
minPercent = 5,
|
||||
maxPercent = 100,
|
||||
decayRate = 0.97, // 0.9–0.99 arasında önerilir
|
||||
volumeScale = 2.0 // gelen rms değerini büyütmek için (normalize daha geniş aralık)
|
||||
} = options;
|
||||
|
||||
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
||||
const source = audioCtx.createMediaStreamSource(stream);
|
||||
const analyser = audioCtx.createAnalyser();
|
||||
|
||||
analyser.fftSize = 512;
|
||||
analyser.smoothingTimeConstant = 0.1;
|
||||
|
||||
const dataArray = new Uint8Array(analyser.frequencyBinCount);
|
||||
source.connect(analyser);
|
||||
|
||||
const track = stream.getAudioTracks()[0];
|
||||
const bufferLength = analyser.frequencyBinCount;
|
||||
|
||||
function update()
|
||||
{
|
||||
if (track.readyState === 'ended' || !track.enabled) {
|
||||
source.disconnect();
|
||||
analyser.disconnect();
|
||||
audioCtx.close();
|
||||
return;
|
||||
}
|
||||
analyser.getByteFrequencyData(dataArray);
|
||||
|
||||
// Ortalama ses seviyesi hesapla
|
||||
let sum = 0;
|
||||
for (let i = 0; i < bufferLength; i++) {
|
||||
sum += dataArray[i];
|
||||
}
|
||||
const avg = sum / bufferLength;
|
||||
|
||||
// Ortalama değeri % olarak hesapla (0-255 arası değer)
|
||||
const volumePercent = Math.min(100, (avg / 255) * 100);
|
||||
element.style.width = `${volumePercent * 2}%`;
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue