player.go 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package player
  2. import (
  3. "context"
  4. "errors"
  5. "io"
  6. )
  7. type Player interface {
  8. Available(context.Context) error
  9. Start(chan error) error
  10. Write([]byte) error
  11. Close() error
  12. }
  13. type writer struct {
  14. pipe io.WriteCloser
  15. exit chan any
  16. buff chan []byte
  17. }
  18. func (w *writer) Run(ch chan error) {
  19. var err error
  20. w.exit = make(chan any)
  21. w.buff = make(chan []byte, 8)
  22. defer func() {
  23. close(w.exit)
  24. close(w.buff)
  25. }()
  26. for {
  27. select {
  28. case <-w.exit:
  29. return
  30. case d := <-w.buff:
  31. if w.pipe == nil {
  32. ch <- io.ErrClosedPipe
  33. return
  34. }
  35. if _, err = w.pipe.Write(d); err != nil {
  36. ch <- err
  37. return
  38. }
  39. }
  40. }
  41. }
  42. func (w *writer) Write(d []byte) error {
  43. if d == nil || w.buff == nil {
  44. return errors.New("illegal state")
  45. }
  46. w.buff <- d
  47. return nil
  48. }
  49. func (w *writer) Close() error {
  50. if w.pipe != nil {
  51. _ = w.pipe.Close()
  52. }
  53. return nil
  54. }
  55. //goland:noinspection GoExportedFuncWithUnexportedType
  56. func Writer(pipe io.WriteCloser) *writer {
  57. return &writer{
  58. pipe: pipe,
  59. exit: make(chan any),
  60. buff: make(chan []byte, 64),
  61. }
  62. }