diff --git a/desktop-client/main.py b/desktop-client/main.py
index 9aa53f8..c9098bb 100644
--- a/desktop-client/main.py
+++ b/desktop-client/main.py
@@ -593,11 +593,92 @@ class VlcSyncApp(QMainWindow):
def fmt(s): return f"{int(s)//3600:02d}:{(int(s)%3600)//60:02d}:{int(s)%60:02d}"
self.on_system_message(f"{username} seeked to {fmt(position_s)}")
+ def _handle_seek_command(self, arg: str) -> bool:
+ current_ms = self.vlc_player.current_time_ms
+ length_ms = self.vlc_player.get_length()
+ if length_ms <= 0:
+ return False
+
+ try:
+ target_ms = 0
+ if arg.startswith('+') or arg.startswith('-'):
+ # relative
+ modifier = 1 if arg.startswith('+') else -1
+ num_str = arg[1:]
+
+ if num_str.endswith('s'):
+ val = float(num_str[:-1]) * 1000
+ elif num_str.endswith('m'):
+ val = float(num_str[:-1]) * 60 * 1000
+ elif num_str.endswith('h'):
+ val = float(num_str[:-1]) * 3600 * 1000
+ else:
+ val = float(num_str) * 1000 # Default to seconds
+
+ target_ms = current_ms + (val * modifier)
+ elif ":" in arg:
+ # absolute time like HH:MM:SS or MM:SS
+ parts = arg.split(":")
+ parts.reverse() # seconds, minutes, hours
+ if len(parts) > 0: target_ms += float(parts[0]) * 1000
+ if len(parts) > 1: target_ms += float(parts[1]) * 60 * 1000
+ if len(parts) > 2: target_ms += float(parts[2]) * 3600 * 1000
+ else:
+ # absolute seconds or something with a suffix but no + or -
+ if arg.endswith('s'):
+ target_ms = float(arg[:-1]) * 1000
+ elif arg.endswith('m'):
+ target_ms = float(arg[:-1]) * 60 * 1000
+ elif arg.endswith('h'):
+ target_ms = float(arg[:-1]) * 3600 * 1000
+ else:
+ target_ms = float(arg) * 1000
+
+ target_ms = max(0, min(target_ms, length_ms))
+ self.vlc_player.seek(int(target_ms))
+ self.sync_client.send_message({"type": "sync", "action": "seek", "position": target_ms / 1000.0})
+ return True
+ except ValueError:
+ return False
+
def send_chat(self):
text = self.chat_input.text().strip()
- if text:
- self.sync_client.send_message({"type": "chat", "message": text})
- self.chat_input.setText("")
+ if not text:
+ return
+
+ if text.startswith("/"):
+ parts = text.split()
+ cmd = parts[0].lower()
+
+ if cmd == "/play":
+ self.chat_input.setText("")
+ if not self.vlc_player.is_playing:
+ self.toggle_playback()
+ self.on_system_message(text)
+ return
+ elif cmd == "/pause":
+ self.chat_input.setText("")
+ if self.vlc_player.is_playing:
+ self.toggle_playback()
+ self.on_system_message(text)
+ return
+ elif cmd == "/seek":
+ self.chat_input.setText("")
+ if len(parts) > 1:
+ if self._handle_seek_command(parts[1]):
+ self.on_system_message(text)
+ else:
+ self.on_system_message("Invalid time format. Use: 1:23, +30s, -1m")
+ else:
+ self.on_system_message("Usage: /seek [time]")
+ return
+ elif cmd == "/help":
+ self.chat_input.setText("")
+ self.on_system_message("Available commands:
/play - Resume playback
/pause - Pause playback
/seek [time] - Seek to specific time (e.g., 1:23) or offset (e.g., +30s, -1m)
/help - Show this message")
+ return
+
+ self.sync_client.send_message({"type": "chat", "message": text})
+ self.chat_input.setText("")
def apply_stylesheet(self):
self.setStyleSheet("""
diff --git a/desktop-client/test_integration.py b/desktop-client/test_integration.py
index 933cabe..b3c6339 100644
--- a/desktop-client/test_integration.py
+++ b/desktop-client/test_integration.py
@@ -4,7 +4,7 @@ import websockets
import sys
async def run_integration_test():
- url = "ws://localhost:3000/ws"
+ url = "wss://video-sync.peterstockings.com/ws"
print("🤖 Test: Starting Integration Test Suite...")