Skip to content

Commit

Permalink
Split restream package and some bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
shaunschembri committed Jun 29, 2021
1 parent ea5cbbd commit a48c08e
Show file tree
Hide file tree
Showing 12 changed files with 350 additions and 307 deletions.
8 changes: 5 additions & 3 deletions pkg/restream/decrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"fmt"
"io"
"strings"

"github.com/shaunschembri/restreamer/pkg/restream/request"
)

type decrypter interface {
Expand All @@ -20,7 +22,7 @@ type aes128 struct {
iv string
keyURL string
bufferSize int
request request
request request.Request
mode cipher.BlockMode
}

Expand All @@ -29,9 +31,9 @@ func (a aes128) info() string {
}

func (a *aes128) init(ctx context.Context) error {
keyFileResponse, err := a.request.do(ctx, a.keyURL)
keyFileResponse, err := a.request.Do(ctx, a.keyURL)
if err != nil {
return err
return fmt.Errorf("request failed: %w", err)
}
defer keyFileResponse.Body.Close()

Expand Down
66 changes: 0 additions & 66 deletions pkg/restream/master.go

This file was deleted.

97 changes: 0 additions & 97 deletions pkg/restream/media.go

This file was deleted.

27 changes: 9 additions & 18 deletions pkg/restream/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package restream
import (
"context"
"io"
"time"

"github.com/shaunschembri/restreamer/pkg/restream/provider"
)

const (
Expand All @@ -17,30 +18,17 @@ type Restream struct {
UserAgent string
MaxBandwidth uint32
Writer io.Writer
SegmentProvider SegmentProvider
SegmentProvider provider.Provider
ReadBufferSize int
streamedBytes int64
currentBandwidth uint32
segments chan segment
segments chan provider.Segment
errors chan error
decrypter decrypter
}

type segment struct {
url string
keyMethod string
keyURL string
iv string
duration float64
}

type SegmentProvider interface {
Get(ctx context.Context, bandwidth uint32) ([]segment, time.Duration, error)
Info() string
}

func (r *Restream) init(ctx context.Context, playlistURL string) error {
r.segments = make(chan segment, 1024)
r.segments = make(chan provider.Segment, 1024)
r.errors = make(chan error, 1024)

if r.MaxBandwidth == 0 {
Expand All @@ -57,9 +45,12 @@ func (r *Restream) init(ctx context.Context, playlistURL string) error {
}

if r.SegmentProvider == nil {
if err := r.getSegmentProvider(ctx, playlistURL); err != nil {
segmentProvider, err := r.detectStream(ctx, playlistURL, r.UserAgent, r.MaxBandwidth)
if err != nil {
return err
}

r.SegmentProvider = segmentProvider
}

return nil
Expand Down
79 changes: 79 additions & 0 deletions pkg/restream/provider/hls/master.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package hls

import (
"context"
"fmt"
"time"

"github.com/grafov/m3u8"

"github.com/shaunschembri/restreamer/pkg/restream/provider"
"github.com/shaunschembri/restreamer/pkg/restream/request"
)

type Master struct {
media *Media
playlist *Playlist
resolution string
maxBandwidth uint32
variantBandwidth uint32
}

func NewMaster(request request.Request, maxBandwidth uint32) *Master {
return &Master{
media: NewMedia(request),
maxBandwidth: maxBandwidth,
}
}

func (m Master) WithPlaylist(playlist *Playlist) *Master {
m.playlist = playlist
return &m
}

func (m Master) Info() string {
infoStr := fmt.Sprintf("Master | Bandwidth: %3.1fMb/s", float32(m.variantBandwidth)/mbDivider)
if m.resolution != "" {
infoStr += fmt.Sprintf(" | Resolution: %s", m.resolution)
}

return infoStr
}

func (m *Master) Get(ctx context.Context, bandwidth uint32) ([]provider.Segment, time.Duration, error) {
if err := m.selectVariant(bandwidth); err != nil {
return nil, 0, err
}

return m.media.Get(ctx, bandwidth)
}

func (m *Master) selectVariant(streamSpeed uint32) error {
var targetVariant *m3u8.Variant
minDiff := streamSpeed

for _, variant := range m.playlist.playlist.(*m3u8.MasterPlaylist).Variants {
if variant.Bandwidth > m.maxBandwidth || variant.Bandwidth > streamSpeed {
continue
}

diff := streamSpeed - variant.Bandwidth
if diff >= minDiff && targetVariant != nil {
continue
}

minDiff = diff
targetVariant = variant
}

parsedURI, err := m.media.request.ResolveReference(targetVariant.URI, m.playlist.referenceURL)
if err != nil {
return fmt.Errorf("cannot resolve reference: %w", err)
}

m.media = m.media.WithPlaylistURL(parsedURI.String())
m.resolution = targetVariant.Resolution
m.variantBandwidth = targetVariant.Bandwidth

return nil
}
Loading

0 comments on commit a48c08e

Please sign in to comment.