config.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package record
  2. import (
  3. "io"
  4. "net/http"
  5. "os"
  6. "path"
  7. "path/filepath"
  8. "regexp"
  9. "strings"
  10. "time"
  11. "m7s.live/engine/v4"
  12. )
  13. type FileWr interface {
  14. io.Reader
  15. io.Writer
  16. io.Seeker
  17. io.Closer
  18. }
  19. type VideoFileInfo struct {
  20. Path string
  21. Size int64
  22. Duration uint32
  23. }
  24. type Record struct {
  25. Ext string //文件扩展名
  26. Path string //存储文件的目录
  27. AutoRecord bool
  28. Filter string
  29. Fragment time.Duration //分片大小,0表示不分片
  30. filterReg *regexp.Regexp
  31. fs http.Handler
  32. CreateFileFn func(filename string, append bool) (FileWr, error) `json:"-" yaml:"-"`
  33. GetDurationFn func(file io.ReadSeeker) uint32 `json:"-" yaml:"-"`
  34. recording map[string]engine.ISubscriber
  35. }
  36. func (r *Record) ServeHTTP(w http.ResponseWriter, req *http.Request) {
  37. r.fs.ServeHTTP(w, req)
  38. }
  39. func (r *Record) NeedRecord(streamPath string) bool {
  40. if _, ok := r.recording[streamPath]; ok {
  41. return false
  42. }
  43. return r.AutoRecord && (r.filterReg == nil || r.filterReg.MatchString(streamPath))
  44. }
  45. func (r *Record) Init() {
  46. r.recording = make(map[string]engine.ISubscriber)
  47. os.MkdirAll(r.Path, 0766)
  48. if r.Filter != "" {
  49. r.filterReg = regexp.MustCompile(r.Filter)
  50. }
  51. r.fs = http.FileServer(http.Dir(r.Path))
  52. r.CreateFileFn = func(filename string, append bool) (file FileWr, err error) {
  53. filePath := filepath.Join(r.Path, filename)
  54. flag := os.O_CREATE
  55. if append {
  56. flag = flag | os.O_RDWR | os.O_APPEND
  57. } else {
  58. flag = flag | os.O_RDWR | os.O_TRUNC
  59. }
  60. if err = os.MkdirAll(filepath.Dir(filePath), 0766); err != nil {
  61. return file, err
  62. }
  63. file, err = os.OpenFile(filePath, flag, 0766)
  64. return
  65. }
  66. }
  67. func (r *Record) Tree(dstPath string, level int) (files []*VideoFileInfo, err error) {
  68. var dstF *os.File
  69. dstF, err = os.Open(dstPath)
  70. if err != nil {
  71. return
  72. }
  73. defer dstF.Close()
  74. fileInfo, err := dstF.Stat()
  75. if err != nil {
  76. return
  77. }
  78. if !fileInfo.IsDir() { //如果dstF是文件
  79. if r.Ext == "." || path.Ext(fileInfo.Name()) == r.Ext {
  80. p := strings.TrimPrefix(dstPath, r.Path)
  81. p = strings.ReplaceAll(p, "\\", "/")
  82. var duration uint32
  83. if r.GetDurationFn != nil {
  84. duration = r.GetDurationFn(dstF)
  85. }
  86. files = append(files, &VideoFileInfo{
  87. Path: strings.TrimPrefix(p, "/"),
  88. Size: fileInfo.Size(),
  89. Duration: duration,
  90. })
  91. }
  92. return
  93. } else { //如果dstF是文件夹
  94. var dir []os.FileInfo
  95. dir, err = dstF.Readdir(0) //获取文件夹下各个文件或文件夹的fileInfo
  96. if err != nil {
  97. return
  98. }
  99. for _, fileInfo = range dir {
  100. var _files []*VideoFileInfo
  101. _files, err = r.Tree(filepath.Join(dstPath, fileInfo.Name()), level+1)
  102. if err != nil {
  103. return
  104. }
  105. files = append(files, _files...)
  106. }
  107. return
  108. }
  109. }