Skip to content

Commit

Permalink
Merge pull request #6 from jwplayer/develop
Browse files Browse the repository at this point in the history
merge to main
  • Loading branch information
rogerpales authored Jul 17, 2023
2 parents 8e09125 + 10d72f3 commit 798cf52
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 0 deletions.
9 changes: 9 additions & 0 deletions reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,12 @@ func decodeLineOfMediaPlaylist(p *MediaPlaylist, wv *WV, state *decodingState, l
return err
}
}
if state.tagGap {
state.tagGap = false
if err = p.SetGap(); strict && err != nil {
return err
}
}
if state.tagProgramDateTime && p.Count() > 0 {
state.tagProgramDateTime = false
if err = p.SetProgramDateTime(state.programDateTime); strict && err != nil {
Expand Down Expand Up @@ -768,6 +774,9 @@ func decodeLineOfMediaPlaylist(p *MediaPlaylist, wv *WV, state *decodingState, l
case !state.tagDiscontinuity && strings.HasPrefix(line, "#EXT-X-DISCONTINUITY"):
state.tagDiscontinuity = true
state.listType = MEDIA
case !state.tagGap && strings.HasPrefix(line, "#EXT-X-GAP"):
state.tagGap = true
state.listType = MEDIA
case strings.HasPrefix(line, "#EXT-X-I-FRAMES-ONLY"):
state.listType = MEDIA
p.Iframe = true
Expand Down
24 changes: 24 additions & 0 deletions reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,30 @@ func TestDecodeMediaPlaylistWithCustomTags(t *testing.T) {
}
}

func TestDecodeMediaPlaylistWithGap(t *testing.T) {
f, err := os.Open("sample-playlists/media-playlist-with-gap.m3u8")
if err != nil {
t.Fatal(err)
}
p, listType, err := DecodeFrom(bufio.NewReader(f), true)
if err != nil {
t.Fatal(err)
}
pp := p.(*MediaPlaylist)
CheckType(t, pp)
if listType != MEDIA {
t.Error("Sample not recognized as media playlist.")
}
var seqId, idx uint
for seqId, idx = 0, 0; idx < pp.Count(); seqId, idx = seqId+1, idx+1 {
if pp.Segments[idx].Duration == 0 {
if !pp.Segments[idx].Gap {
t.Error("Expected Gap set to true on segment with duration 0.")
}
}
}
}

/***************************
* Code parsing examples *
***************************/
Expand Down
18 changes: 18 additions & 0 deletions sample-playlists/media-playlist-with-gap.m3u8
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
1.ts
#EXTINF:8.0,
2.ts
#EXT-X-GAP
#EXTINF:0.0, no desc
3.ts
#EXT-X-DISCONTINUITY
#EXTINF:10.0,
4.ts
#EXTINF:10.0,
5.ts
#EXTINF:10.0,
6.ts
2 changes: 2 additions & 0 deletions structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ type MediaSegment struct {
Key *Key // EXT-X-KEY displayed before the segment and means changing of encryption key (in theory each segment may have own key)
Map *Map // EXT-X-MAP displayed before the segment
Discontinuity bool // EXT-X-DISCONTINUITY indicates an encoding discontinuity between the media segment that follows it and the one that preceded it (i.e. file format, number and type of tracks, encoding parameters, encoding sequence, timestamp sequence)
Gap bool // EXT-X-GAP indicates that the segment URI to which it applies does not contain media data and SHOULD NOT be loaded by clients
DateRange []*DateRange // EXT-X-DATERANGE tags
SCTE *SCTE // SCTE-35 used for Ad signaling in HLS
ProgramDateTime time.Time // EXT-X-PROGRAM-DATE-TIME tag associates the first sample of a media segment with an absolute date and/or time
Expand Down Expand Up @@ -335,6 +336,7 @@ type decodingState struct {
tagSCTE35 bool
tagRange bool
tagDiscontinuity bool
tagGap bool
tagProgramDateTime bool
tagKey bool
tagMap bool
Expand Down
14 changes: 14 additions & 0 deletions writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,9 @@ func (p *MediaPlaylist) Encode() *bytes.Buffer {
if seg.Discontinuity {
p.buf.WriteString("#EXT-X-DISCONTINUITY\n")
}
if seg.Gap {
p.buf.WriteString("#EXT-X-GAP\n")
}
// ignore segment Map if default playlist Map is present
if p.Map == nil && seg.Map != nil {
p.buf.WriteString("#EXT-X-MAP:")
Expand Down Expand Up @@ -932,6 +935,17 @@ func (p *MediaPlaylist) SetDiscontinuity() error {
return nil
}

// SetGap sets gap flag for the current media
// segment. EXT-X-GAP indicates that the segment URI to which it applies
// does not contain media data and SHOULD NOT be loaded by clients/
func (p *MediaPlaylist) SetGap() error {
if p.count == 0 {
return errors.New("playlist is empty")
}
p.Segments[p.last()].Gap = true
return nil
}

// SetProgramDateTime sets program date and time for the current media
// segment. EXT-X-PROGRAM-DATE-TIME tag associates the first sample of
// a media segment with an absolute date and/or time. It applies only
Expand Down
34 changes: 34 additions & 0 deletions writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,40 @@ func TestEncodeMediaPlaylistDateRangeTags(t *testing.T) {
}
}

// Create new media playlist
// Add three segments to media playlist
// Set gap tag for the 2nd segment.
func TestGapForMediaPlaylist(t *testing.T) {
var e error
p, e := NewMediaPlaylist(3, 4)
if e != nil {
t.Fatalf("Create media playlist failed: %s", e)
}
p.Close()
if e = p.Append("test01.ts", 5.0, ""); e != nil {
t.Errorf("Add 1st segment to a media playlist failed: %s", e)
}
if e = p.Append("test02.ts", 0.0, ""); e != nil {
t.Errorf("Add 2nd segment to a media playlist failed: %s", e)
}
if e = p.SetGap(); e != nil {
t.Error("Can't set gap tag")
}
if e = p.Append("test03.ts", 6.0, ""); e != nil {
t.Errorf("Add 3nd segment to a media playlist failed: %s", e)
}
if e = p.SetDiscontinuity(); e != nil {
t.Error("Can't set discontinuity tag")
}
encoded := p.Encode().String()
expectedStrings := []string{"#EXT-X-GAP"}
for _, expected := range expectedStrings {
if !strings.Contains(encoded, expected) {
t.Fatalf("Media playlist does not contain tag: %s\nMedia Playlist:\n%v", expected, encoded)
}
}
}

/******************************
* Code generation examples *
******************************/
Expand Down

0 comments on commit 798cf52

Please sign in to comment.