From 17bc3d9da373a19a6b3cc2c00ecefab4b0d7c7f5 Mon Sep 17 00:00:00 2001 From: trichimtrich Date: Sun, 7 Apr 2019 00:25:28 +0800 Subject: [PATCH] choose http/ws, remove frame, add close state --- index_http.html | 219 +++++++++++++ index.html => index_ws.html | 602 +++++++++++++++++------------------- main.go | 72 +++-- ui/director.go | 2 +- ui/gameview.go | 11 +- webrtc/webrtc.go | 6 + 6 files changed, 558 insertions(+), 354 deletions(-) create mode 100644 index_http.html rename index.html => index_ws.html (82%) diff --git a/index_http.html b/index_http.html new file mode 100644 index 00000000..aed190d9 --- /dev/null +++ b/index_http.html @@ -0,0 +1,219 @@ + + + + + + + +

+ +

+ +

Instruction

+
+ Use Up, Down, Left, Right to Move
+ Z to jump (A)
+ X to sprint (B)
+ C is start button
+ V is select button
+ + +

+ +

Log:

+

+
+
+ 🎮Refresh to retry when checking is too long +
+ + diff --git a/index.html b/index_ws.html similarity index 82% rename from index.html rename to index_ws.html index c5cad153..7774dc16 100644 --- a/index.html +++ b/index_ws.html @@ -1,319 +1,283 @@ - - - - - - - - -

- -

- -

Instruction

-
- Use Up, Down, Left, Right to Move
- Z to jump (A)
- X to sprint (B)
- C is start button
- V is select button
- - -

- -

Log:

-

-
-
- 🎮Refresh to retry when checking is too long -
- - + + + + + + + +

+ +

+ +

Instruction

+
+ Use Up, Down, Left, Right to Move
+ Z to jump (A)
+ X to sprint (B)
+ C is start button
+ V is select button
+ + +

+ +

Log:

+

