Files
xTeVe/src/internal/m3u-parser/xteve_m3uParser.go
2019-09-04 20:12:26 +02:00

183 lines
3.9 KiB
Go
Executable File

package m3u
import (
"errors"
"fmt"
"log"
"net/url"
"regexp"
"strings"
)
// MakeInterfaceFromM3U :
func MakeInterfaceFromM3U(byteStream []byte) (allChannels []interface{}, err error) {
var content = string(byteStream)
var channelName string
var uuids []string
var parseMetaData = func(channel string) (stream map[string]string) {
stream = make(map[string]string)
var exceptForParameter = `[a-z-A-Z=]*(".*?")`
var exceptForChannelName = `,([^\n]*|,[^\r]*)`
var lines = strings.Split(strings.Replace(channel, "\r\n", "\n", -1), "\n")
// Zeilen mit # und leerer Zeilen entfernen
for i := len(lines) - 1; i >= 0; i-- {
if len(lines[i]) == 0 || lines[i][0:1] == "#" {
lines = append(lines[:i], lines[i+1:]...)
}
}
if len(lines) >= 2 {
for _, line := range lines {
_, err := url.ParseRequestURI(line)
switch err {
case nil:
stream["url"] = strings.Trim(line, "\r\n")
default:
var value string
// Alle Parameter parsen
var p = regexp.MustCompile(exceptForParameter)
var streamParameter = p.FindAllString(line, -1)
for _, p := range streamParameter {
line = strings.Replace(line, p, "", 1)
p = strings.Replace(p, `"`, "", -1)
var parameter = strings.SplitN(p, "=", 2)
if len(parameter) == 2 {
// TVG Key als Kleinbuchstaben speichern
switch strings.Contains(parameter[0], "tvg") {
case true:
stream[strings.ToLower(parameter[0])] = parameter[1]
case false:
stream[parameter[0]] = parameter[1]
}
// URL's nicht an die Filterfunktion übergeben
if !strings.Contains(parameter[1], "://") && len(parameter[1]) > 0 {
value = value + parameter[1] + " "
}
}
}
// Kanalnamen parsen
n := regexp.MustCompile(exceptForChannelName)
var name = n.FindAllString(line, 1)
if len(name) > 0 {
channelName = name[0]
channelName = strings.Replace(channelName, `,`, "", 1)
channelName = strings.TrimRight(channelName, "\r\n")
channelName = strings.TrimRight(channelName, " ")
}
if len(channelName) == 0 {
if v, ok := stream["tvg-name"]; ok {
channelName = v
}
}
channelName = strings.TrimRight(channelName, " ")
// Kanäle ohne Namen werden augelassen
if len(channelName) == 0 {
return
}
stream["name"] = channelName
value = value + channelName
stream["_values"] = value
}
}
}
// Nach eindeutiger ID im Stream suchen
for key, value := range stream {
if !strings.Contains(strings.ToLower(key), "tvg-id") {
if strings.Contains(strings.ToLower(key), "id") {
if indexOfString(value, uuids) != -1 {
log.Println(fmt.Sprintf("Channel: %s - %s = %s ", stream["name"], key, value))
break
}
uuids = append(uuids, value)
stream["_uuid.key"] = key
stream["_uuid.value"] = value
break
}
}
}
return
}
//fmt.Println(content)
if strings.Contains(content, "#EXTM3U") {
var channels = strings.Split(content, "#EXTINF")
channels = append(channels[:0], channels[1:]...)
for _, channel := range channels {
var stream = parseMetaData(channel)
if len(stream) > 0 && stream != nil {
allChannels = append(allChannels, stream)
}
}
} else {
err = errors.New("No valid m3u file")
}
return
}
func indexOfString(element string, data []string) int {
for k, v := range data {
if element == v {
return k
}
}
return -1
}