88 lines
2.2 KiB
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")
|
|
}
|
|
}
|