Add synchronized YouTube watching
This commit is contained in:
+41
-3
@@ -30,6 +30,7 @@
|
||||
|
||||
(defvar kkkmeet-server--process nil)
|
||||
(defvar kkkmeet-server--rooms (make-hash-table :test 'equal))
|
||||
(defvar kkkmeet-server--watch-states (make-hash-table :test 'equal))
|
||||
(defconst kkkmeet-server--default-room-id "main")
|
||||
|
||||
(defconst kkkmeet-server--mime-types
|
||||
@@ -146,7 +147,8 @@ When KEEP-OPEN is nil, close PROCESS after writing."
|
||||
(kkkmeet-server--broadcast
|
||||
room-id peer-id `((type . "peer-left") (peerId . ,peer-id)))
|
||||
(when (= (hash-table-count room) 0)
|
||||
(remhash room-id kkkmeet-server--rooms)))))))
|
||||
(remhash room-id kkkmeet-server--rooms)
|
||||
(remhash room-id kkkmeet-server--watch-states)))))))
|
||||
|
||||
(defun kkkmeet-server--parse-request (raw)
|
||||
"Parse RAW HTTP request into an alist."
|
||||
@@ -235,7 +237,9 @@ When KEEP-OPEN is nil, close PROCESS after writing."
|
||||
process `((type . "welcome")
|
||||
(peerId . ,peer-id)
|
||||
(name . ,safe-name)
|
||||
(peers . ,peers)))
|
||||
(peers . ,peers)
|
||||
(watchState . ,(or (gethash safe-room-id kkkmeet-server--watch-states)
|
||||
:null))))
|
||||
(kkkmeet-server--broadcast
|
||||
safe-room-id peer-id `((type . "peer-joined")
|
||||
(peerId . ,peer-id)
|
||||
@@ -260,6 +264,35 @@ When KEEP-OPEN is nil, close PROCESS after writing."
|
||||
(error
|
||||
(kkkmeet-server--send-json process 400 `((error . ,(error-message-string error)))))))
|
||||
|
||||
(defun kkkmeet-server--handle-watch (process room-id body)
|
||||
"Handle shared YouTube watch state BODY for ROOM-ID."
|
||||
(condition-case error
|
||||
(let* ((json-object-type 'alist)
|
||||
(payload (json-read-from-string body))
|
||||
(from (alist-get 'from payload))
|
||||
(type (alist-get 'type payload))
|
||||
(video-id (alist-get 'videoId payload))
|
||||
(safe-room-id (if (string-empty-p room-id)
|
||||
kkkmeet-server--default-room-id
|
||||
room-id)))
|
||||
(if (and from (equal type "watch-state") video-id)
|
||||
(let ((watch-state `((type . "watch-state")
|
||||
(from . ,from)
|
||||
(name . ,(kkkmeet-server--normalize-name
|
||||
(alist-get 'name payload)))
|
||||
(videoId . ,video-id)
|
||||
(position . ,(or (alist-get 'position payload) 0))
|
||||
(playing . ,(if (alist-get 'playing payload) t :false))
|
||||
(updatedAt . ,(or (alist-get 'updatedAt payload)
|
||||
(floor (* 1000 (float-time))))))))
|
||||
(puthash safe-room-id watch-state kkkmeet-server--watch-states)
|
||||
(kkkmeet-server--broadcast safe-room-id from watch-state)
|
||||
(kkkmeet-server--send-json process 202 '((ok . t))))
|
||||
(kkkmeet-server--send-json
|
||||
process 400 '((error . "Watch messages require from, type=watch-state, and videoId.")))))
|
||||
(error
|
||||
(kkkmeet-server--send-json process 400 `((error . ,(error-message-string error)))))))
|
||||
|
||||
(defun kkkmeet-server--handle-request (process request)
|
||||
"Route REQUEST for PROCESS."
|
||||
(let ((method (alist-get 'method request))
|
||||
@@ -275,6 +308,9 @@ When KEEP-OPEN is nil, close PROCESS after writing."
|
||||
((and (equal method "POST") (string-prefix-p "/signal/" path))
|
||||
(kkkmeet-server--handle-signal
|
||||
process (url-unhex-string (string-remove-prefix "/signal/" path)) body))
|
||||
((and (equal method "POST") (string-prefix-p "/watch/" path))
|
||||
(kkkmeet-server--handle-watch
|
||||
process (url-unhex-string (string-remove-prefix "/watch/" path)) body))
|
||||
((member method '("GET" "HEAD"))
|
||||
(kkkmeet-server--serve-static process method path))
|
||||
(t
|
||||
@@ -302,6 +338,7 @@ When KEEP-OPEN is nil, close PROCESS after writing."
|
||||
(interactive)
|
||||
(kkkmeet-server-stop)
|
||||
(setq kkkmeet-server--rooms (make-hash-table :test 'equal))
|
||||
(setq kkkmeet-server--watch-states (make-hash-table :test 'equal))
|
||||
(setq kkkmeet-server--process
|
||||
(make-network-process
|
||||
:name "kkkmeet-server"
|
||||
@@ -329,7 +366,8 @@ When KEEP-OPEN is nil, close PROCESS after writing."
|
||||
room))
|
||||
kkkmeet-server--rooms)
|
||||
(setq kkkmeet-server--process nil)
|
||||
(setq kkkmeet-server--rooms (make-hash-table :test 'equal)))
|
||||
(setq kkkmeet-server--rooms (make-hash-table :test 'equal))
|
||||
(setq kkkmeet-server--watch-states (make-hash-table :test 'equal)))
|
||||
|
||||
;;;###autoload
|
||||
(defun kkkmeet-server-run-batch ()
|
||||
|
||||
Reference in New Issue
Block a user