playback composition object
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
mxladapter "mxl-player/internal/adapter/mxl"
|
||||
"mxl-player/internal/output"
|
||||
"mxl-player/internal/playback"
|
||||
)
|
||||
|
||||
type playerPlayback struct {
|
||||
Controller *playback.SessionController
|
||||
Commands chan playback.SessionCommand
|
||||
Video *playback.VideoBridge
|
||||
Status *playback.StatusStore
|
||||
Audio *output.SDLAudioSink
|
||||
}
|
||||
|
||||
func newPlayerPlayback(
|
||||
audioDevice uint32,
|
||||
retry playback.RetryPolicy,
|
||||
) (*playerPlayback, error) {
|
||||
videoBridge := playback.NewVideoBridge()
|
||||
statusStore := playback.NewStatusStore()
|
||||
audioSink := output.NewSDLAudioSink(audioDevice)
|
||||
|
||||
observe := func(status playback.Status) {
|
||||
statusStore.Observe(status)
|
||||
|
||||
if status.Err != nil {
|
||||
log.Printf(
|
||||
"%s: state=%v attempt=%d failed=%d: %v",
|
||||
status.Unit,
|
||||
status.State,
|
||||
status.Attempt,
|
||||
status.FailedAttempts,
|
||||
status.Err,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf(
|
||||
"%s: state=%v attempt=%d failed=%d",
|
||||
status.Unit,
|
||||
status.State,
|
||||
status.Attempt,
|
||||
status.FailedAttempts,
|
||||
)
|
||||
}
|
||||
|
||||
videoWorker, err := playback.NewVideoWorker(
|
||||
mxladapter.VideoFactory{},
|
||||
videoBridge,
|
||||
retry,
|
||||
mxladapter.ShouldRetry,
|
||||
observe,
|
||||
)
|
||||
if err != nil {
|
||||
_ = audioSink.Close()
|
||||
return nil, err
|
||||
}
|
||||
videoSlot, err := playback.NewVideoSlot(videoWorker)
|
||||
if err != nil {
|
||||
_ = audioSink.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
audioWorker, err := playback.NewAudioWorker(
|
||||
mxladapter.AudioFactory{},
|
||||
audioSink,
|
||||
retry,
|
||||
mxladapter.ShouldRetry,
|
||||
observe,
|
||||
)
|
||||
if err != nil {
|
||||
_ = audioSink.Close()
|
||||
return nil, err
|
||||
}
|
||||
audioSlot, err := playback.NewAudioSlot(audioWorker)
|
||||
if err != nil {
|
||||
_ = audioSink.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
syncWorker, err := playback.NewSyncWorker(
|
||||
mxladapter.SyncFactory{},
|
||||
videoBridge,
|
||||
audioSink,
|
||||
retry,
|
||||
mxladapter.ShouldRetry,
|
||||
observe,
|
||||
)
|
||||
if err != nil {
|
||||
_ = audioSink.Close()
|
||||
return nil, err
|
||||
}
|
||||
syncSlot, err := playback.NewSyncSlot(syncWorker)
|
||||
if err != nil {
|
||||
_ = audioSink.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
controller, err := playback.NewSessionController(
|
||||
videoSlot,
|
||||
audioSlot,
|
||||
syncSlot,
|
||||
func(video, audio playback.FeedConfig) bool {
|
||||
return video.Domain == audio.Domain
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
_ = audioSink.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &playerPlayback{
|
||||
Controller: controller,
|
||||
Commands: make(chan playback.SessionCommand, 32),
|
||||
Video: videoBridge,
|
||||
Status: statusStore,
|
||||
Audio: audioSink,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *playerPlayback) Close() error {
|
||||
return p.Audio.Close()
|
||||
}
|
||||
Reference in New Issue
Block a user