package player import ( "context" "errors" "fmt" "io" "os" "path/filepath" "strings" "time" ) type Recorder struct { path string bid string wr *writer } func NewRecorder(path string, bid string) (Player, error) { if path = strings.TrimSpace(path); path == "" { return nil, errors.New("illegal arguments: empty path") } if bid = strings.TrimSpace(bid); bid == "" { return nil, errors.New("illegal arguments: empty bid") } var ( r = Recorder{ path: path, bid: bid, } err error ) if err = r.Available(nil); err != nil { return nil, err } return &r, nil } func (r *Recorder) Available(context.Context) error { if r.path == "" || r.bid == "" { return errors.New("illegal state") } var ( f *os.File err error ) if f, err = os.OpenFile( filepath.Join(r.path, ".watchdog"), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0666); err != nil { return err } defer func() { if f == nil { return } _ = f.Close() _ = os.Remove(f.Name()) }() return nil } func (r *Recorder) Start(stop chan error) error { var ( pipe io.WriteCloser err error ) pipe, err = os.OpenFile( filepath.Join(r.path, fmt.Sprintf("%s_%s.TS", r.bid, time.Now().String())), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0666) if err != nil { return err } r.wr = Writer(pipe) go r.wr.Run(stop) return nil } func (r *Recorder) Write(d []byte) error { if r.wr == nil { return io.ErrClosedPipe } return r.wr.Write(d) } func (r *Recorder) Close() error { if r.wr != nil { _ = r.wr.Close() } return nil }