streaming

Media streaming and broadcast systems in Go
Log | Files | Refs | README | LICENSE

commit 34d647b964d037705c244de67dc552c4ce4615ca
parent b80fe72bf0cda6e47989801e6e86bb43a03bb2d7
Author: Arthur D <a.dranchuk@setplex.com>
Date:   Thu, 21 Nov 2024 19:29:58 +0300

fix: play rate as decimal

Diffstat:
Mcmcd/cmcd.go | 17++++++++++++-----
Mcmcd/encode.go | 2+-
Mcmcd/parse.go | 9++-------
Mcmcd/parse_test.go | 10+++++-----
4 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/cmcd/cmcd.go b/cmcd/cmcd.go @@ -177,10 +177,8 @@ type Session struct { // A GUID uniquely identifying the session, no longer than 64 // characters. ID string - // Type of the stream. If false, all playback segments are - // available. Otherwise, the stream is considered live, and - // segments become available over time. - Live bool + // Type of the stream. + StreamType // A unique identifier of the client's requested content, no // longer than 64 characters. ContentID string @@ -191,7 +189,7 @@ type Session struct { version int } -type PlayRate uint8 +type PlayRate float32 const ( Stopped PlayRate = iota @@ -199,6 +197,15 @@ const ( DoubleTime ) +type StreamType string + +const ( + StreamTypeLive = "l" + StreamTypeVOD = "v" +) + +func (st StreamType) Live() bool { return st == StreamTypeLive } + type StreamFormat byte const ( diff --git a/cmcd/encode.go b/cmcd/encode.go @@ -74,7 +74,7 @@ func (s Session) Encode() string { } // "SHOULD only be sent if not equal to 1": CTA-5004 page 10. if s.PlayRate != RealTime { - attrs = append(attrs, fmt.Sprintf("pr=%d", s.PlayRate)) + attrs = append(attrs, fmt.Sprintf("pr=%v", s.PlayRate)) } switch s.Format { case FormatDASH, FormatHLS, FormatSmooth, FormatOther: diff --git a/cmcd/parse.go b/cmcd/parse.go @@ -132,21 +132,16 @@ func parseSession(attrs map[string]string) (Session, error) { ses.ID = strings.Trim(v, `"`) case "st": // TODO(otl): what if it's not "l"? - if v == "l" { - ses.Live = true - } + ses.StreamType = StreamType(v) case "cid": ses.ContentID = strings.Trim(v, `"`) case "pr": - i, err := strconv.Atoi(v) + i, err := strconv.ParseFloat(v, 32) if err != nil { return ses, fmt.Errorf("play rate: %w", err) } // TODO(otl): what is this max value? why? // Include in the error message. - if i > 2 { - return ses, fmt.Errorf("play rate: %d greater than max %d", i, 2) - } ses.PlayRate = PlayRate(i) case "sf": if len(v) != 1 { diff --git a/cmcd/parse_test.go b/cmcd/parse_test.go @@ -15,10 +15,10 @@ import ( ) var tests = map[string]Info{ - "testdata/simple": Info{ + "testdata/simple": { Session: Session{ID: "6e2fb550-c457-11e9-bb97-0800200c9a66", PlayRate: RealTime}, }, - "testdata/all_four": Info{ + "testdata/all_four": { Request: Request{Throughput: 25400}, Object: Object{ Bitrate: 3200, @@ -29,17 +29,17 @@ var tests = map[string]Info{ Status: Status{true, 15000}, Session: Session{ID: "6e2fb550-c457-11e9-bb97-0800200c9a66", PlayRate: RealTime}, }, - "testdata/booleans": Info{ + "testdata/booleans": { Status: Status{true, 0}, Request: Request{Startup: true}, Session: Session{PlayRate: RealTime}, }, - "testdata/range": Info{ + "testdata/range": { Request: Request{NextRange: [2]int{12323, 48763}}, Object: Object{Duration: 4004 * time.Millisecond}, Session: Session{PlayRate: RealTime}, }, - "testdata/custom": Info{ + "testdata/custom": { Object: Object{Duration: 4004 * time.Millisecond}, Session: Session{PlayRate: RealTime}, Custom: map[string]any{