Streams H.264 to the Galahad II LCD via USB (gousb) with: - ffmpeg CLI transcoding (no fragile FFmpeg C-ABI bindings) - pure-Go Annex-B access-unit splitting - framerate pacing with graceful shutdown and USB reconnect - TOML config, cobra CLI, structured slog logging, unit tests
67 lines
1.6 KiB
Go
67 lines
1.6 KiB
Go
// Package cli implements the galahad2lcd command-line interface.
|
|
package cli
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"os"
|
|
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// Execute runs the CLI and returns the first error encountered. The version
|
|
// is injected by the caller (typically main via -ldflags).
|
|
func Execute(version string) error {
|
|
root := newRootCmd(version)
|
|
return root.Execute()
|
|
}
|
|
|
|
func newRootCmd(version string) *cobra.Command {
|
|
var verbose bool
|
|
|
|
root := &cobra.Command{
|
|
Use: "galahad2lcd",
|
|
Short: "Driver for the Lian Li Galahad II LCD",
|
|
Long: `galahad2lcd streams H.264 video to the Lian Li Galahad II LCD
|
|
display over USB.`,
|
|
SilenceUsage: true,
|
|
SilenceErrors: true,
|
|
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
|
|
level := slog.LevelInfo
|
|
if verbose {
|
|
level = slog.LevelDebug
|
|
}
|
|
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: level})))
|
|
},
|
|
}
|
|
|
|
root.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "enable debug logging")
|
|
|
|
root.AddCommand(
|
|
newDaemonCmd(),
|
|
newSetCmd(),
|
|
newListCmd(),
|
|
newVersionCmd(version),
|
|
)
|
|
return root
|
|
}
|
|
|
|
func newVersionCmd(version string) *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "version",
|
|
Short: "Print the version and exit",
|
|
Args: cobra.NoArgs,
|
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
|
fmt.Fprintln(cmd.OutOrStdout(), version)
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
// signalContext returns a context cancelled on SIGINT and SIGTERM so that
|
|
// systemctl stop and Ctrl-C both trigger a clean shutdown.
|
|
func signalContext() (context.Context, context.CancelFunc) {
|
|
return newSignalContext()
|
|
}
|