Compare commits
No commits in common. "stable" and "perfectnogation" have entirely different histories.
stable
...
perfectnog
|
@ -5,7 +5,6 @@ html,body{
|
||||||
body{
|
body{
|
||||||
background-color: #141414;
|
background-color: #141414;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-family: system-ui;
|
|
||||||
}
|
}
|
||||||
*{
|
*{
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -74,7 +73,6 @@ video{
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
|
||||||
}
|
}
|
||||||
.tool-container > .tools{
|
.tool-container > .tools{
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
@ -100,43 +98,3 @@ video{
|
||||||
line-height: 2;
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
158
public/index.js
158
public/index.js
|
@ -1,4 +1,3 @@
|
||||||
const url = new URL(window.location);
|
|
||||||
/**
|
/**
|
||||||
* @type {import("./MWSE/index").default}
|
* @type {import("./MWSE/index").default}
|
||||||
*/
|
*/
|
||||||
|
@ -7,14 +6,6 @@ let mwse;
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
let mySocketId;
|
let mySocketId;
|
||||||
/**
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
let myIPAddress;
|
|
||||||
/**
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
let myNumber;
|
|
||||||
/**
|
/**
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
|
@ -43,10 +34,18 @@ function connect()
|
||||||
endpoint: "wss://ws.saqut.com"
|
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);
|
mwse.scope(beginEngine);
|
||||||
}
|
}
|
||||||
|
|
||||||
let peername = url.searchParams.get("user");
|
|
||||||
|
|
||||||
let interact = false;
|
let interact = false;
|
||||||
|
|
||||||
|
@ -65,31 +64,23 @@ document.addEventListener("click",()=>{
|
||||||
*/
|
*/
|
||||||
let activeVideo;
|
let activeVideo;
|
||||||
|
|
||||||
function templateVideo(name, stream,infinitedMute, peername)
|
function templateVideo(name, stream,infinitedMute)
|
||||||
{
|
{
|
||||||
let t = new DOMParser().parseFromString(`
|
let t = new DOMParser().parseFromString(`
|
||||||
<div class="frame" data-name="${name}">
|
<div class="frame">
|
||||||
<video autoplay playsinline muted>
|
<video autoplay playsinline muted data-name="${name}">
|
||||||
|
|
||||||
</video>
|
</video>
|
||||||
<div class="tool-container">
|
<!--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 class="tools">
|
<div class="tools">
|
||||||
|
<button>
|
||||||
|
<i class="material-icons">home</i>
|
||||||
|
</button>
|
||||||
|
<button>
|
||||||
|
<i class="material-icons">close</i>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="progress">
|
</div--->
|
||||||
<div class="progress-box">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
`,"text/html");
|
`,"text/html");
|
||||||
|
|
||||||
|
@ -102,17 +93,14 @@ function templateVideo(name, stream,infinitedMute, peername)
|
||||||
i.muted = 1;
|
i.muted = 1;
|
||||||
i.classList.add("soundon");
|
i.classList.add("soundon");
|
||||||
}
|
}
|
||||||
if(stream){
|
if(stream) i.srcObject = stream;
|
||||||
i.srcObject = stream;
|
|
||||||
bindAudioLevel(stream, t.querySelector(".progress-box"));
|
|
||||||
}
|
|
||||||
return t.querySelector("div");
|
return t.querySelector("div");
|
||||||
}
|
}
|
||||||
function addVideoList(name, stream, peer, infinitedMute, name)
|
function addVideoList(name, stream, peer, infinitedMute)
|
||||||
{
|
{
|
||||||
if(!videoContainer.querySelector(`[name="${name}"]`))
|
if(!videoContainer.querySelector(`[name="${name}"]`))
|
||||||
{
|
{
|
||||||
let video = templateVideo(name, stream, infinitedMute, name);
|
let video = templateVideo(name, stream, infinitedMute);
|
||||||
video.dataset.user = peer.socketId;
|
video.dataset.user = peer.socketId;
|
||||||
videoContainer.appendChild(video);
|
videoContainer.appendChild(video);
|
||||||
}
|
}
|
||||||
|
@ -123,6 +111,10 @@ function removeVideoList(name)
|
||||||
if(videoContainer.querySelector(`[data-user="${name}"]`))
|
if(videoContainer.querySelector(`[data-user="${name}"]`))
|
||||||
{
|
{
|
||||||
let k = videoContainer.querySelector(`[data-user="${name}"]`);
|
let k = videoContainer.querySelector(`[data-user="${name}"]`);
|
||||||
|
if(k.dataset.user == activeVideo?.dataset.user || !activeVideo)
|
||||||
|
{
|
||||||
|
activePeer = null;
|
||||||
|
}
|
||||||
k.remove();
|
k.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,8 +124,8 @@ async function beginEngine()
|
||||||
let me = mwse.peer("me");
|
let me = mwse.peer("me");
|
||||||
me.disablePairAuth();
|
me.disablePairAuth();
|
||||||
mySocketId = me.socketId;
|
mySocketId = me.socketId;
|
||||||
myIPAddress = await mwse.virtualPressure.allocAPIPAddress();
|
|
||||||
myNumber = await mwse.virtualPressure.allocAPNumber();
|
let url = new URL(window.location);
|
||||||
roomid = url.searchParams.get("room");
|
roomid = url.searchParams.get("room");
|
||||||
|
|
||||||
if(!!roomid == 0)
|
if(!!roomid == 0)
|
||||||
|
@ -186,8 +178,7 @@ async function startOutgoingWebcam()
|
||||||
{ width: { exact: 240 } }
|
{ width: { exact: 240 } }
|
||||||
],
|
],
|
||||||
facingMode: "user"
|
facingMode: "user"
|
||||||
},
|
}
|
||||||
audio: true
|
|
||||||
});
|
});
|
||||||
outgoingStream = mediaStream;
|
outgoingStream = mediaStream;
|
||||||
}
|
}
|
||||||
|
@ -208,62 +199,47 @@ async function connectRoom()
|
||||||
notifyActionInvite: false,
|
notifyActionInvite: false,
|
||||||
notifyActionJoined: true
|
notifyActionJoined: true
|
||||||
});
|
});
|
||||||
|
|
||||||
await mwse.peer('me').info.set("name", peername);
|
|
||||||
|
|
||||||
await room.createRoom();
|
await room.createRoom();
|
||||||
|
|
||||||
room.on("join", peer => IncomingPeer(peer, true));
|
room.on("join", peer => IncomingPeer(peer,true));
|
||||||
room.on("eject", peer => OutgoingPeer(peer));
|
room.on("eject", peer => OutgoingPeer(peer));
|
||||||
|
|
||||||
for (const peer of await room.fetchPeers()) {
|
for (const peer of await room.fetchPeers()) {
|
||||||
IncomingPeer(peer)
|
if(peer.socketId != mwse.peer('me').socketId){
|
||||||
|
IncomingPeer(peer,false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addVideoList("My Webcam",outgoingStream, mwse.peer("me"), true, peername);
|
addVideoList("My Webcam",outgoingStream, mwse.peer("me"), true)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("./MWSE/Peer").default} peer
|
* @param {import("./MWSE/Peer").default} peer
|
||||||
*/
|
*/
|
||||||
async function IncomingPeer(peer,activeConnect)
|
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)
|
if(activeConnect)
|
||||||
{
|
{
|
||||||
peer.rtc.connect();
|
peer.rtc.connect();
|
||||||
}
|
}
|
||||||
peer.rtc.rtc.turboBitrate = 0;
|
peer.rtc.rtc.turboBitrate = 0;
|
||||||
peer.rtc.on('connected',() => {
|
peer.rtc.on('connected',() => {
|
||||||
|
console.log("Connected");
|
||||||
if(!activeConnect)
|
if(!activeConnect)
|
||||||
{
|
{
|
||||||
peer.rtc.sendStream(outgoingStream, "Webcam", {});
|
peer.rtc.sendStream(outgoingStream, "Webcam", {});
|
||||||
|
activePeers[peer.socketId] = peer.rtc.rtc;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
peer.rtc.on('disconnected',() => {
|
peer.rtc.on('disconnected',() => {
|
||||||
removeVideoList(peer.socketId, peer);
|
console.log("Disconnected");
|
||||||
|
removeVideoList(peer.streamY, peer);
|
||||||
delete activePeers[peer.socketId];
|
delete activePeers[peer.socketId];
|
||||||
});
|
});
|
||||||
peer.rtc.on("stream:added", ({stream,name}) => {
|
peer.rtc.on("stream:added", ({stream,name}) => {
|
||||||
addVideoList(
|
peer.streamY = peer.socketId + " | " + name + " - " + stream.id;
|
||||||
peer.socketId,
|
addVideoList(peer.socketId + " | " + name + " - " + stream.id,stream, peer);
|
||||||
stream,
|
|
||||||
peer,
|
|
||||||
void 0,
|
|
||||||
peer.info.get("name")
|
|
||||||
);
|
|
||||||
if(activeConnect)
|
if(activeConnect)
|
||||||
{
|
{
|
||||||
peer.rtc.sendStream(outgoingStream, "Webcam", {});
|
peer.rtc.sendStream(outgoingStream, "Webcam", {});
|
||||||
|
@ -276,11 +252,12 @@ async function IncomingPeer(peer,activeConnect)
|
||||||
function OutgoingPeer(peer)
|
function OutgoingPeer(peer)
|
||||||
{
|
{
|
||||||
removeVideoList(peer.socketId, peer);
|
removeVideoList(peer.socketId, peer);
|
||||||
delete activePeers[peer.socketId];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let relative;
|
let relative;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
for(const [,peerRtc] of Object.entries(activePeers))
|
for(const [,peerRtc] of Object.entries(activePeers))
|
||||||
{
|
{
|
||||||
|
@ -299,50 +276,3 @@ 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