vlc.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package player
  2. import (
  3. "context"
  4. "errors"
  5. "io"
  6. "os"
  7. "os/exec"
  8. "path/filepath"
  9. )
  10. type VLC struct {
  11. session *exec.Cmd
  12. ctx context.Context
  13. cancelFunc context.CancelFunc
  14. wr *writer
  15. }
  16. func NewVLC(ctx context.Context) (Player, error) {
  17. r := new(VLC)
  18. if err := r.Available(ctx); err != nil {
  19. return nil, err
  20. }
  21. return r, nil
  22. }
  23. func (p *VLC) Available(ctx context.Context) error {
  24. p.ctx, p.cancelFunc = context.WithCancel(ctx)
  25. home, err := os.UserHomeDir()
  26. if err != nil {
  27. return err
  28. }
  29. var (
  30. paths = []string{
  31. filepath.Join("/", "Applications", "VLC.app", "Contents", "MacOS", "VLC"),
  32. filepath.Join("/", "Applications", "VLC.app", "Contents", "MacOS", "vlc"),
  33. filepath.Join("/", "Applications", "MacPorts", "VLC.app", "Contents", "MacOS", "VLC"),
  34. filepath.Join("/", "Applications", "MacPorts", "VLC.app", "Contents", "MacOS", "vlc"),
  35. filepath.Join(home, "Applications", "VLC.app", "Contents", "MacOS", "vlc"),
  36. filepath.Join(home, "Applications", "VLC.app", "Contents", "MacOS", "vlc"),
  37. }
  38. f *os.File
  39. s os.FileInfo
  40. )
  41. for _, path := range paths {
  42. if f, err = os.Open(path); err != nil {
  43. continue
  44. }
  45. if s, err = f.Stat(); err != nil {
  46. continue
  47. }
  48. if s.IsDir() {
  49. continue
  50. }
  51. p.session = exec.CommandContext(p.ctx, path, "-")
  52. return nil
  53. }
  54. return errors.New("could not find installed VLC player")
  55. }
  56. func (p *VLC) Start(stop chan error) error {
  57. if p.session == nil {
  58. return errors.New("illegal state: player session was not established")
  59. }
  60. var (
  61. pipe io.WriteCloser
  62. err error
  63. )
  64. if pipe, err = p.session.StdinPipe(); err != nil {
  65. return err
  66. }
  67. if err = p.session.Start(); err != nil {
  68. return err
  69. }
  70. p.wr = Writer(pipe)
  71. go p.wr.Run(stop)
  72. return nil
  73. }
  74. func (p *VLC) Write(d []byte) error {
  75. if p.wr == nil {
  76. return io.ErrClosedPipe
  77. }
  78. return p.wr.Write(d)
  79. }
  80. func (p *VLC) Close() error {
  81. if p.cancelFunc != nil {
  82. p.cancelFunc()
  83. }
  84. if p.wr != nil {
  85. _ = p.wr.Close()
  86. }
  87. p.session = nil
  88. return nil
  89. }