68 lines
1.8 KiB
Go
68 lines
1.8 KiB
Go
|
// Copyright (c) 2025, Julian Müller (ChaoticByte)
|
||
|
|
||
|
package core
|
||
|
|
||
|
import (
|
||
|
"regexp"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
var availFormatsRegex = regexp.MustCompile(`NAME="(.+)"`)
|
||
|
|
||
|
func parseAvailFormatsFromM3u8(m3u8 string) []VideoFormat {
|
||
|
foundFormats := []VideoFormat{}
|
||
|
m3u8 = strings.ReplaceAll(m3u8, "\r", "")
|
||
|
parts := strings.Split(m3u8, "#EXT-X-STREAM-INF")
|
||
|
for _, p := range parts {
|
||
|
p := strings.Trim(p, " \n")
|
||
|
if strings.HasPrefix(p, ":") && strings.Contains(p, "RESOLUTION=") && strings.Contains(p, "FRAMERATE=") && strings.Contains(p, "NAME=") {
|
||
|
format := VideoFormat{}
|
||
|
plItem := strings.Split(p, "\n")
|
||
|
if len(plItem) < 2 {
|
||
|
continue
|
||
|
}
|
||
|
formatName := availFormatsRegex.FindStringSubmatch(plItem[0])
|
||
|
if formatName == nil {
|
||
|
continue // didn't find format
|
||
|
}
|
||
|
format.Name = formatName[1]
|
||
|
format.Url = plItem[1]
|
||
|
foundFormats = append(foundFormats, format)
|
||
|
}
|
||
|
}
|
||
|
return foundFormats
|
||
|
}
|
||
|
|
||
|
var targetDurationRegex = regexp.MustCompile(`#EXT-X-TARGETDURATION:(.+)`)
|
||
|
|
||
|
func parseChunkListFromM3u8(m3u8 string, baseurl string) (ChunkList, error) {
|
||
|
chunklist := ChunkList{BaseUrl: baseurl}
|
||
|
m3u8 = strings.ReplaceAll(m3u8, "\r", "")
|
||
|
parts := strings.Split(m3u8, "#EXTINF")
|
||
|
for _, p := range parts {
|
||
|
if strings.HasPrefix(p, "#EXTM3U") {
|
||
|
lines := strings.Split(p, "\n")
|
||
|
for _, l := range lines {
|
||
|
if strings.HasPrefix(l, "#EXT-X-TARGETDURATION") {
|
||
|
targetDuration := targetDurationRegex.FindStringSubmatch(l)
|
||
|
if targetDuration == nil {
|
||
|
continue
|
||
|
}
|
||
|
chunkDuration, err := strconv.ParseFloat(targetDuration[1], 64)
|
||
|
if err != nil {
|
||
|
return chunklist, err
|
||
|
}
|
||
|
chunklist.ChunkDuration = chunkDuration
|
||
|
}
|
||
|
}
|
||
|
} else if strings.HasPrefix(p, ":") {
|
||
|
lines := strings.Split(p, "\n")
|
||
|
if len(lines) > 1 {
|
||
|
chunklist.Chunks = append(chunklist.Chunks, lines[1])
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return chunklist, nil
|
||
|
}
|