mirror of https://github.com/synctv-org/synctv
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
2.8 KiB
Go
95 lines
2.8 KiB
Go
package m3u8
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
func GetM3u8AllSegments(m3u8Str string, baseURL string) ([]string, error) {
|
|
var segments []string
|
|
err := RangeM3u8SegmentsWithBaseURL(m3u8Str, baseURL, func(segmentUrl string) (bool, error) {
|
|
segments = append(segments, segmentUrl)
|
|
return true, nil
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return segments, nil
|
|
}
|
|
|
|
func RangeM3u8Segments(m3u8Str string, callback func(segmentUrl string) (bool, error)) error {
|
|
scanner := bufio.NewScanner(strings.NewReader(m3u8Str))
|
|
for scanner.Scan() {
|
|
line := strings.TrimSpace(scanner.Text())
|
|
if line != "" && !strings.HasPrefix(line, "#") {
|
|
if ok, err := callback(line); err != nil {
|
|
return err
|
|
} else if !ok {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if err := scanner.Err(); err != nil {
|
|
return fmt.Errorf("scan m3u8 error: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func RangeM3u8SegmentsWithBaseURL(m3u8Str string, baseURL string, callback func(segmentURL string) (bool, error)) error {
|
|
baseURLParsed, err := url.Parse(baseURL)
|
|
if err != nil {
|
|
return fmt.Errorf("parse base url error: %w", err)
|
|
}
|
|
return RangeM3u8Segments(m3u8Str, func(segmentURL string) (bool, error) {
|
|
if !strings.HasPrefix(segmentURL, "http://") && !strings.HasPrefix(segmentURL, "https://") {
|
|
segmentURLParsed, err := url.Parse(segmentURL)
|
|
if err != nil {
|
|
return false, fmt.Errorf("parse segment url error: %w", err)
|
|
}
|
|
segmentURL = baseURLParsed.ResolveReference(segmentURLParsed).String()
|
|
}
|
|
return callback(segmentURL)
|
|
})
|
|
}
|
|
|
|
func ReplaceM3u8Segments(m3u8Str string, callback func(segmentURL string) (string, error)) (string, error) {
|
|
var result strings.Builder
|
|
scanner := bufio.NewScanner(strings.NewReader(m3u8Str))
|
|
for scanner.Scan() {
|
|
line := strings.TrimSpace(scanner.Text())
|
|
if line != "" && !strings.HasPrefix(line, "#") {
|
|
newSegment, err := callback(line)
|
|
if err != nil {
|
|
return "", fmt.Errorf("callback error: %w", err)
|
|
}
|
|
result.WriteString(newSegment)
|
|
} else {
|
|
result.WriteString(line)
|
|
}
|
|
result.WriteString("\n")
|
|
}
|
|
if err := scanner.Err(); err != nil {
|
|
return "", fmt.Errorf("scan m3u8 error: %w", err)
|
|
}
|
|
return result.String(), nil
|
|
}
|
|
|
|
func ReplaceM3u8SegmentsWithBaseURL(m3u8Str string, baseURL string, callback func(segmentURL string) (string, error)) (string, error) {
|
|
baseURLParsed, err := url.Parse(baseURL)
|
|
if err != nil {
|
|
return "", fmt.Errorf("parse base url error: %w", err)
|
|
}
|
|
return ReplaceM3u8Segments(m3u8Str, func(segmentURL string) (string, error) {
|
|
if !strings.HasPrefix(segmentURL, "http://") && !strings.HasPrefix(segmentURL, "https://") {
|
|
segmentURLParsed, err := url.Parse(segmentURL)
|
|
if err != nil {
|
|
return "", fmt.Errorf("parse segment url error: %w", err)
|
|
}
|
|
segmentURL = baseURLParsed.ResolveReference(segmentURLParsed).String()
|
|
}
|
|
return callback(segmentURL)
|
|
})
|
|
}
|