déconnexion du canal vocal
This commit is contained in:
parent
e6a755b1d6
commit
04e745874e
@ -156,22 +156,36 @@ if ($action === "poll") {
|
|||||||
} catch (Exception $e) {}
|
} catch (Exception $e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read signals
|
// Read signals from DB
|
||||||
$log_file = room_log_file($room);
|
|
||||||
$signals = [];
|
$signals = [];
|
||||||
if (file_exists($log_file)) {
|
try {
|
||||||
$lines = file($log_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
$stmt = db()->prepare("SELECT id, from_peer_id as `from`, data FROM voice_signals WHERE to_peer_id = ? ORDER BY id ASC");
|
||||||
$remaining = [];
|
$stmt->execute([$my_id]);
|
||||||
$now = now_ms();
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
foreach ($lines as $line) {
|
|
||||||
$sig = json_decode($line, true);
|
if (!empty($rows)) {
|
||||||
if ($sig && isset($sig["to"]) && $sig["to"] === $my_id) {
|
$ids = [];
|
||||||
$signals[] = $sig;
|
foreach ($rows as $r) {
|
||||||
} elseif ($sig && ($now - ($sig["time"] ?? 0) < 30000)) {
|
$signals[] = [
|
||||||
$remaining[] = $line;
|
"from" => $r["from"],
|
||||||
|
"data" => json_decode($r["data"], true)
|
||||||
|
];
|
||||||
|
$ids[] = $r["id"];
|
||||||
}
|
}
|
||||||
|
// Delete signals we just read
|
||||||
|
$placeholders = implode(',', array_fill(0, count($ids), '?'));
|
||||||
|
$stmt_del = db()->prepare("DELETE FROM voice_signals WHERE id IN ($placeholders)");
|
||||||
|
$stmt_del->execute($ids);
|
||||||
}
|
}
|
||||||
file_put_contents($log_file, implode("\n", $remaining) . (empty($remaining) ? "" : "\n"), LOCK_EX);
|
|
||||||
|
// Periodic cleanup of old signals (> 1 minute)
|
||||||
|
if (rand(1, 20) === 1) {
|
||||||
|
$old_time = now_ms() - 60000;
|
||||||
|
$stmt_clean = db()->prepare("DELETE FROM voice_signals WHERE created_at_ms < ?");
|
||||||
|
$stmt_clean->execute([$old_time]);
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
error_log("Signal poll error: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
json_out(["success" => true, "participants" => $ps, "signals" => $signals]);
|
json_out(["success" => true, "participants" => $ps, "signals" => $signals]);
|
||||||
@ -183,15 +197,13 @@ if ($action === "signal") {
|
|||||||
$data = $_REQUEST["data"] ?? "";
|
$data = $_REQUEST["data"] ?? "";
|
||||||
if (!$to || !$data) json_out(["error" => "Missing to/data"], 400);
|
if (!$to || !$data) json_out(["error" => "Missing to/data"], 400);
|
||||||
|
|
||||||
$sig = [
|
try {
|
||||||
"from" => $my_id,
|
$stmt = db()->prepare("INSERT INTO voice_signals (room_id, from_peer_id, to_peer_id, data, created_at_ms) VALUES (?, ?, ?, ?, ?)");
|
||||||
"to" => $to,
|
$stmt->execute([$room, $my_id, $to, $data, now_ms()]);
|
||||||
"data" => json_decode($data, true),
|
json_out(["success" => true]);
|
||||||
"time" => now_ms()
|
} catch (Exception $e) {
|
||||||
];
|
json_out(["error" => "Signal send failed: " . $e->getMessage()], 500);
|
||||||
|
}
|
||||||
file_put_contents(room_log_file($room), json_encode($sig) . "\n", FILE_APPEND | LOCK_EX);
|
|
||||||
json_out(["success" => true]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($action === "list_all") {
|
if ($action === "list_all") {
|
||||||
|
|||||||
@ -216,18 +216,31 @@ class VoiceChannel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pc.ontrack = (event) => {
|
pc.ontrack = (event) => {
|
||||||
console.log('Received remote track from:', userId, event);
|
console.log('Received remote track from:', userId, 'Stream count:', event.streams.length);
|
||||||
|
const stream = event.streams[0] || new MediaStream([event.track]);
|
||||||
|
|
||||||
if (this.remoteAudios[userId]) {
|
if (this.remoteAudios[userId]) {
|
||||||
|
console.log('Replacing existing audio element for:', userId);
|
||||||
this.remoteAudios[userId].pause();
|
this.remoteAudios[userId].pause();
|
||||||
this.remoteAudios[userId].remove();
|
|
||||||
this.remoteAudios[userId].srcObject = null;
|
this.remoteAudios[userId].srcObject = null;
|
||||||
|
this.remoteAudios[userId].remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
const remoteAudio = new Audio();
|
const remoteAudio = new Audio();
|
||||||
|
remoteAudio.autoplay = true;
|
||||||
remoteAudio.style.display = 'none';
|
remoteAudio.style.display = 'none';
|
||||||
remoteAudio.srcObject = event.streams[0];
|
remoteAudio.srcObject = stream;
|
||||||
document.body.appendChild(remoteAudio);
|
document.body.appendChild(remoteAudio);
|
||||||
this.remoteAudios[userId] = remoteAudio;
|
this.remoteAudios[userId] = remoteAudio;
|
||||||
remoteAudio.play().catch(e => console.warn('Autoplay prevented:', e));
|
|
||||||
|
console.log('Playing remote audio for:', userId);
|
||||||
|
remoteAudio.play().then(() => {
|
||||||
|
console.log('Remote audio playing successfully for:', userId);
|
||||||
|
}).catch(e => {
|
||||||
|
console.warn('Autoplay prevented or play failed for:', userId, e);
|
||||||
|
// In case of autoplay prevention, we might need a user gesture,
|
||||||
|
// but they just clicked a channel so it should be fine.
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isOfferor) {
|
if (isOfferor) {
|
||||||
@ -454,6 +467,10 @@ class VoiceChannel {
|
|||||||
this.currentChannelId = null;
|
this.currentChannelId = null;
|
||||||
this.myPeerId = null;
|
this.myPeerId = null;
|
||||||
this.speakingUsers.clear();
|
this.speakingUsers.clear();
|
||||||
|
|
||||||
|
// Also remove 'active' class from all voice items
|
||||||
|
document.querySelectorAll('.voice-item').forEach(el => el.classList.remove('active'));
|
||||||
|
|
||||||
this.updateVoiceUI();
|
this.updateVoiceUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,8 +538,10 @@ class VoiceChannel {
|
|||||||
Object.keys(data.channels).forEach(channelId => {
|
Object.keys(data.channels).forEach(channelId => {
|
||||||
const voiceItem = document.querySelector(`.voice-item[data-channel-id="${channelId}"]`);
|
const voiceItem = document.querySelector(`.voice-item[data-channel-id="${channelId}"]`);
|
||||||
if (voiceItem) {
|
if (voiceItem) {
|
||||||
// Highlight channel as connected if anyone is in it
|
// Highlight channel as connected only if I am in it
|
||||||
|
if (window.voiceHandler && window.voiceHandler.currentChannelId == channelId) {
|
||||||
voiceItem.classList.add('connected');
|
voiceItem.classList.add('connected');
|
||||||
|
}
|
||||||
|
|
||||||
const container = voiceItem.closest('.channel-item-container');
|
const container = voiceItem.closest('.channel-item-container');
|
||||||
if (container) {
|
if (container) {
|
||||||
|
|||||||
BIN
assets/pasted-20260218-191112-132e95c8.png
Normal file
BIN
assets/pasted-20260218-191112-132e95c8.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
@ -1 +1 @@
|
|||||||
{"3356a3073b77f72d":{"id":"3356a3073b77f72d","user_id":3,"name":"swefheim","avatar_url":"","last_seen":1771441757997},"d58aa0268cc9e8d0":{"id":"d58aa0268cc9e8d0","user_id":2,"name":"swefpifh ᵇʰᶠʳ","avatar_url":"","last_seen":1771441758062}}
|
{"b9cd47d7dce5c259":{"id":"b9cd47d7dce5c259","user_id":3,"name":"swefheim","avatar_url":"","last_seen":1771442163346},"28ab267700c18621":{"id":"28ab267700c18621","user_id":2,"name":"swefpifh ᵇʰᶠʳ","avatar_url":"","last_seen":1771442163368}}
|
||||||
11
db/migrations/20260218_voice_signals.sql
Normal file
11
db/migrations/20260218_voice_signals.sql
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
-- Create voice_signals table for reliable signaling
|
||||||
|
CREATE TABLE IF NOT EXISTS voice_signals (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
room_id VARCHAR(50) NOT NULL,
|
||||||
|
from_peer_id VARCHAR(16) NOT NULL,
|
||||||
|
to_peer_id VARCHAR(16) NOT NULL,
|
||||||
|
data TEXT NOT NULL,
|
||||||
|
created_at_ms BIGINT NOT NULL,
|
||||||
|
INDEX (to_peer_id),
|
||||||
|
INDEX (created_at_ms)
|
||||||
|
);
|
||||||
@ -676,3 +676,11 @@
|
|||||||
2026-02-18 19:06:59 - GET /index.php - POST: []
|
2026-02-18 19:06:59 - GET /index.php - POST: []
|
||||||
2026-02-18 19:07:22 - GET /index.php - POST: []
|
2026-02-18 19:07:22 - GET /index.php - POST: []
|
||||||
2026-02-18 19:08:00 - GET /index.php?server_id=1&channel_id=6 - POST: []
|
2026-02-18 19:08:00 - GET /index.php?server_id=1&channel_id=6 - POST: []
|
||||||
|
2026-02-18 19:11:46 - GET /index.php - POST: []
|
||||||
|
2026-02-18 19:13:10 - GET /?fl_project=38443 - POST: []
|
||||||
|
2026-02-18 19:14:15 - GET /index.php - POST: []
|
||||||
|
2026-02-18 19:14:22 - GET /index.php - POST: []
|
||||||
|
2026-02-18 19:14:31 - GET /index.php - POST: []
|
||||||
|
2026-02-18 19:15:26 - GET /index.php - POST: []
|
||||||
|
2026-02-18 19:15:30 - GET /index.php - POST: []
|
||||||
|
2026-02-18 19:15:31 - GET /index.php - POST: []
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user