From 2bca07ea85158b3c86f5166f0ddac9799929dc68 Mon Sep 17 00:00:00 2001
From: Himadri Bhattacharjee <107522312+lavafroth@users.noreply.github.com>
Date: Sun, 7 Sep 2025 18:02:06 +0530
Subject: [PATCH] init: initial commit
---
go.mod | 5 ++
go.sum | 2 +
index.html | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++
main.go | 83 +++++++++++++++++++++++++++++++++
4 files changed, 221 insertions(+)
create mode 100644 go.mod
create mode 100644 go.sum
create mode 100644 index.html
create mode 100644 main.go
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..5325a5e
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,5 @@
+module github.com/lavafroth/okiiparty
+
+go 1.24.5
+
+require github.com/gorilla/websocket v1.5.3
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..25a9fc4
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,2 @@
+github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
+github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..a028021
--- /dev/null
+++ b/index.html
@@ -0,0 +1,131 @@
+
+
+
+ Okiiparty
+
+
+
+
+
+
+
The stream is muted because autoplay requires audio to be switched off. Please unmute the stream and I will disappear.
+
+
+
+
+
+
+
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..0d90659
--- /dev/null
+++ b/main.go
@@ -0,0 +1,83 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "log"
+ "net/http"
+ "sync"
+
+ "github.com/gorilla/websocket"
+)
+
+var upgrader = websocket.Upgrader{
+ ReadBufferSize: 128,
+ WriteBufferSize: 128,
+}
+
+var broker Broker
+
+type Broker struct {
+ sockets map[*websocket.Conn]struct{}
+ mutex sync.Mutex
+}
+
+func newStreamHandler(movieFile string) func(w http.ResponseWriter, r *http.Request) {
+ return func(w http.ResponseWriter, r *http.Request) {
+ http.ServeFile(w, r, movieFile)
+ }
+}
+
+func playPauseBroker(w http.ResponseWriter, r *http.Request) {
+ conn, err := upgrader.Upgrade(w, r, nil)
+ if err != nil {
+ log.Printf("failed to fulfill client request for playPauseBroker: %v", err)
+ return
+ }
+
+ broker.mutex.Lock()
+ broker.sockets[conn] = struct{}{}
+ log.Printf("broker currently handles %d clients", len(broker.sockets))
+ broker.mutex.Unlock()
+
+ for {
+ messageType, p, err := conn.ReadMessage()
+ if err != nil {
+ log.Printf("failed to read message from client %p: %v", conn, err)
+ log.Printf("will attempt to close connection %p", conn)
+ if err := conn.Close(); err != nil {
+ log.Printf("failed to close connection at %p", conn)
+ }
+ delete(broker.sockets, conn)
+ return
+ }
+
+ for client := range broker.sockets {
+ if client == conn {
+ continue // prevent self echo
+ }
+
+ if err := client.WriteMessage(messageType, p); err != nil {
+ log.Printf("while sending: %s to client %p: %v", p, client, err)
+ }
+ log.Printf("successfully sent %s", p)
+ }
+ }
+}
+
+func main() {
+ listenPort := flag.Uint("port", 8000, "port to listen on")
+ flag.Parse()
+ streamFile := flag.Arg(0)
+ if streamFile == "" {
+ log.Fatal("stream file is undefined")
+ }
+ broker.sockets = make(map[*websocket.Conn]struct{})
+ http.HandleFunc("/stream", newStreamHandler(streamFile))
+ http.HandleFunc("/broker", playPauseBroker)
+ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ http.ServeFile(w, r, "index.html")
+ })
+
+ panic(http.ListenAndServe(fmt.Sprintf(":%d", *listenPort), nil))
+}