//go:build gstreamer package player import ( "fmt" "time" "git.leaktechnologies.dev/stu/VideoTools/internal/logging" ) // newController creates a GStreamer-based controller for embedded video playback func newController() Controller { config := Config{ Backend: BackendAuto, WindowWidth: 640, WindowHeight: 360, Volume: 1.0, Muted: false, AutoPlay: false, HardwareAccel: false, PreviewMode: false, // Full playback mode AudioOutput: "auto", VideoOutput: "rgb24", CacheEnabled: true, CacheSize: 64 * 1024 * 1024, LogLevel: LogInfo, } player, err := NewGStreamerPlayer(config) if err != nil { logging.Error(logging.CatPlayer, "Failed to create GStreamer player: %v", err) return &stubController{} } logging.Info(logging.CatPlayer, "GStreamer controller initialized (GStreamer %s)", "1.26+") return &gstreamerController{ player: player, } } // gstreamerController wraps GStreamerPlayer to implement the Controller interface type gstreamerController struct { player *GStreamerPlayer } func (c *gstreamerController) Load(path string, offset float64) error { if c.player == nil { return fmt.Errorf("GStreamer player not initialized") } offsetDuration := time.Duration(offset * float64(time.Second)) logging.Debug(logging.CatPlayer, "Loading video: path=%s offset=%.3fs", path, offset) return c.player.Load(path, offsetDuration) } func (c *gstreamerController) SetWindow(x, y, w, h int) { if c.player == nil { return } c.player.SetWindow(x, y, w, h) } func (c *gstreamerController) Play() error { if c.player == nil { return fmt.Errorf("GStreamer player not initialized") } return c.player.Play() } func (c *gstreamerController) Pause() error { if c.player == nil { return fmt.Errorf("GStreamer player not initialized") } return c.player.Pause() } func (c *gstreamerController) Seek(offset float64) error { if c.player == nil { return fmt.Errorf("GStreamer player not initialized") } offsetDuration := time.Duration(offset * float64(time.Second)) return c.player.SeekToTime(offsetDuration) } func (c *gstreamerController) SetVolume(level float64) error { if c.player == nil { return fmt.Errorf("GStreamer player not initialized") } // Controller uses 0-100 scale, GStreamer uses 0.0-1.0 normalizedLevel := level / 100.0 return c.player.SetVolume(normalizedLevel) } func (c *gstreamerController) FullScreen() error { if c.player == nil { return fmt.Errorf("GStreamer player not initialized") } return c.player.SetFullScreen(true) } func (c *gstreamerController) Stop() error { if c.player == nil { return fmt.Errorf("GStreamer player not initialized") } return c.player.Stop() } func (c *gstreamerController) Close() { if c.player != nil { c.player.Close() } } // stubController provides a no-op implementation when GStreamer fails to initialize type stubController struct{} func (s *stubController) Load(path string, offset float64) error { return fmt.Errorf("GStreamer player not available") } func (s *stubController) SetWindow(x, y, w, h int) {} func (s *stubController) Play() error { return fmt.Errorf("GStreamer player not available") } func (s *stubController) Pause() error { return fmt.Errorf("GStreamer player not available") } func (s *stubController) Seek(offset float64) error { return fmt.Errorf("GStreamer player not available") } func (s *stubController) SetVolume(level float64) error { return fmt.Errorf("GStreamer player not available") } func (s *stubController) FullScreen() error { return fmt.Errorf("GStreamer player not available") } func (s *stubController) Stop() error { return fmt.Errorf("GStreamer player not available") } func (s *stubController) Close() {}