package player import ( "context" "errors" "io" ) type Player interface { Available(context.Context) error Start(chan error) error Write([]byte) error Close() error } type writer struct { pipe io.WriteCloser exit chan any buff chan []byte } func (w *writer) Run(ch chan error) { var err error w.exit = make(chan any) w.buff = make(chan []byte, 8) defer func() { close(w.exit) close(w.buff) }() for { select { case <-w.exit: return case d := <-w.buff: if w.pipe == nil { ch <- io.ErrClosedPipe return } if _, err = w.pipe.Write(d); err != nil { ch <- err return } } } } func (w *writer) Write(d []byte) error { if d == nil || w.buff == nil { return errors.New("illegal state") } w.buff <- d return nil } func (w *writer) Close() error { if w.pipe != nil { _ = w.pipe.Close() } return nil } //goland:noinspection GoExportedFuncWithUnexportedType func Writer(pipe io.WriteCloser) *writer { return &writer{ pipe: pipe, exit: make(chan any), buff: make(chan []byte, 64), } }