Refactoring #3
@@ -53,6 +53,7 @@ type appArgs struct {
|
|||||||
ListGPU bool
|
ListGPU bool
|
||||||
SyncRequested bool
|
SyncRequested bool
|
||||||
MaxAttempts int
|
MaxAttempts int
|
||||||
|
PlaylistPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
func printCliHelp(fs *pflag.FlagSet) {
|
func printCliHelp(fs *pflag.FlagSet) {
|
||||||
@@ -129,6 +130,12 @@ func main() {
|
|||||||
0,
|
0,
|
||||||
"Maximum connection attempts per playback lifecycle; 0 retries indefinitely",
|
"Maximum connection attempts per playback lifecycle; 0 retries indefinitely",
|
||||||
)
|
)
|
||||||
|
flagSet.StringVar(
|
||||||
|
&args.PlaylistPath,
|
||||||
|
"playlist",
|
||||||
|
"",
|
||||||
|
"Load playlist from a JSON file",
|
||||||
|
)
|
||||||
flagSet.BoolVarP(&args.IsFullscreen, "fullscreen", "f", false, "Run app in fullscreen mode")
|
flagSet.BoolVarP(&args.IsFullscreen, "fullscreen", "f", false, "Run app in fullscreen mode")
|
||||||
flagSet.Uint32VarP(&args.GpuId, "gpu-id", "g", 0, "GPU id [TODO]")
|
flagSet.Uint32VarP(&args.GpuId, "gpu-id", "g", 0, "GPU id [TODO]")
|
||||||
flagSet.Uint32VarP(&args.PlaybackId, "playback-id", "p", 0, "Playback audio device id")
|
flagSet.Uint32VarP(&args.PlaybackId, "playback-id", "p", 0, "Playback audio device id")
|
||||||
@@ -159,6 +166,16 @@ func main() {
|
|||||||
fmt.Fprintln(os.Stderr, "invalid retry configuration:", err)
|
fmt.Fprintln(os.Stderr, "invalid retry configuration:", err)
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
configuredPlaylist := playback.Playlist{}
|
||||||
|
hasPlaylist := args.PlaylistPath != ""
|
||||||
|
if hasPlaylist {
|
||||||
|
playlist, err := loadPlaylistFile(args.PlaylistPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
os.Exit(2)
|
||||||
|
}
|
||||||
|
configuredPlaylist = playlist
|
||||||
|
}
|
||||||
if args.VideoDomain == "" {
|
if args.VideoDomain == "" {
|
||||||
args.VideoDomain = args.Domain
|
args.VideoDomain = args.Domain
|
||||||
}
|
}
|
||||||
@@ -415,6 +432,28 @@ func main() {
|
|||||||
)
|
)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
var playlistRuntime *playerPlaylist
|
||||||
|
var playlistDone chan error
|
||||||
|
if hasPlaylist {
|
||||||
|
playlistRuntime, err = newPlayerPlaylist(
|
||||||
|
configuredPlaylist,
|
||||||
|
retryPolicy,
|
||||||
|
player,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
playlistDone = make(chan error, 1)
|
||||||
|
go func() {
|
||||||
|
playlistDone <- playlistRuntime.Run(ctx)
|
||||||
|
}()
|
||||||
|
|
||||||
|
if shouldAutoStartPlaylist(args, configuredPlaylist) &&
|
||||||
|
!playlistRuntime.Select(0) {
|
||||||
|
log.Print("playlist command queue is full")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
running := true
|
running := true
|
||||||
resized := false
|
resized := false
|
||||||
fullscreen := args.IsFullscreen
|
fullscreen := args.IsFullscreen
|
||||||
@@ -774,6 +813,11 @@ func main() {
|
|||||||
if err := <-playbackDone; err != nil && !errors.Is(err, context.Canceled) {
|
if err := <-playbackDone; err != nil && !errors.Is(err, context.Canceled) {
|
||||||
log.Printf("playback controller: %v", err)
|
log.Printf("playback controller: %v", err)
|
||||||
}
|
}
|
||||||
|
if playlistDone != nil {
|
||||||
|
if err := <-playlistDone; err != nil && !errors.Is(err, context.Canceled) {
|
||||||
|
log.Printf("playlist runtime: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
if err := player.Close(); err != nil {
|
if err := player.Close(); err != nil {
|
||||||
log.Printf("close playback: %v", err)
|
log.Printf("close playback: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,3 +125,13 @@ func playlistRuntimeError(err error) error {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func shouldAutoStartPlaylist(
|
||||||
|
args appArgs,
|
||||||
|
playlist playback.Playlist,
|
||||||
|
) bool {
|
||||||
|
return args.PlaylistPath != "" &&
|
||||||
|
args.VideoFlowId == "" &&
|
||||||
|
args.AudioFlowId == "" &&
|
||||||
|
len(playlist.Entries) > 0
|
||||||
|
}
|
||||||
|
|||||||
@@ -242,6 +242,62 @@ func TestPlayerPlaylistTimedEntryAdvances(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestShouldAutoStartPlaylist(t *testing.T) {
|
||||||
|
playlist := playback.Playlist{Entries: []playback.PlaylistEntry{
|
||||||
|
{Video: playback.PlaylistFeed{Domain: "domain", UUID: "video"}},
|
||||||
|
}}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args appArgs
|
||||||
|
playlist playback.Playlist
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "playlist only",
|
||||||
|
args: appArgs{PlaylistPath: "playlist.json"},
|
||||||
|
playlist: playlist,
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "direct video",
|
||||||
|
args: appArgs{PlaylistPath: "playlist.json", VideoFlowId: "video"},
|
||||||
|
playlist: playlist,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "direct audio",
|
||||||
|
args: appArgs{PlaylistPath: "playlist.json", AudioFlowId: "audio"},
|
||||||
|
playlist: playlist,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "both direct feeds",
|
||||||
|
args: appArgs{
|
||||||
|
PlaylistPath: "playlist.json",
|
||||||
|
VideoFlowId: "video",
|
||||||
|
AudioFlowId: "audio",
|
||||||
|
},
|
||||||
|
playlist: playlist,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty playlist",
|
||||||
|
args: appArgs{PlaylistPath: "playlist.json"},
|
||||||
|
playlist: playback.Playlist{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no playlist flag",
|
||||||
|
args: appArgs{},
|
||||||
|
playlist: playlist,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
if got := shouldAutoStartPlaylist(test.args, test.playlist); got != test.want {
|
||||||
|
t.Fatalf("shouldAutoStartPlaylist() = %v, want %v", got, test.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newPlaylistTestPlayer(t *testing.T) *playerPlayback {
|
func newPlaylistTestPlayer(t *testing.T) *playerPlayback {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
return &playerPlayback{
|
return &playerPlayback{
|
||||||
|
|||||||
Reference in New Issue
Block a user