Open elv-peter opened 4 years ago
#EXT-X-MEDIA
tags can be parsed using custom tags ex:
type ExtXMediaTagValue struct {
Type string
GroupID string
Channels string
Name string
Language string
Default bool
AutoSelect bool
Forced bool
URI string
}
type ExtXMediaTag struct {
Values []*ExtXMediaTagValue
}
func (tag *ExtXMediaTag) TagName() string {
return "#EXT-X-MEDIA:"
}
func (tag *ExtXMediaTag) Decode(line string) (m3u8.CustomTag, error) {
val := &ExtXMediaTagValue{}
for k, v := range m3u8.DecodeAttributeList(line) {
switch k {
case "TYPE":
val.Type = v
case "GROUP-ID":
val.GroupID = v
case "CHANNELS":
val.Channels = v
case "NAME":
val.Name = v
case "LANGUAGE":
val.Language = v
case "DEFAULT":
val.Default = v == "YES"
case "AUTOSELECT":
val.AutoSelect = v == "YES"
case "FORCED":
val.Forced = v == "YES"
case "URI":
val.URI = v
}
}
tag.Values = append(tag.Values, val)
return tag, nil
}
func (tag *ExtXMediaTag) SegmentTag() bool {
return false
}
func (tag *ExtXMediaTag) Encode() *bytes.Buffer {
b := bytes.NewBuffer(nil)
for i, val := range tag.Values {
if i != 0 {
b.WriteByte('\n')
}
b.WriteString(tag.TagName())
writeStringTagAttr(b, "TYPE", val.Type, false)
b.WriteRune(',')
writeStringTagAttr(b, "GROUP-ID", val.GroupID, true)
if val.Type == "AUDIO" {
b.WriteRune(',')
writeStringTagAttr(b, "CHANNELS", val.Channels, true)
}
b.WriteRune(',')
writeStringTagAttr(b, "NAME", val.Name, true)
b.WriteRune(',')
writeStringTagAttr(b, "LANGUAGE", val.Language, true)
b.WriteRune(',')
writeBoolTagAttr(b, "DEFAULT", val.Default)
b.WriteRune(',')
writeBoolTagAttr(b, "AUTOSELECT", val.AutoSelect)
if val.Type == "SUBTITLES" {
b.WriteRune(',')
writeBoolTagAttr(b, "FORCED", val.Forced)
}
b.WriteRune(',')
writeStringTagAttr(b, "URI", val.URI, true)
}
return b
}
func (tag *ExtXMediaTag) String() string {
return tag.Encode().String()
}
func writeStringTagAttr(b *bytes.Buffer, k string, v string, quote bool) {
b.WriteString(k)
b.WriteRune('=')
if quote {
b.WriteRune('"')
}
b.WriteString(v)
if quote {
b.WriteRune('"')
}
}
func writeBoolTagAttr(b *bytes.Buffer, k string, v bool) {
b.WriteString(k)
b.WriteRune('=')
if v {
b.WriteString("YES")
} else {
b.WriteString("NO")
}
}
For the master playlist below, the
MasterPlaylist
object (after decoding) is missing the audio stream withGROUP-ID="audio-aacl-128"
. That is,MasterPlaylist.Variants[9].VariantParams.Alternatives
isnil
.Also, only the first variant's
Alternatives
is populated, which I believe is this ticket: https://github.com/grafov/m3u8/issues/96. However, I can't work around this by accessing theaudio-aacl-128
stream using the first variant, because it specifiesAUDIO="audio-aacl-64"
.