func parseRequest(w http.ResponseWriter, r *http.Request) (runMode string, s generator.Stream, err error) { urlBase := strings.Split(r.URL.Path, ".")[0] pathComps := strings.Split(urlBase, "/") runMode = "load" identifier := urlBase if len(pathComps) > 1 { runMode = pathComps[0] identifier = pathComps[1] } if runMode == "function" { functionId := identifier instructionString := functionId + "?" + r.URL.RawQuery si := generator.InstructionFromString(instructionString) s = generator.NewStream("temporary-stream", si) err = nil } else { s, err = generator.LoadStream(identifier) if err != nil && r.Method == "GET" { w.WriteHeader(404) w.Header().Add("Content-Type", "text/plain") fmt.Fprintln(w, "stream not found") } } w.Header().Add("Content-Type", "application/x-mpegurl") return }
func GenerateStreamJob(msg *workers.Msg) { jobStartTime := time.Now().Unix() jobStartTimeString := strconv.FormatInt(jobStartTime, 10) identifier, iderr := msg.Args().Get("identifier").String() if identifier == "" || iderr != nil { log.Println("No identifier! aborting!") return } client := datastore.RedisClient() lockid := "guide-stream-lock-" + identifier gotLock, err := client.SetNX(lockid, jobStartTimeString, 3*time.Second).Result() if !gotLock || err != nil { return } ticker := time.NewTicker(1 * time.Second) cancelChan := make(chan bool, 3) go func() { for { select { case <-ticker.C: client.Set(lockid, jobStartTimeString, 3*time.Second) case <-cancelChan: ticker.Stop() client.Del(lockid) return } } }() defer func() { cancelChan <- true }() stream, err := generator.LoadStream(identifier) if err != nil { log.Println("could not load given identifier", identifier, "aborting!") return } freebies := 0 if stream.Playlist.Count() == 0 { freebies = 3 } out := stream.Generate() for command := range out { if command.Type == "broadcast-segment" { durationMs := time.Duration(command.Segment.TargetDuration * 1000000) if freebies > 0 { durationMs = 0 freebies = freebies - 1 } canAdvance := time.After(durationMs * time.Microsecond) stream.ToChannel().SavePlaylist() <-canAdvance } } cancelChan <- true workers.Enqueue("guide-generate-stream-job", "GenerateStreamJob", map[string]string{ "identifier": identifier, }) }