StreamRecorder/pkg/media/segment.go

113 lines
2.6 KiB
Go

package media
import (
"fmt"
"m3u8-downloader/pkg/constants"
"strconv"
"strings"
)
type Segment struct {
URL string
Duration float64
Sequence int
}
type SegmentPlaylist struct {
SegmentList []Segment
TargetDuration float64
IsLive bool
HasEndList bool
}
//func (s *StreamSet) FetchSegmentPlaylists() (videoPlaylist, audioPlaylist string, err error) {
// video, audio := s.SelectBestQualityStreams()
// if video == nil {
// return "", "", errors.New("no VideoFeeds streams available")
// }
//
// videoURL := s.BuildStreamURL(video.URL)
//
// videoContent, err := http.FetchPlaylistContent(StripQuotes(videoURL))
// if err != nil {
// return "", "", err
// }
//
// var audioContent string
// if audio != nil {
// audioURL := s.BuildStreamURL(StripQuotes(audio.URL))
// audioContent, err = http.FetchPlaylistContent(StripQuotes(audioURL))
// if err != nil {
// return "", "", err
// }
// }
//
// return videoContent, audioContent, nil
//}
func (s *StreamSet) BuildSegmentURL(filename string) string {
return fmt.Sprintf("%s%s", constants.HTTPSPrefix, s.Metadata.Domain+"/streams/"+s.Metadata.StreamID+"/"+filename)
}
func ParseMediaPlaylist(content string) *SegmentPlaylist {
lines := strings.Split(content, "\n")
var segments []Segment
playlist := &SegmentPlaylist{
IsLive: true,
HasEndList: false,
}
mediaSequence := 0
for i, line := range lines {
switch {
case strings.HasPrefix(line, constants.ExtXTargetDuration):
playlist.TargetDuration = parseTargetDuration(line)
case strings.HasPrefix(line, constants.ExtInf):
if i+1 < len(lines) {
duration := parseSegmentDuration(line)
segments = append(segments, Segment{
URL: lines[i+1],
Duration: duration,
Sequence: mediaSequence,
})
mediaSequence++
}
case strings.HasPrefix(line, constants.ExtXPlaylistType):
if strings.Contains(line, constants.PlaylistTypeVOD) {
playlist.IsLive = false
}
case strings.HasPrefix(line, constants.ExtXEndList):
playlist.HasEndList = true
}
}
playlist.SegmentList = segments
return playlist
}
func parseTargetDuration(line string) float64 {
parts := strings.SplitN(line, ":", 2)
if len(parts) == 2 {
if duration, err := strconv.ParseFloat(strings.TrimSpace(parts[1]), 64); err == nil {
return duration
}
}
return 0.0
}
func parseSegmentDuration(line string) float64 {
parts := strings.Split(line, ":")
if len(parts) >= 2 {
durationPart := strings.Split(parts[1], ",")[0]
if duration, err := strconv.ParseFloat(durationPart, 64); err == nil {
return duration
}
}
return 0.0
}