From c29336f40a41c9f10d5074076a7ce489a0448c48 Mon Sep 17 00:00:00 2001 From: Bradley Falzon Date: Mon, 10 Apr 2017 15:35:40 +1000 Subject: [PATCH] Remove breaking changes from previous SCTE-35 modifications --- reader.go | 8 ++++---- reader_test.go | 24 ++++++++++++------------ structure.go | 15 +++++++-------- writer.go | 32 ++++++++++++++++---------------- writer_test.go | 6 +++--- 5 files changed, 42 insertions(+), 43 deletions(-) diff --git a/reader.go b/reader.go index 20303f9f..cabe0a85 100644 --- a/reader.go +++ b/reader.go @@ -523,7 +523,7 @@ func decodeLineOfMediaPlaylist(p *MediaPlaylist, wv *WV, state *decodingState, l case !state.tagSCTE35 && strings.HasPrefix(line, "#EXT-SCTE35:"): state.tagSCTE35 = true state.listType = MEDIA - state.scte = new(SCTE35) + state.scte = new(SCTE) state.scte.Syntax = SCTE35_67_2014 for attribute, value := range decodeParamsLine(line[12:]) { switch attribute { @@ -538,7 +538,7 @@ func decodeLineOfMediaPlaylist(p *MediaPlaylist, wv *WV, state *decodingState, l case !state.tagSCTE35 && strings.HasPrefix(line, "#EXT-OATCLS-SCTE35:"): // EXT-OATCLS-SCTE35 contains the SCTE35 tag, EXT-X-CUE-OUT contains duration state.tagSCTE35 = true - state.scte = new(SCTE35) + state.scte = new(SCTE) state.scte.Syntax = SCTE35_OATCLS state.scte.Cue = line[19:] case state.tagSCTE35 && state.scte.Syntax == SCTE35_OATCLS && strings.HasPrefix(line, "#EXT-X-CUE-OUT:"): @@ -547,7 +547,7 @@ func decodeLineOfMediaPlaylist(p *MediaPlaylist, wv *WV, state *decodingState, l state.scte.CueType = SCTE35Cue_Start case !state.tagSCTE35 && strings.HasPrefix(line, "#EXT-X-CUE-OUT-CONT:"): state.tagSCTE35 = true - state.scte = new(SCTE35) + state.scte = new(SCTE) state.scte.Syntax = SCTE35_OATCLS state.scte.CueType = SCTE35Cue_Mid for attribute, value := range decodeParamsLine(line[20:]) { @@ -562,7 +562,7 @@ func decodeLineOfMediaPlaylist(p *MediaPlaylist, wv *WV, state *decodingState, l } case !state.tagSCTE35 && line == "#EXT-X-CUE-IN": state.tagSCTE35 = true - state.scte = new(SCTE35) + state.scte = new(SCTE) state.scte.Syntax = SCTE35_OATCLS state.scte.CueType = SCTE35Cue_End case !state.tagDiscontinuity && strings.HasPrefix(line, "#EXT-X-DISCONTINUITY"): diff --git a/reader_test.go b/reader_test.go index e1aff364..867bdd87 100644 --- a/reader_test.go +++ b/reader_test.go @@ -380,15 +380,15 @@ func TestMediaPlaylistWithOATCLSSCTE35Tag(t *testing.T) { } pp := p.(*MediaPlaylist) - expect := map[int]*SCTE35{ + expect := map[int]*SCTE{ 0: {Syntax: SCTE35_OATCLS, CueType: SCTE35Cue_Start, Cue: "/DAlAAAAAAAAAP/wFAUAAAABf+/+ANgNkv4AFJlwAAEBAQAA5xULLA==", Time: 15}, 1: {Syntax: SCTE35_OATCLS, CueType: SCTE35Cue_Mid, Cue: "/DAlAAAAAAAAAP/wFAUAAAABf+/+ANgNkv4AFJlwAAEBAQAA5xULLA==", Time: 15, Elapsed: 8.844}, 2: {Syntax: SCTE35_OATCLS, CueType: SCTE35Cue_End}, } for i := 0; i < int(pp.Count()); i++ { - if !reflect.DeepEqual(pp.Segments[i].SCTE35, expect[i]) { + if !reflect.DeepEqual(pp.Segments[i].SCTE, expect[i]) { t.Errorf("OATCLS SCTE35 segment %v (uri: %v)\ngot: %#v\nexp: %#v", - i, pp.Segments[i].URI, pp.Segments[i].SCTE35, expect[i], + i, pp.Segments[i].URI, pp.Segments[i].SCTE, expect[i], ) } } @@ -453,17 +453,17 @@ func TestMediaPlaylistWithSCTE35Tag(t *testing.T) { if item == nil { break } - if index != c.expectedSCTEIndex && item.SCTE35 != nil { + if index != c.expectedSCTEIndex && item.SCTE != nil { t.Error("Not expecting SCTE information on this segment") - } else if index == c.expectedSCTEIndex && item.SCTE35 == nil { + } else if index == c.expectedSCTEIndex && item.SCTE == nil { t.Error("Expecting SCTE information on this segment") - } else if index == c.expectedSCTEIndex && item.SCTE35 != nil { - if (*item.SCTE35).Cue != c.expectedSCTECue { - t.Error("Expected ", c.expectedSCTECue, " got ", (*item.SCTE35).Cue) - } else if (*item.SCTE35).ID != c.expectedSCTEID { - t.Error("Expected ", c.expectedSCTEID, " got ", (*item.SCTE35).ID) - } else if (*item.SCTE35).Time != c.expectedSCTETime { - t.Error("Expected ", c.expectedSCTETime, " got ", (*item.SCTE35).Time) + } else if index == c.expectedSCTEIndex && item.SCTE != nil { + if (*item.SCTE).Cue != c.expectedSCTECue { + t.Error("Expected ", c.expectedSCTECue, " got ", (*item.SCTE).Cue) + } else if (*item.SCTE).ID != c.expectedSCTEID { + t.Error("Expected ", c.expectedSCTEID, " got ", (*item.SCTE).ID) + } else if (*item.SCTE).Time != c.expectedSCTETime { + t.Error("Expected ", c.expectedSCTETime, " got ", (*item.SCTE).Time) } } } diff --git a/structure.go b/structure.go index e862362b..b442cdec 100644 --- a/structure.go +++ b/structure.go @@ -58,10 +58,9 @@ const ( type SCTE35Syntax uint const ( - // 0 is reserved for draft-pantos-http-live-streaming-19 *if* its decided to - // be implemented via this api (instead of via a EXT-X-DATERANGE specific api) - SCTE35_67_2014 SCTE35Syntax = iota + 1 // SCTE35_67_2014 defined in http://www.scte.org/documents/pdf/standards/SCTE%2067%202014.pdf - SCTE35_OATCLS // SCTE35_OATCLS is a non-standard but common format + // SCTE35_67_2014 will be the default due to backwards compatibility reasons. + SCTE35_67_2014 SCTE35Syntax = iota // SCTE35_67_2014 defined in http://www.scte.org/documents/pdf/standards/SCTE%2067%202014.pdf + SCTE35_OATCLS // SCTE35_OATCLS is a non-standard but common format ) // SCTE35CueType defines the type of cue point, used by readers and writers to @@ -198,12 +197,12 @@ 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) - SCTE35 *SCTE35 // SCTE-35 used for Ad signaling in HLS + 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 } -// SCTE35 holds custom, non EXT-X-DATERANGE, SCTE-35 tags -type SCTE35 struct { +// SCTE holds custom, non EXT-X-DATERANGE, SCTE-35 tags +type SCTE struct { Syntax SCTE35Syntax // Syntax defines the format of the SCTE-35 cue tag CueType SCTE35CueType // CueType defines whether the cue is a start, mid, end (if applicable) Cue string @@ -287,5 +286,5 @@ type decodingState struct { alternatives []*Alternative xkey *Key xmap *Map - scte *SCTE35 + scte *SCTE } diff --git a/writer.go b/writer.go index 137ff0a1..744d35b2 100644 --- a/writer.go +++ b/writer.go @@ -478,40 +478,40 @@ func (p *MediaPlaylist) Encode() *bytes.Buffer { if p.winsize > 0 { // skip for VOD playlists, where winsize = 0 i++ } - if seg.SCTE35 != nil { - switch seg.SCTE35.Syntax { + if seg.SCTE != nil { + switch seg.SCTE.Syntax { case SCTE35_67_2014: p.buf.WriteString("#EXT-SCTE35:") p.buf.WriteString("CUE=\"") - p.buf.WriteString(seg.SCTE35.Cue) + p.buf.WriteString(seg.SCTE.Cue) p.buf.WriteRune('"') - if seg.SCTE35.ID != "" { + if seg.SCTE.ID != "" { p.buf.WriteString(",ID=\"") - p.buf.WriteString(seg.SCTE35.ID) + p.buf.WriteString(seg.SCTE.ID) p.buf.WriteRune('"') } - if seg.SCTE35.Time != 0 { + if seg.SCTE.Time != 0 { p.buf.WriteString(",TIME=") - p.buf.WriteString(strconv.FormatFloat(seg.SCTE35.Time, 'f', -1, 64)) + p.buf.WriteString(strconv.FormatFloat(seg.SCTE.Time, 'f', -1, 64)) } p.buf.WriteRune('\n') case SCTE35_OATCLS: - switch seg.SCTE35.CueType { + switch seg.SCTE.CueType { case SCTE35Cue_Start: p.buf.WriteString("#EXT-OATCLS-SCTE35:") - p.buf.WriteString(seg.SCTE35.Cue) + p.buf.WriteString(seg.SCTE.Cue) p.buf.WriteRune('\n') p.buf.WriteString("#EXT-X-CUE-OUT:") - p.buf.WriteString(strconv.FormatFloat(seg.SCTE35.Time, 'f', -1, 64)) + p.buf.WriteString(strconv.FormatFloat(seg.SCTE.Time, 'f', -1, 64)) p.buf.WriteRune('\n') case SCTE35Cue_Mid: p.buf.WriteString("#EXT-X-CUE-OUT-CONT:") p.buf.WriteString("ElapsedTime=") - p.buf.WriteString(strconv.FormatFloat(seg.SCTE35.Elapsed, 'f', -1, 64)) + p.buf.WriteString(strconv.FormatFloat(seg.SCTE.Elapsed, 'f', -1, 64)) p.buf.WriteString(",Duration=") - p.buf.WriteString(strconv.FormatFloat(seg.SCTE35.Time, 'f', -1, 64)) + p.buf.WriteString(strconv.FormatFloat(seg.SCTE.Time, 'f', -1, 64)) p.buf.WriteString(",SCTE35=") - p.buf.WriteString(seg.SCTE35.Cue) + p.buf.WriteString(seg.SCTE.Cue) p.buf.WriteRune('\n') case SCTE35Cue_End: p.buf.WriteString("#EXT-X-CUE-IN") @@ -685,17 +685,17 @@ func (p *MediaPlaylist) SetRange(limit, offset int64) error { } // SetSCTE35 sets the SCTE cue format for the current media segment -func (p *MediaPlaylist) SetSCTE35(scte35 *SCTE35) error { +func (p *MediaPlaylist) SetSCTE35(scte35 *SCTE) error { if p.count == 0 { return errors.New("playlist is empty") } - p.Segments[p.last()].SCTE35 = scte35 + p.Segments[p.last()].SCTE = scte35 return nil } // SetSCTE is deprecated, use SetSCTE35 func (p *MediaPlaylist) SetSCTE(cue string, id string, time float64) error { - return p.SetSCTE35(&SCTE35{Syntax: SCTE35_67_2014, Cue: cue, ID: id, Time: time}) + return p.SetSCTE35(&SCTE{Syntax: SCTE35_67_2014, Cue: cue, ID: id, Time: time}) } // Set discontinuity flag for the current media segment. diff --git a/writer_test.go b/writer_test.go index f8b7e0ff..b2d69f3d 100644 --- a/writer_test.go +++ b/writer_test.go @@ -189,7 +189,7 @@ func TestOverAddSegmentsToMediaPlaylist(t *testing.T) { func TestSetSCTE35(t *testing.T) { p, _ := NewMediaPlaylist(1, 2) - scte := &SCTE35{Cue: "some cue"} + scte := &SCTE{Cue: "some cue"} if err := p.SetSCTE35(scte); err == nil { t.Error("SetSCTE35 expected empty playlist error") } @@ -197,8 +197,8 @@ func TestSetSCTE35(t *testing.T) { if err := p.SetSCTE35(scte); err != nil { t.Errorf("SetSCTE35 did not expect error: %v", err) } - if !reflect.DeepEqual(p.Segments[0].SCTE35, scte) { - t.Errorf("SetSCTE35\nexp: %#v\ngot: %#v", scte, p.Segments[0].SCTE35) + if !reflect.DeepEqual(p.Segments[0].SCTE, scte) { + t.Errorf("SetSCTE35\nexp: %#v\ngot: %#v", scte, p.Segments[0].SCTE) } }