Skip to content

Commit

Permalink
Append all matching alternatives to variant
Browse files Browse the repository at this point in the history
  • Loading branch information
markniebur committed Jan 6, 2022
1 parent 2ce07e6 commit b722502
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 24 deletions.
50 changes: 41 additions & 9 deletions reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,24 @@ func (p *MasterPlaylist) decode(buf *bytes.Buffer, strict bool) error {
if strict && !state.m3u {
return errors.New("#EXTM3U absent")
}
if len(state.alternatives) > 0 {
for _, variant := range p.Variants {
// enumerate ext-x-media types
if val, ok := state.alternatives["AUDIO"+variant.Audio]; ok {
variant.Alternatives = append(variant.Alternatives, val...)
}
if val, ok := state.alternatives["VIDEO"+variant.Video]; ok {
variant.Alternatives = append(variant.Alternatives, val...)
}
if val, ok := state.alternatives["SUBTITLES"+variant.Subtitles]; ok {
variant.Alternatives = append(variant.Alternatives, val...)
}
if val, ok := state.alternatives["CLOSED-CAPTIONS"+variant.Captions]; ok {
variant.Alternatives = append(variant.Alternatives, val...)
}
}
}

return nil
}

Expand Down Expand Up @@ -238,6 +256,24 @@ func decode(buf *bytes.Buffer, strict bool, customDecoders []CustomDecoder) (Pla
return nil, listType, errors.New("#EXTM3U absent")
}

if state.listType == MASTER && len(state.alternatives) > 0 {
for _, variant := range master.Variants {
// enumerate ext-x-media types
if val, ok := state.alternatives["AUDIO"+variant.Audio]; ok {
variant.Alternatives = append(variant.Alternatives, val...)
}
if val, ok := state.alternatives["VIDEO"+variant.Video]; ok {
variant.Alternatives = append(variant.Alternatives, val...)
}
if val, ok := state.alternatives["SUBTITLES"+variant.Subtitles]; ok {
variant.Alternatives = append(variant.Alternatives, val...)
}
if val, ok := state.alternatives["CLOSED-CAPTIONS"+variant.Captions]; ok {
variant.Alternatives = append(variant.Alternatives, val...)
}
}
}

