déconnexion du canal vocal
This commit is contained in:
parent
e6a755b1d6
commit
04e745874e
@ -156,22 +156,36 @@ if ($action === "poll") {
|
||||
} catch (Exception $e) {}
|
||||
}
|
||||
|
||||
// Read signals
|
||||
$log_file = room_log_file($room);
|
||||
// Read signals from DB
|
||||
$signals = [];
|
||||
if (file_exists($log_file)) {
|
||||
$lines = file($log_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
$remaining = [];
|
||||
$now = now_ms();
|
||||
foreach ($lines as $line) {
|
||||
$sig = json_decode($line, true);
|
||||
if ($sig && isset($sig["to"]) && $sig["to"] === $my_id) {
|
||||
$signals[] = $sig;
|
||||
} elseif ($sig && ($now - ($sig["time"] ?? 0) < 30000)) {
|
||||
$remaining[] = $line;
|
||||
try {
|
||||
$stmt = db()->prepare("SELECT id, from_peer_id as `from`, data FROM voice_signals WHERE to_peer_id = ? ORDER BY id ASC");
|
||||
$stmt->execute([$my_id]);
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!empty($rows)) {
|
||||
$ids = [];
|
||||
foreach ($rows as $r) {
|
||||
$signals[] = [
|
||||
"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]);
|
||||
@ -183,15 +197,13 @@ if ($action === "signal") {
|
||||
$data = $_REQUEST["data"] ?? "";
|
||||
if (!$to || !$data) json_out(["error" => "Missing to/data"], 400);
|
||||
|
||||
$sig = [
|
||||
"from" => $my_id,
|
||||
"to" => $to,
|
||||
"data" => json_decode($data, true),
|
||||
"time" => now_ms()
|
||||
];
|
||||
|
||||
file_put_contents(room_log_file($room), json_encode($sig) . "\n", FILE_APPEND | LOCK_EX);
|
||||
json_out(["success" => true]);
|
||||
try {
|
||||
$stmt = db()->prepare("INSERT INTO voice_signals (room_id, from_peer_id, to_peer_id, data, created_at_ms) VALUES (?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$room, $my_id, $to, $data, now_ms()]);
|
||||
json_out(["success" => true]);
|
||||
} catch (Exception $e) {
|
||||
json_out(["error" => "Signal send failed: " . $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
if ($action === "list_all") {
|
||||
|
||||
@ -216,18 +216,31 @@ class VoiceChannel {
|
||||
};
|
||||
|
||||
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]) {
|
||||
console.log('Replacing existing audio element for:', userId);
|
||||
this.remoteAudios[userId].pause();
|
||||
this.remoteAudios[userId].remove();
|
||||
this.remoteAudios[userId].srcObject = null;
|
||||
this.remoteAudios[userId].remove();
|
||||
}
|
||||
|
||||
const remoteAudio = new Audio();
|
||||
remoteAudio.autoplay = true;
|
||||
remoteAudio.style.display = 'none';
|
||||
remoteAudio.srcObject = event.streams[0];
|
||||
remoteAudio.srcObject = stream;
|
||||
document.body.appendChild(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) {
|
||||
@ -454,6 +467,10 @@ class VoiceChannel {
|
||||
this.currentChannelId = null;
|
||||
this.myPeerId = null;
|
||||
this.speakingUsers.clear();
|
||||
|
||||
// Also remove 'active' class from all voice items
|
||||
document.querySelectorAll('.voice-item').forEach(el => el.classList.remove('active'));
|
||||
|
||||
this.updateVoiceUI();
|
||||
}
|
||||
|
||||
@ -521,8 +538,10 @@ class VoiceChannel {
|
||||
Object.keys(data.channels).forEach(channelId => {
|
||||
const voiceItem = document.querySelector(`.voice-item[data-channel-id="${channelId}"]`);
|
||||
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');
|
||||
}
|
||||
|
||||
const container = voiceItem.closest('.channel-item-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: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: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