From 382f202bb051f4784bd51e454b6552c1bc357b80 Mon Sep 17 00:00:00 2001 From: Saxon Nelson-Milton Date: Thu, 25 May 2023 06:17:58 +0930 Subject: [PATCH] Add slate request handler This change adds a request handler for /slate. This endpoint can now be used to upload a new slate file. --- cmd/vidforward/main.go | 42 +++++++++++++++++++++++++++++++++++++++++ cmd/vidforward/slate.go | 8 ++++---- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/cmd/vidforward/main.go b/cmd/vidforward/main.go index 20aff8b1..8b0994fe 100644 --- a/cmd/vidforward/main.go +++ b/cmd/vidforward/main.go @@ -34,6 +34,7 @@ import ( "io" "net" "net/http" + "os" "strconv" "sync" "time" @@ -217,6 +218,46 @@ func (m *broadcastManager) control(w http.ResponseWriter, r *http.Request) { } } +// slate handles slate API requests to upload a new slate video. +func (m *broadcastManager) slate(w http.ResponseWriter, r *http.Request) { + done := m.dogNotifier.handlerInvoked("slate") + defer done() + + if r.Method != http.MethodPost { + http.Error(w, "invalid request method", http.StatusMethodNotAllowed) + return + } + + file, _, err := r.FormFile("slate-file") + if err != nil { + m.errorLogWrite(m.log, w, "could not get slate file from form", "error", err) + return + } + defer file.Close() + + // This will overwrite the slate file if it already exists. + dst, err := os.OpenFile(slateFileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + m.errorLogWrite(m.log, w, "could not open slate file", "error", err) + return + } + defer dst.Close() + + n, err := io.Copy(dst, file) + if err != nil { + m.errorLogWrite(m.log, w, "could not copy slate file", "error", err) + return + } + + // Return response to client as JSON. + jsn, err := json.Marshal(map[string]interface{}{"size": n}) + if err != nil { + m.errorLogWrite(m.log, w, "could not get json for response", "error", err) + return + } + fmt.Fprint(w, string(jsn)) +} + // processRequest unmarshals the broadcast data object from the request into // a Broadcast value, and then performs the provided action with that value. func (m *broadcastManager) processRequest(w http.ResponseWriter, r *http.Request, action func(Broadcast) error) { @@ -374,6 +415,7 @@ func main() { http.HandleFunc("/recv", m.recv) http.HandleFunc("/control", m.control) + http.HandleFunc("/slate", m.slate) go m.dogNotifier.notify() diff --git a/cmd/vidforward/slate.go b/cmd/vidforward/slate.go index 2983824b..5a17b0be 100644 --- a/cmd/vidforward/slate.go +++ b/cmd/vidforward/slate.go @@ -36,6 +36,10 @@ import ( "bitbucket.org/ausocean/utils/logging" ) +// @note this is temporary; slate names will be created based on device mac so that we can +// have a slate per device (or maybe multiple slates per device). +const slateFileName = "/home/saxon/go/src/bitbucket.org/ausocean/av/cmd/vidforward/slate.h264" + func writeSlateAndCheckErrors(dst io.Writer, signalCh chan struct{}, log logging.Logger) error { // Also create an errCh that will be used to communicate errors from the // writeSlate routine. @@ -72,10 +76,6 @@ func writeSlateAndCheckErrors(dst io.Writer, signalCh chan struct{}, log logging func writeSlate(dst io.Writer, errCh chan error, exitSignal chan struct{}, log logging.Logger) { log.Info("writing slate") const ( - // This is temporary and will eventually be part of a broadcast configuration - // where the remote vidforward API user can provide the slate image. - slateFileName = "/home/saxon/go/src/bitbucket.org/ausocean/av/cmd/vidforward/slate.h264" - // Assume 25fps until this becomes configurable. slateFrameRate = 25