déconnexion du canal vocal

This commit is contained in:
Flatlogic Bot 2026-02-18 19:16:04 +00:00
parent e6a755b1d6
commit 04e745874e
6 changed files with 78 additions and 28 deletions

View File

@ -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") {

View File

@ -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) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -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}}

View 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)
);

View File

@ -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: []