func AddSegmentToSchedule(s *datastore.Schedule, bs BroadcastSegment) error { playlistBlob := datastore.Blob{s.CacheKey()} if s.MediaPlaylist == nil { // If no playlist exists s.MediaPlaylist, _ = m3u8.NewMediaPlaylist(100, 100) // alloc a new one if plistData, err := playlistBlob.GetBuffer(); err == nil { s.MediaPlaylist.Decode(*plistData, false) } } err := s.MediaPlaylist.Append(bs.MediaURL, bs.TargetDuration, bs.Title) // append the item if err != nil { s.MediaPlaylist.Slide(bs.MediaURL, bs.TargetDuration, bs.Title) // or slide if playlist full } s.MediaPlaylist.SetProgramDateTime(time.Now()) if bs.Discontinuity { // If the video format is different than the last segment if err := s.MediaPlaylist.SetDiscontinuity(); err != nil { // let the player know return err } } if err := playlistBlob.Set(s.PlaylistData()); err != nil { return err } return nil }
func (c GeneratorController) ServeHTTP(w http.ResponseWriter, r *http.Request) { requestedChannel := strings.Split(r.URL.Path, ".")[0] channelSchedule := &datastore.Schedule{Id: requestedChannel} blob := datastore.Blob{channelSchedule.CacheKey()} if !channelSchedule.IsPlaying() { go generator.Start(channelSchedule) // start generator } str, err := blob.Get() if err != nil { // If playlist isn't rendered w.WriteHeader(202) fmt.Fprintln(w, "generating", requestedChannel) } else { // otherwise render playlist from redis w.Header().Add("Content-Type", "application/x-mpegurl") fmt.Fprintln(w, str) } }