commit 52ca0d40aee46b2fdb156b73c5c16509f3e3505e
parent 8b9dabb3f7e20b95c9d353d7cdc8deed50330b9f
Author: Oliver Lowe <o@olowe.co>
Date: Sat, 18 May 2024 21:26:07 +1000
m3u8: use scte35.SpliceInfo in the DateRange instead of raw bytes
This means we don't need to test whether encoding splices works;
that's already the responsibility of package scte35. Makes
documentation much clearer.
Diffstat:
3 files changed, 22 insertions(+), 27 deletions(-)
diff --git a/m3u8/m3u8.go b/m3u8/m3u8.go
@@ -6,6 +6,8 @@ import (
"fmt"
"strconv"
"time"
+
+ "github.com/untangledco/streaming/scte35"
)
type Playlist struct {
@@ -111,10 +113,14 @@ type DateRange struct {
Planned time.Duration
// value must be a string, float or hex sequence (int?)
Custom map[string]any
- CueCommand []byte
- CueIn []byte
- CueOut []byte
- EndOnNext bool
+ CueCommand *scte35.SpliceInfo
+ // Contains the first of the in/out cue pair. Command may be
+ // TimeSignal or Insert, with OutOfNetwork set to true.
+ CueOut *scte35.SpliceInfo
+ // Contains the second of the cue in/out pair. The Command's
+ // Type must match the "out" cue.
+ CueIn *scte35.SpliceInfo
+ EndOnNext bool
}
type PlaylistType uint8
diff --git a/m3u8/write.go b/m3u8/write.go
@@ -6,6 +6,8 @@ import (
"io"
"strings"
"time"
+
+ "github.com/untangledco/streaming/scte35"
)
func Encode(w io.Writer, p *Playlist) error {
@@ -52,10 +54,18 @@ func writeDateRange(w io.Writer, dr *DateRange) error {
// TODO(otl): dr.Custom.
// TODO(otl): dr.CueCommand, when to write this versuse cuein, cueout.
if dr.CueIn != nil {
- attrs = append(attrs, fmt.Sprintf("SCTE35-IN=0x%s", hex.EncodeToString(dr.CueIn)))
+ b, err := scte35.EncodeSpliceInfo(dr.CueIn)
+ if err != nil {
+ return fmt.Errorf("encode cue in: %w", err)
+ }
+ attrs = append(attrs, fmt.Sprintf("SCTE35-IN=0x%s", hex.EncodeToString(b)))
}
if dr.CueOut != nil {
- attrs = append(attrs, fmt.Sprintf("SCTE35-OUT=0x%s", hex.EncodeToString(dr.CueOut)))
+ b, err := scte35.EncodeSpliceInfo(dr.CueOut)
+ if err != nil {
+ return fmt.Errorf("encode cue out: %w", err)
+ }
+ attrs = append(attrs, fmt.Sprintf("SCTE35-OUT=0x%s", hex.EncodeToString(b)))
}
if dr.EndOnNext {
attrs = append(attrs, "END-ON-NEXT:YES")
diff --git a/m3u8/write_test.go b/m3u8/write_test.go
@@ -3,7 +3,6 @@ package m3u8
import (
"bufio"
"bytes"
- "encoding/base64"
"testing"
"time"
)
@@ -33,23 +32,3 @@ func TestEncodeSegDuration(t *testing.T) {
t.Errorf("no matching segment duration %s", want)
}
}
-
-func TestDateRange(t *testing.T) {
- // splice insert from SCTE 35 section 14.2
- out, err := base64.StdEncoding.DecodeString("/DAvAAAAAAAA///wFAVIAACPf+/+c2nALv4AUsz1AAAAAAAKAAhDVUVJAAABNWLbowo=")
- if err != nil {
- t.Fatal(err)
- }
- dr := DateRange{
- ID: "break",
- CueOut: out,
- }
- buf := &bytes.Buffer{}
- if err := writeDateRange(buf, &dr); err != nil {
- t.Fatalf("write date range: %v", err)
- }
- want := `#EXT-X-DATERANGE:ID="break",SCTE35-OUT=0xfc302f000000000000fffff014054800008f7feffe7369c02efe0052ccf500000000000a0008435545490000013562dba30a` + "\n"
- if buf.String() != want {
- t.Errorf("encode %v: got %s, want %s", dr, buf.String(), want)
- }
-}