Esempio n. 1
0
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
}
Esempio n. 2
0
func (s *Stream) ResetPlaylist(vodPlaylist bool) {
	s.Playlist, _ = m3u8.NewMediaPlaylist(10000, 10000) // alloc a new Playlist
	if vodPlaylist {
		s.Playlist.MediaType = m3u8.VOD
		s.Playlist.Closed = true
	}
}
Esempio n. 3
0
func NewStream(idx string, instruction StreamInstruction) (stream Stream) {
	stream.Identifier = idx
	stream.UUID = uuid.NewRandom().String()
	stream.Instruction = instruction
	stream.Playlist, _ = m3u8.NewMediaPlaylist(10000, 10000) // alloc a new one
	return
}
Esempio n. 4
0
func RunPlaylist(in generator.StreamInstruction, out chan generator.BroadcastCommand) error {
	params := in.Args
	playlistUrl := params["playlist_url"]
	startString := params["start_at"]
	endString := params["end_at"]
	startAt, _ := strconv.Atoi(startString) // error will default to 0
	endAt, conversionErr := strconv.Atoi(endString)
	if conversionErr != nil {
		endAt = 200000
	}

	resp, err := http.Get(playlistUrl)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	mp, _ := m3u8.NewMediaPlaylist(100000, 100000)
	if err := mp.DecodeFrom(resp.Body, false); err != nil {
		return err
	}
	playlistHasMoreItems := func(z int) bool { return (mp.Segments[z] != nil && (z < endAt)) }

	for i := startAt; playlistHasMoreItems(i); i++ {
		segmentUrl := ""
		relativePath := mp.Segments[i].URI

		if comps := strings.Split(playlistUrl, "/"); len(comps) > 0 {
			suffix := comps[len(comps)-1]
			baseUrl := strings.TrimSuffix(playlistUrl, suffix)
			segmentUrl = baseUrl + relativePath
		} else {
			segmentUrl = relativePath
		}

		relativeUrls, ok := params["relative_urls"]
		if ok && relativeUrls == "true" {
			segmentUrl = strings.TrimPrefix(segmentUrl, "http://www.smick.tv")
		}

		bs := generator.BroadcastSegment{
			MediaURL:       segmentUrl,
			TargetDuration: mp.Segments[i].Duration,
			Discontinuity:  (i == startAt || mp.Segments[i].Discontinuity),
		}
		command := generator.BroadcastCommand{
			Type:    "broadcast-segment",
			Segment: bs,
		}
		out <- command
	}

	return nil
}
Esempio n. 5
0
func Preview(p datastore.Program) (mediaPlaylist *m3u8.MediaPlaylist, err error) {
	pipeline := RunProgram(p) // Run the program
	pipeline.Close()          // And close it out when we're done

	segments := make([]BroadcastSegment, 0)
	for vd := range pipeline.MediaChannel() {
		segments = append(segments, vd.Segment)
	}

	seglen := uint(len(segments))
	mediaPlaylist, _ = m3u8.NewMediaPlaylist(seglen, seglen)
	mediaPlaylist.MediaType = m3u8.VOD
	mediaPlaylist.Closed = true

	for _, s := range segments {
		if err = s.AddTo(mediaPlaylist); err != nil {
			return
		}
	}

	return
}
Esempio n. 6
0
func trimM3u8(c web.C, w http.ResponseWriter, r *http.Request) {

	q := r.URL.Query().Get("sec")

	sec, err := strconv.Atoi(q)
	if err != nil {
		sec = 0
	}

	resp, err := http.Get(m3u8URL)
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte("faild to get m3u8 file"))
		return
	}
	defer resp.Body.Close()

	p, err := m3u8.NewMediaPlaylist(1024, 1024)
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte("faild to NewMediaPlaylist"))
		return
	}
	defer p.Close()

	err = p.DecodeFrom(resp.Body, true)
	if err != nil {
		w.WriteHeader(500)
		w.Write([]byte("faild to decode m3u8 file"))
		return
	}

	if sec != 0 {
		p.Segments = append(p.Segments[(sec / int(p.TargetDuration)):])
	}

	w.Write(p.Encode().Bytes())
}
Esempio n. 7
0
func (p *Playlist) PlayDescriptor(vd generator.VideoDescriptor) error {
	params := vd.Params
	playlistUrl := params["playlist_url"]
	startString := params["start_at"]
	endString, _ := params["end_at"]
	startAt, _ := strconv.Atoi(startString)
	endAt, conversionErr := strconv.Atoi(endString)
	if conversionErr != nil {
		endAt = 200000
	}

	resp, err := http.Get(playlistUrl)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	mp, _ := m3u8.NewMediaPlaylist(100000, 100000)
	if err := mp.DecodeFrom(resp.Body, false); err != nil {
		return err
	}
	playlistHasMoreItems := func(z int) bool { return (mp.Segments[z] != nil && (z < endAt)) }

	for i := startAt; playlistHasMoreItems(i); i++ {
		select {
		case <-p.CancelChan:
			return errors.New("canceled")
		default:
			segmentUrl := ""
			relativePath := mp.Segments[i].URI

			if comps := strings.Split(playlistUrl, "/"); len(comps) > 0 {
				suffix := comps[len(comps)-1]
				baseUrl := strings.TrimSuffix(playlistUrl, suffix)
				segmentUrl = baseUrl + relativePath
			} else {
				segmentUrl = relativePath
			}

			relativeUrls, ok := params["relative_urls"]
			if ok && relativeUrls == "true" {
				segmentUrl = strings.TrimPrefix(segmentUrl, "http://www.smick.tv")
			}

			bs := generator.BroadcastSegment{
				MediaURL:       segmentUrl,
				TargetDuration: mp.Segments[i].Duration,
				Discontinuity:  (i == startAt),
			}
			vd := generator.VideoDescriptor{
				SegmentReady: true,
				Segment:      bs,
				Params:       map[string]string{},
			}

			p.Output <- vd
		}
	}

	return nil
}
Esempio n. 8
0
func (s *Stream) ResizePlaylist(size uint) {
	s.Playlist, _ = m3u8.NewMediaPlaylist(size, size) // alloc a new Playlist
}