diff options
-rw-r--r-- | player/player.go | 154 |
1 files changed, 150 insertions, 4 deletions
diff --git a/player/player.go b/player/player.go index 5328475..f9b5335 100644 --- a/player/player.go +++ b/player/player.go @@ -34,10 +34,48 @@ func init() { gst.Init(nil) } +type loadResult struct { + err error +} + +type loadRequest struct { + cart uint + cut uint + response chan<- loadResult +} + +type playResult struct { + err error +} + +type playRequest struct { + response chan<- playResult +} + +type pauseResult struct { + err error +} + +type pauseRequest struct { + response chan<- pauseResult +} + +type stopResult struct { + err error +} + +type stopRequest struct { + response chan<- stopResult +} + type Player struct { - pipe *gst.Element - bus *gst.Bus - basepath string + pipe *gst.Element + bus *gst.Bus + basepath string + loadChan chan loadRequest + playChan chan playRequest + pauseChan chan pauseRequest + stopChan chan stopRequest } func (p *Player) onMessage(bus *gst.Bus, msg *gst.Message) { @@ -65,16 +103,123 @@ func (p *Player) onMessage(bus *gst.Bus, msg *gst.Message) { } } -func (p *Player) Play(cart, cut uint) (err error) { +func (p *Player) load(cart, cut uint) (resp loadResult) { filename := path.Join(p.basepath, fmt.Sprintf("%06d_%03d.wav", cart, cut)) p.pipe.SetProperty("uri", "file://"+filename) + p.pipe.SetState(gst.STATE_PAUSED) + return +} + +func (p *Player) play() (resp playResult) { p.pipe.SetState(gst.STATE_PLAYING) return } +func (p *Player) pause() (resp pauseResult) { + p.pipe.SetState(gst.STATE_PAUSED) + return +} + +func (p *Player) stop() (resp stopResult) { + p.pipe.SetState(gst.STATE_NULL) + return +} + +func (p *Player) dispatchRequests() { + for { + select { + case req := <-p.loadChan: + req.response <- p.load(req.cart, req.cut) + case req := <-p.playChan: + req.response <- p.play() + case req := <-p.pauseChan: + req.response <- p.pause() + case req := <-p.stopChan: + req.response <- p.stop() + } + } +} + +// ********************************************************* +// Public Interface + +type PlayerChan struct { + load chan<- loadRequest + play chan<- playRequest + pause chan<- pauseRequest + stop chan<- stopRequest +} + +func (p *PlayerChan) Load(cart, cut uint) error { + resCh := make(chan loadResult) + req := loadRequest{} + req.cart = cart + req.cut = cut + req.response = resCh + p.load <- req + + res := <-resCh + if res.err != nil { + return res.err + } + return nil +} + +func (p *PlayerChan) Play() error { + resCh := make(chan playResult) + req := playRequest{} + req.response = resCh + p.play <- req + + res := <-resCh + if res.err != nil { + return res.err + } + return nil +} + +func (p *PlayerChan) Pause() error { + resCh := make(chan pauseResult) + req := pauseRequest{} + req.response = resCh + p.pause <- req + + res := <-resCh + if res.err != nil { + return res.err + } + return nil +} + +func (p *PlayerChan) Stop() error { + resCh := make(chan stopResult) + req := stopRequest{} + req.response = resCh + p.stop <- req + + res := <-resCh + if res.err != nil { + return res.err + } + return nil +} + +func (p *Player) GetInterface() *PlayerChan { + ch := &PlayerChan{} + ch.load = p.loadChan + ch.play = p.playChan + ch.pause = p.pauseChan + ch.stop = p.stopChan + return ch +} + func NewPlayer(basepath string) (p *Player, err error) { p = &Player{} p.basepath = path.Clean(basepath) + p.loadChan = make(chan loadRequest) + p.playChan = make(chan playRequest) + p.pauseChan = make(chan pauseRequest) + p.stopChan = make(chan stopRequest) if p.pipe, err = gst.ElementFactoryMake("playbin", "autoplay"); err != nil { return @@ -86,5 +231,6 @@ func NewPlayer(basepath string) (p *Player, err error) { p.bus.AddSignalWatch() p.bus.Connect("message", func(bus *gst.Bus, msg *gst.Message) { p.onMessage(bus, msg) }) + go p.dispatchRequests() return } |