mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-09 21:56:50 -04:00
Add a display type for showing a Twitch stream.
This commit is contained in:
@@ -31,6 +31,7 @@ const (
|
||||
AudienceDisplay
|
||||
FieldMonitorDisplay
|
||||
PitDisplay
|
||||
TwitchStreamDisplay
|
||||
)
|
||||
|
||||
var DisplayTypeNames = map[DisplayType]string{
|
||||
@@ -40,6 +41,7 @@ var DisplayTypeNames = map[DisplayType]string{
|
||||
AudienceDisplay: "Audience",
|
||||
FieldMonitorDisplay: "Field Monitor",
|
||||
PitDisplay: "Pit",
|
||||
TwitchStreamDisplay: "Twitch Stream",
|
||||
}
|
||||
|
||||
var displayTypePaths = map[DisplayType]string{
|
||||
@@ -49,6 +51,7 @@ var displayTypePaths = map[DisplayType]string{
|
||||
AudienceDisplay: "/displays/audience",
|
||||
FieldMonitorDisplay: "/displays/fta",
|
||||
PitDisplay: "/displays/pit",
|
||||
TwitchStreamDisplay: "/displays/twitch",
|
||||
}
|
||||
|
||||
var displayRegistryMutex sync.Mutex
|
||||
|
||||
12
static/css/twitch_display.css
Normal file
12
static/css/twitch_display.css
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
Copyright 2018 Team 254. All Rights Reserved.
|
||||
Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
*/
|
||||
|
||||
html {
|
||||
overflow: hidden;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: #000;
|
||||
}
|
||||
23
static/js/twitch_display.js
Normal file
23
static/js/twitch_display.js
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2018 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
//
|
||||
// Client-side logic for the Twitch stream display.
|
||||
|
||||
var websocket;
|
||||
|
||||
$(function() {
|
||||
// Read the configuration for this display from the URL query string.
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
// Embed the video stream.
|
||||
new Twitch.Embed("twitchEmbed", {
|
||||
channel: urlParams.get("channel"),
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
layout: "video"
|
||||
});
|
||||
|
||||
// Set up the websocket back to the server.
|
||||
websocket = new CheesyWebsocket("/displays/twitch/websocket", {
|
||||
});
|
||||
});
|
||||
23
templates/twitch_display.html
Normal file
23
templates/twitch_display.html
Normal file
@@ -0,0 +1,23 @@
|
||||
{{/*
|
||||
Copyright 2018 Team 254. All Rights Reserved.
|
||||
Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
Display to show a configurable Twitch live video stream.
|
||||
*/}}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Twitch Stream Display - {{.EventSettings.Name}} - Cheesy Arena </title>
|
||||
<link rel="shortcut icon" href="/static/img/favicon.ico">
|
||||
<link rel="stylesheet" href="/static/css/twitch_display.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="twitchEmbed"></div>
|
||||
<script src="https://embed.twitch.tv/embed/v1.js"></script>
|
||||
<script src="/static/js/lib/jquery.min.js"></script>
|
||||
<script src="/static/js/lib/jquery.json-2.4.min.js"></script>
|
||||
<script src="/static/js/lib/jquery.websocket-0.0.1.js"></script>
|
||||
<script src="/static/js/cheesy-websocket.js"></script>
|
||||
<script src="/static/js/twitch_display.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
61
web/twitch_display.go
Normal file
61
web/twitch_display.go
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright 2018 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
//
|
||||
// Web routes for a display to show a configurable Twitch live video stream.
|
||||
|
||||
package web
|
||||
|
||||
import (
|
||||
"github.com/Team254/cheesy-arena/model"
|
||||
"github.com/Team254/cheesy-arena/websocket"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Renders the Twitch stream view.
|
||||
func (web *Web) twitchDisplayHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !web.userIsReader(w, r) {
|
||||
return
|
||||
}
|
||||
|
||||
if !web.enforceDisplayConfiguration(w, r, map[string]string{"channel": "team254"}) {
|
||||
return
|
||||
}
|
||||
|
||||
template, err := web.parseFiles("templates/twitch_display.html")
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
}
|
||||
data := struct {
|
||||
*model.EventSettings
|
||||
}{web.arena.EventSettings}
|
||||
err = template.ExecuteTemplate(w, "twitch_display.html", data)
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// The websocket endpoint for sending configuration commands to the display.
|
||||
func (web *Web) twitchDisplayWebsocketHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !web.userIsReader(w, r) {
|
||||
return
|
||||
}
|
||||
|
||||
display, err := web.registerDisplay(r)
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
}
|
||||
defer web.arena.MarkDisplayDisconnected(display)
|
||||
|
||||
ws, err := websocket.NewWebsocket(w, r)
|
||||
if err != nil {
|
||||
handleWebErr(w, err)
|
||||
return
|
||||
}
|
||||
defer ws.Close()
|
||||
|
||||
// Subscribe the websocket to the notifiers whose messages will be passed on to the client.
|
||||
ws.HandleNotifiers(web.arena.DisplayConfigurationNotifier, web.arena.ReloadDisplaysNotifier)
|
||||
}
|
||||
33
web/twitch_display_test.go
Normal file
33
web/twitch_display_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright 2018 Team 254. All Rights Reserved.
|
||||
// Author: pat@patfairbank.com (Patrick Fairbank)
|
||||
|
||||
package web
|
||||
|
||||
import (
|
||||
"github.com/Team254/cheesy-arena/websocket"
|
||||
gorillawebsocket "github.com/gorilla/websocket"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTwitchDisplay(t *testing.T) {
|
||||
web := setupTestWeb(t)
|
||||
|
||||
recorder := web.getHttpResponse("/displays/twitch?displayId=1&channel=team254")
|
||||
assert.Equal(t, 200, recorder.Code)
|
||||
assert.Contains(t, recorder.Body.String(), "Twitch Stream Display - Untitled Event - Cheesy Arena")
|
||||
}
|
||||
|
||||
func TestTwitchDisplayWebsocket(t *testing.T) {
|
||||
web := setupTestWeb(t)
|
||||
|
||||
server, wsUrl := web.startTestServer()
|
||||
defer server.Close()
|
||||
conn, _, err := gorillawebsocket.DefaultDialer.Dial(wsUrl+"/displays/twitch/websocket?displayId=123", nil)
|
||||
assert.Nil(t, err)
|
||||
defer conn.Close()
|
||||
ws := websocket.NewTestWebsocket(conn)
|
||||
|
||||
// Should get a few status updates right after connection.
|
||||
readWebsocketType(t, ws, "displayConfiguration")
|
||||
}
|
||||
@@ -148,6 +148,8 @@ func (web *Web) newHandler() http.Handler {
|
||||
router.HandleFunc("/displays/fta/websocket", web.ftaDisplayWebsocketHandler).Methods("GET")
|
||||
router.HandleFunc("/displays/pit", web.pitDisplayHandler).Methods("GET")
|
||||
router.HandleFunc("/displays/pit/websocket", web.pitDisplayWebsocketHandler).Methods("GET")
|
||||
router.HandleFunc("/displays/twitch", web.twitchDisplayHandler).Methods("GET")
|
||||
router.HandleFunc("/displays/twitch/websocket", web.twitchDisplayWebsocketHandler).Methods("GET")
|
||||
router.HandleFunc("/match_play", web.matchPlayHandler).Methods("GET")
|
||||
router.HandleFunc("/match_play/{matchId}/load", web.matchPlayLoadHandler).Methods("GET")
|
||||
router.HandleFunc("/match_play/{matchId}/show_result", web.matchPlayShowResultHandler).Methods("GET")
|
||||
|
||||
Reference in New Issue
Block a user