+
+
+ 🎮Refresh to retry when checking is too long +
+ + diff --git a/main.go b/main.go index e88d644a..44408b55 100644 --- a/main.go +++ b/main.go @@ -2,19 +2,19 @@ package main import ( pionRTC "github.com/pions/webrtc" + "os" + "fmt" "image" "io/ioutil" "log" "net/http" - "time" - "github.com/giongto35/cloud-game/ui" "github.com/giongto35/cloud-game/util" "github.com/giongto35/cloud-game/webrtc" - // "github.com/gorilla/mux" + "github.com/gorilla/mux" "github.com/gorilla/websocket" "encoding/json" @@ -23,10 +23,7 @@ import ( // var webRTC *webrtc.WebRTC var width = 256 var height = 240 -// var gameName = "supermariobros.rom" -var gameName string - -// var FPS = 60 +var index string = "./index_http.html" var upgrader = websocket.Upgrader{} @@ -43,25 +40,28 @@ func startGame(path string, imageChannel chan *image.RGBA, inputChannel chan int } func main() { + fmt.Printf("Usage: %s [ws]\n", os.Args[0]) fmt.Println("http://localhost:8000") - fmt.Println(time.Now().UnixNano()) + if len(os.Args) > 1 { + log.Println("Using websocket") + index = "./index_ws.html" - // router := mux.NewRouter() - // router.HandleFunc("/", getWeb).Methods("GET") - // router.HandleFunc("/session", postSession).Methods("POST") - // http.ListenAndServe(":8000", router) - - // ignore origin - upgrader.CheckOrigin = func(r *http.Request) bool { return true } - - http.HandleFunc("/", getWeb) - http.HandleFunc("/ws", ws) - - http.ListenAndServe(":8000", nil) + // ignore origin + upgrader.CheckOrigin = func(r *http.Request) bool { return true } + http.HandleFunc("/", getWeb) + http.HandleFunc("/ws", ws) + http.ListenAndServe(":8000", nil) + } else { + log.Println("Using http") + router := mux.NewRouter() + router.HandleFunc("/", getWeb).Methods("GET") + router.HandleFunc("/session", postSession).Methods("POST") + http.ListenAndServe(":8000", router) + } } func getWeb(w http.ResponseWriter, r *http.Request) { - bs, err := ioutil.ReadFile("./index.html") + bs, err := ioutil.ReadFile(index) if err != nil { log.Fatal(err) } @@ -84,6 +84,8 @@ func ws(w http.ResponseWriter, r *http.Request) { // start new games and webrtc stuff? isDone := false + var gameName string + for !isDone { mt, message, err := c.ReadMessage() if err != nil { @@ -150,6 +152,15 @@ func ws(w http.ResponseWriter, r *http.Request) { } } + + + +type SessionPacket struct { + Game string `json:"game"` + SDP string `json:"sdp"` +} + + func postSession(w http.ResponseWriter, r *http.Request) { bs, err := ioutil.ReadAll(r.Body) if err != nil { @@ -157,16 +168,24 @@ func postSession(w http.ResponseWriter, r *http.Request) { } r.Body.Close() + var postPacket SessionPacket + err = json.Unmarshal(bs, &postPacket) + if err != nil { + log.Fatalln(err) + } + + log.Println("Got session with game request:", postPacket.Game) + webRTC := webrtc.NewWebRTC() - localSession, err := webRTC.StartClient(string(bs), width, height) + localSession, err := webRTC.StartClient(postPacket.SDP, width, height) if err != nil { log.Fatalln(err) } imageChannel := make(chan *image.RGBA, 100) go screenshotLoop(imageChannel, webRTC) - go startGame("games/"+gameName, imageChannel, webRTC.InputChannel, webRTC) + go startGame("games/" + postPacket.Game, imageChannel, webRTC.InputChannel, webRTC) w.Write([]byte(localSession)) } @@ -174,12 +193,15 @@ func postSession(w http.ResponseWriter, r *http.Request) { // func screenshotLoop(imageChannel chan *image.RGBA) { func screenshotLoop(imageChannel chan *image.RGBA, webRTC *webrtc.WebRTC) { for image := range imageChannel { + // Client stopped + if webRTC.IsClosed() { + break + } + // encode frame if webRTC.IsConnected() { yuv := util.RgbaToYuv(image) webRTC.ImageChannel <- yuv - } else { - break } } } diff --git a/ui/director.go b/ui/director.go index 6997b171..bed29af5 100644 --- a/ui/director.go +++ b/ui/director.go @@ -65,7 +65,7 @@ func (d *Director) Start(paths []string) { func (d *Director) Run() { for { // quit game - if !d.webRTC.IsConnected() { + if d.webRTC.IsClosed() { break } diff --git a/ui/gameview.go b/ui/gameview.go index 28eee480..0845ea86 100644 --- a/ui/gameview.go +++ b/ui/gameview.go @@ -4,7 +4,6 @@ import ( "image" "fmt" - "time" "github.com/giongto35/cloud-game/nes" ) @@ -24,11 +23,10 @@ type GameView struct { imageChannel chan *image.RGBA inputChannel chan int - nanotime int64 } func NewGameView(director *Director, console *nes.Console, title, hash string, imageChannel chan *image.RGBA, inputChannel chan int) View { - gameview := &GameView{director, console, title, hash, false, nil, [8]bool{false}, imageChannel, inputChannel, time.Now().UnixNano()} + gameview := &GameView{director, console, title, hash, false, nil, [8]bool{false}, imageChannel, inputChannel} go gameview.ListenToInputChannel() return gameview } @@ -88,12 +86,7 @@ func (view *GameView) Update(t, dt float64) { console.StepSeconds(dt) // fps to set frame - n := time.Now().UnixNano() - if n - view.nanotime > 1000000000 / 100000 { - view.nanotime = n - view.imageChannel <- console.Buffer() - } - + view.imageChannel <- console.Buffer() if view.record { diff --git a/webrtc/webrtc.go b/webrtc/webrtc.go index dbdc7a9b..e0fdf8f4 100644 --- a/webrtc/webrtc.go +++ b/webrtc/webrtc.go @@ -108,6 +108,7 @@ type WebRTC struct { connection *webrtc.PeerConnection encoder *vpxEncoder.VpxEncoder isConnected bool + isClosed bool // for yuvI420 image ImageChannel chan []byte InputChannel chan int @@ -225,6 +226,7 @@ func (w *WebRTC) StopClient() { w.connection.Close() } w.connection = nil + w.isClosed = true } // IsConnected comment @@ -232,6 +234,10 @@ func (w *WebRTC) IsConnected() bool { return w.isConnected } +func (w *WebRTC) IsClosed() bool { + return w.isClosed +} + func (w *WebRTC) startStreaming(vp8Track *webrtc.Track) { fmt.Println("Start streaming")