switch state.listType {
case MASTER:
return master, MASTER, nil
Expand Down Expand Up @@ -301,6 +337,9 @@ func decodeLineOfMasterPlaylist(p *MasterPlaylist, state *decodingState, line st
case strings.HasPrefix(line, "#EXT-X-MEDIA:"):
var alt Alternative
state.listType = MASTER
if state.alternatives == nil {
state.alternatives = make(map[string][]*Alternative)
}
for k, v := range decodeParamsLine(line[13:]) {
switch k {
case "TYPE":
Expand Down Expand Up @@ -331,15 +370,12 @@ func decodeLineOfMasterPlaylist(p *MasterPlaylist, state *decodingState, line st
alt.URI = v
}
}
state.alternatives = append(state.alternatives, &alt)
// create hash out of type + group id
state.alternatives[alt.Type+alt.GroupId] = append(state.alternatives[alt.Type+alt.GroupId], &alt)
case !state.tagStreamInf && strings.HasPrefix(line, "#EXT-X-STREAM-INF:"):
state.tagStreamInf = true
state.listType = MASTER
state.variant = new(Variant)
if len(state.alternatives) > 0 {
state.variant.Alternatives = state.alternatives
state.alternatives = nil
}
p.Variants = append(p.Variants, state.variant)
for k, v := range decodeParamsLine(line[18:]) {
switch k {
Expand Down Expand Up @@ -395,10 +431,6 @@ func decodeLineOfMasterPlaylist(p *MasterPlaylist, state *decodingState, line st
state.listType = MASTER
state.variant = new(Variant)
state.variant.Iframe = true
if len(state.alternatives) > 0 {
state.variant.Alternatives = state.alternatives
state.alternatives = nil
}
p.Variants = append(p.Variants, state.variant)
for k, v := range decodeParamsLine(line[26:]) {
switch k {
Expand Down
16 changes: 8 additions & 8 deletions reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,17 @@ func TestDecodeMasterPlaylistWithAlternatives(t *testing.T) {
}
// TODO check other values
for i, v := range p.Variants {
if i == 0 && len(v.Alternatives) != 3 {
t.Fatalf("not all alternatives from #EXT-X-MEDIA parsed (has %d but should be 3", len(v.Alternatives))
if i == 0 && len(v.Alternatives) != 6 {
t.Fatalf("not all alternatives from #EXT-X-MEDIA parsed (has %d but should be 6", len(v.Alternatives))
}
if i == 1 && len(v.Alternatives) != 3 {
t.Fatalf("not all alternatives from #EXT-X-MEDIA parsed (has %d but should be 3", len(v.Alternatives))
if i == 1 && len(v.Alternatives) != 6 {
t.Fatalf("not all alternatives from #EXT-X-MEDIA parsed (has %d but should be 6", len(v.Alternatives))
}
if i == 2 && len(v.Alternatives) != 3 {
t.Fatalf("not all alternatives from #EXT-X-MEDIA parsed (has %d but should be 3", len(v.Alternatives))
if i == 2 && len(v.Alternatives) != 6 {
t.Fatalf("not all alternatives from #EXT-X-MEDIA parsed (has %d but should be 6", len(v.Alternatives))
}
if i == 3 && len(v.Alternatives) > 0 {
t.Fatal("should not be alternatives for this variant")
if i == 3 && len(v.Alternatives) != 3 {
t.Fatalf("not all alternatives from #EXT-X-MEDIA parsed (has %d but should be 3", len(v.Alternatives))
}
}
// fmt.Println(p.Encode().String())
Expand Down
17 changes: 11 additions & 6 deletions sample-playlists/master-with-alternatives.m3u8
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Main",DEFAULT=YES,URI="low/main/audio-video.m3u8"
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Centerfield",DEFAULT=NO,URI="low/centerfield/audio-video.m3u8"
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Dugout",DEFAULT=NO,URI="low/dugout/audio-video.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=1280000,VIDEO="low"
low/main/audio-video.m3u8
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="mid",NAME="Main",DEFAULT=YES,URI="mid/main/audio-video.m3u8"
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="mid",NAME="Centerfield",DEFAULT=NO,URI="mid/centerfield/audio-video.m3u8"
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="mid",NAME="Dugout",DEFAULT=NO,URI="mid/dugout/audio-video.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=2560000,VIDEO="mid"
mid/main/audio-video.m3u8
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="hi",NAME="Main",DEFAULT=YES,URI="hi/main/audio-video.m3u8"
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="hi",NAME="Centerfield",DEFAULT=NO,URI="hi/centerfield/audio-video.m3u8"
#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="hi",NAME="Dugout",DEFAULT=NO,URI="hi/dugout/audio-video.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=7680000,VIDEO="hi"

#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",NAME="English",LANGUAGE="en",DEFAULT=YES,AUTOSELECT=YES
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",NAME="Spanish",LANGUAGE="es",DEFAULT=NO,AUTOSELECT=YES,URI="main/spa.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",NAME="French",LANGUAGE="fr",DEFAULT=NO,AUTOSELECT=YES,URI="main/fra.m3u8"

#EXT-X-STREAM-INF:BANDWIDTH=1280000,VIDEO="low",AUDIO="audio"
low/main/audio-video.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2560000,VIDEO="mid",AUDIO="audio"
mid/main/audio-video.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=7680000,VIDEO="hi",AUDIO="audio"
hi/main/audio-video.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=65000,CODECS="mp4a.40.5"
#EXT-X-STREAM-INF:BANDWIDTH=65000,CODECS="mp4a.40.5",AUDIO="audio"
main/audio-only.m3u8
2 changes: 1 addition & 1 deletion structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ type decodingState struct {
duration float64
title string
variant *Variant
alternatives []*Alternative
alternatives map[string][]*Alternative
xkey *Key
xmap *Map
scte *SCTE
Expand Down

0 comments on commit b722502

Please sign in to comment.