Skip to content
This repository has been archived by the owner on Dec 8, 2024. It is now read-only.

Commit

Permalink
Remove breaking changes from previous SCTE-35 modifications
Browse files Browse the repository at this point in the history
  • Loading branch information
Bradley Falzon committed Apr 10, 2017
1 parent 7837bac commit c29336f
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 43 deletions.
8 changes: 4 additions & 4 deletions reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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:"):
Expand All @@ -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:]) {
Expand All @@ -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"):
Expand Down
24 changes: 12 additions & 12 deletions reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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],
)
}
}
Expand Down Expand Up @@ -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)
}
}
}
Expand Down
15 changes: 7 additions & 8 deletions structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -287,5 +286,5 @@ type decodingState struct {
alternatives []*Alternative
xkey *Key
xmap *Map
scte *SCTE35
scte *SCTE
}
32 changes: 16 additions & 16 deletions writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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.
Expand Down
6 changes: 3 additions & 3 deletions writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,16 +189,16 @@ 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")
}
_ = p.Append("test01.ts", 10.0, "title")
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)
}
}

Expand Down

0 comments on commit c29336f

Please sign in to comment.