raw.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package record
  2. import (
  3. "path/filepath"
  4. "strconv"
  5. "time"
  6. "go.uber.org/zap"
  7. . "m7s.live/engine/v4"
  8. "m7s.live/engine/v4/codec"
  9. "m7s.live/engine/v4/track"
  10. )
  11. type RawRecorder struct {
  12. Recorder
  13. IsAudio bool
  14. }
  15. func (r *RawRecorder) Start(streamPath string) error {
  16. if r.IsAudio {
  17. r.Record = &RecordPluginConfig.RawAudio
  18. } else {
  19. r.Record = &RecordPluginConfig.Raw
  20. }
  21. r.ID = streamPath + "/raw"
  22. if r.IsAudio {
  23. r.ID += "_audio"
  24. }
  25. if _, ok := RecordPluginConfig.recordings.Load(r.ID); ok {
  26. return ErrRecordExist
  27. }
  28. return plugin.Subscribe(streamPath, r)
  29. }
  30. func (r *RawRecorder) OnEvent(event any) {
  31. switch v := event.(type) {
  32. case *RawRecorder:
  33. filename := strconv.FormatInt(time.Now().Unix(), 10) + r.Ext
  34. if r.Fragment == 0 {
  35. filename = r.Stream.Path + r.Ext
  36. } else {
  37. filename = filepath.Join(r.Stream.Path, filename)
  38. }
  39. if file, err := r.CreateFileFn(filename, r.append); err == nil {
  40. r.SetIO(file)
  41. } else {
  42. r.Error("create file failed", zap.Error(err))
  43. r.Stop()
  44. }
  45. go r.start()
  46. case *track.Video:
  47. if r.IsAudio {
  48. break
  49. }
  50. if r.Ext == "." {
  51. if v.CodecID == codec.CodecID_H264 {
  52. r.Ext = ".h264"
  53. } else {
  54. r.Ext = ".h265"
  55. }
  56. }
  57. r.AddTrack(v)
  58. case *track.Audio:
  59. if !r.IsAudio {
  60. break
  61. }
  62. if r.Ext == "." {
  63. switch v.CodecID {
  64. case codec.CodecID_AAC:
  65. r.Ext = ".aac"
  66. case codec.CodecID_PCMA:
  67. r.Ext = ".pcma"
  68. case codec.CodecID_PCMU:
  69. r.Ext = ".pcmu"
  70. }
  71. }
  72. r.AddTrack(v)
  73. case AudioFrame:
  74. if r.Fragment > 0 {
  75. if r.cut(v.AbsTime); r.newFile {
  76. r.newFile = false
  77. r.Close()
  78. if file, err := r.CreateFileFn(filepath.Join(r.Stream.Path, strconv.FormatInt(time.Now().Unix(), 10)+r.Ext), false); err == nil {
  79. r.SetIO(file)
  80. }
  81. }
  82. }
  83. v.WriteRawTo(r)
  84. case VideoFrame:
  85. if r.Fragment > 0 && v.IFrame {
  86. if r.cut(v.AbsTime); r.newFile {
  87. r.newFile = false
  88. r.Close()
  89. if file, err := r.CreateFileFn(filepath.Join(r.Stream.Path, strconv.FormatInt(time.Now().Unix(), 10)+r.Ext), false); err == nil {
  90. r.SetIO(file)
  91. }
  92. }
  93. }
  94. v.WriteAnnexBTo(r)
  95. default:
  96. r.IO.OnEvent(v)
  97. }
  98. }