Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spectate Remote Control v1 #426

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open

Conversation

jmlee337
Copy link
Contributor

@jmlee337 jmlee337 commented Mar 12, 2024

Implement Spectate Remote Control v1 per the design doc

Possible Changes

Please let me know if you'd like me to

  • move spectate.worker.ts and spectate_manager.ts from broadcast/ to common/ or something like that
  • move the UI control panel to somewhere a bit less discoverable for non-advanced users

Screenshots

Screenshot 2024-03-12 145935
Screenshot 2024-03-12 145944

Spectate Remote Control server: WebSocket API

(accepts only 1 connection at a time)

spectate-protocol

> let socket = new WebSocket("ws://localhost:55761", "spectate-protocol");
> socket.onopen = () => { console.log("open") };
> socket.onmessage = (event) => { console.log("message: " + event.data) };
> socket.onerror = (event) => { console.log("error: " + JSON.stringify(event)) };
> socket.onclose = () => { console.log("close") };

open

spectating-broadcasts-event

(sent once only when a client connects)

message: {"op":"spectating-broadcasts-event","spectatingBroadcasts":[{"broadcastId":"q0ejrrUneJcA5v65nUVX13OYr0o2-oFTsLA8jxfP9GqqVt7kxYk","dolphinId":"1713518126142broadcast0"}]}

new-file-event

message: {"op":"new-file-event","dolphinId":"spectate-q0ejrrUneJcA5v65nUVX13OYr0o2-cYp8HZJ9FB3P3uW72b2dHM","filePath":"C:\\Users\\jmlee337\\Documents\\Slippi\\Spectate\\Game_20240309T104448.slp"}

game-end-event

message: {"op":"game-end-event","dolphinId":"spectate-q0ejrrUneJcA5v65nUVX13OYr0o2-cYp8HZJ9FB3P3uW72b2dHM"}

dolphin-closed-event

message: {"op":"dolphin-closed-event","dolphinId":"spectate-q0ejrrUneJcA5v65nUVX13OYr0o2-cYp8HZJ9FB3P3uW72b2dHM"}

list-broadcasts-request

> socket.send(JSON.stringify({op: "list-broadcasts-request"}))

message: {"op":"list-broadcasts-response","broadcasts":[{"id":"q0ejrrUneJcA5v65nUVX13OYr0o2-cYp8HZJ9FB3P3uW72b2dHM","name":"LOST#882","broadcaster":{"uid":"q0ejrrUneJcA5v65nUVX13OYr0o2","name":"lostletters"}}]}

spectate-broadcast-request

if dolphinId is not specified, spectating will begin in a new dolphin window

> socket.send(JSON.stringify({op: "spectate-broadcast-request", broadcastId: "PMmdJgqjWzWrMHmq2IbktBKpbcf2-4zXtnoxyBgA2jRwH6wYbtb"}));

message: {"op":"spectate-broadcast-response","dolphinId":"1710210546025remote0","path":"C:\\Users\\jmlee337\\Documents\\Slippi\\Spectate"}
message: {"op":"new-file-event","dolphinId":"1710210546025remote0","filePath":"C:\\Users\\jmlee337\\Documents\\Slippi\\Spectate\\Game_20240309T104448.slp"}

if dolphinId is specified, spectating will begin in the existing dolphin window with that id (if one exists), or a new dolphin window (if none exists)

> socket.send(JSON.stringify({op: "spectate-broadcast-request", broadcastId: "PMmdJgqjWzWrMHmq2IbktBKpbcf2-4zXtnoxyBgA2jRwH6wYbtb", dolphinId: "dolphin-id"}));

message: {"op":"spectate-broadcast-response","dolphinId":"dolphin-id","path":"C:\\Users\\jmlee337\\Documents\\Slippi\\Spectate"}
message: {"op":"new-file-event","dolphinId":"dolphin-id","filePath":"C:\\Users\\jmlee337\\Documents\\Slippi\\Spectate\\Game_20240312T130151.slp"}

> socket.send(JSON.stringify({op: "spectate-broadcast-request", broadcastId: "q0ejrrUneJcA5v65nUVX13OYr0o2-pb3C5YdjLzCP4sZHhCAbyg", dolphinId: "dolphin-id"}));

message: {"op":"spectate-broadcast-response","dolphinId":"dolphin-id","path":"C:\\Users\\jmlee337\\Documents\\Slippi\\Spectate"}
message: {"op":"new-file-event","dolphinId":"dolphin-id","filePath":"C:\\Users\\jmlee337\\Documents\\Slippi\\Spectate\\Game_20240312T130208.slp"}

err

Request errors are denoted by the presence of an err field in the response

> socket.send(JSON.stringify({op: "close-dolphin-request", dolphinId: "nonexistent-dolphin-id"}));
message: {"op":"close-dolphin-response","err":"no such playback dolphin instance"}

jmlee337 and others added 19 commits April 16, 2024 22:54
tested core functionality (list broadcasts, spectate broadcasts)

reconnect not yet tested
UI not quite there
quite a bit of v1 functionality still missing
- add dolphinId in spectate-broadcast-response
- add dolphin-closed-event
- add new-file-event

(also tested 1hr reconnect on previous commit)
…han every 1s

current Ishii sys/stat behavior only has second precision for file mod time, so comms file modifications won't be picked up if they happen in the same epoch second
`broadcasterName` is propagated to the dolphin window title so keep it the same for OBS purposes
different libraries may treat `localhost` differently on different operating systems in regards to IPv4 vs IPv6. On my machine, this ends up with the WebSocket server bound to IPv4 while a client I'm writing attempts and fails to connect via IPv6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants