Files
Aroll-Cutter/handlers/export.go

88 lines
2.2 KiB
Go

package handlers
import (
"encoding/json"
"log"
"net/http"
"os"
"aroll/store"
"aroll/transcode"
"aroll/ws"
)
type exportRequest struct {
Filename string `json:"filename"`
Segments []transcode.Segment `json:"segments"`
Duration float64 `json:"duration"`
}
type updateTimeLine struct {
Type string `json:"type"`
Segments []transcode.Segment `json:"segments"`
Duration float64 `json:"duration"`
}
func ExportHandler(st *store.Store, hub *ws.Hub) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
var req exportRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "bad JSON: "+err.Error(), http.StatusBadRequest)
return
}
if len(req.Segments) == 0 {
http.Error(w, "no segments", http.StatusBadRequest)
return
}
inPath, ok := st.Path(req.Filename)
if !ok {
http.Error(w, "file not found", http.StatusNotFound)
return
}
go func() {
/* ToDo: Make sure that other video formats gets transcoded */
outputKey := "output-" + store.NewID() + ".mp4"
outPath := st.Allocate(outputKey)
if err := transcode.ExportSegments(inPath, outPath, req.Segments, hub.Broadcast); err != nil {
os.Remove(outPath)
broadcastError(hub, err.Error())
return
}
doneMsg, _ := json.Marshal(map[string]string{
"type": "done",
"message": outputKey,
})
hub.Broadcast(doneMsg)
// Build normalized segments for the exported video: timestamps start at 0
// with no gaps, so the timeline reflects the exported file's layout.
var normalized []transcode.Segment
cursor := 0.0
for _, seg := range req.Segments {
dur := seg.End - seg.Start
normalized = append(normalized, transcode.Segment{Start: cursor, End: cursor + dur})
cursor += dur
}
timelineMsg, _ := json.Marshal(updateTimeLine{
Type: "timeline",
Segments: normalized,
Duration: cursor,
})
hub.Broadcast(timelineMsg)
}()
w.WriteHeader(http.StatusAccepted)
log.Println("Export handler works")
}
}