subscriber.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package record
  2. import (
  3. "path/filepath"
  4. "strconv"
  5. "time"
  6. "go.uber.org/zap"
  7. . "m7s.live/engine/v4"
  8. )
  9. type Recorder struct {
  10. Subscriber
  11. SkipTS uint32
  12. *Record `json:"-" yaml:"-"`
  13. newFile bool // 创建了新的文件
  14. append bool // 是否追加模式
  15. }
  16. func (r *Recorder) start() {
  17. RecordPluginConfig.recordings.Store(r.ID, r)
  18. r.PlayRaw()
  19. RecordPluginConfig.recordings.Delete(r.ID)
  20. }
  21. func (r *Recorder) cut(absTime uint32) {
  22. if ts := absTime - r.SkipTS; time.Duration(ts)*time.Millisecond >= r.Fragment {
  23. r.SkipTS = absTime
  24. r.newFile = true
  25. }
  26. }
  27. func (r *Recorder) OnEvent(event any) {
  28. switch v := event.(type) {
  29. case ISubscriber:
  30. filename := strconv.FormatInt(time.Now().Unix(), 10) + r.Ext
  31. if r.Fragment == 0 {
  32. filename = r.Stream.Path + r.Ext
  33. } else {
  34. filename = filepath.Join(r.Stream.Path, filename)
  35. }
  36. if file, err := r.CreateFileFn(filename, r.append); err == nil {
  37. r.SetIO(file)
  38. } else {
  39. r.Error("create file failed", zap.Error(err))
  40. r.Stop()
  41. }
  42. case AudioFrame:
  43. // 纯音频流的情况下需要切割文件
  44. if r.Fragment > 0 && r.VideoReader == nil {
  45. r.cut(v.AbsTime)
  46. }
  47. case VideoFrame:
  48. if r.Fragment > 0 && v.IFrame {
  49. r.cut(v.AbsTime)
  50. }
  51. default:
  52. r.Subscriber.OnEvent(event)
  53. }
  54. }