mirror of
https://github.com/Monibuca/plugin-record.git
synced 2025-10-06 01:07:00 +08:00
111 lines
2.5 KiB
Go
111 lines
2.5 KiB
Go
package record
|
||
|
||
import (
|
||
"io"
|
||
"net/http"
|
||
"os"
|
||
"path"
|
||
"path/filepath"
|
||
"regexp"
|
||
"strings"
|
||
)
|
||
|
||
type FileWr interface {
|
||
io.Reader
|
||
io.Writer
|
||
io.Seeker
|
||
io.Closer
|
||
}
|
||
type VideoFileInfo struct {
|
||
Path string
|
||
Size int64
|
||
Duration uint32
|
||
}
|
||
|
||
type Record struct {
|
||
Ext string //文件扩展名
|
||
Path string //存储文件的目录
|
||
AutoRecord bool
|
||
Filter string
|
||
Fragment int //分片大小(秒)0表示不分片
|
||
filterReg *regexp.Regexp
|
||
fs http.Handler
|
||
CreateFileFn func(filename string, append bool) (FileWr, error) `yaml:"-" json:"-"`
|
||
GetDurationFn func(file io.ReadSeeker) uint32 `yaml:"-" json:"-"`
|
||
}
|
||
|
||
func (r *Record) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||
r.fs.ServeHTTP(w, req)
|
||
}
|
||
|
||
func (r *Record) NeedRecord(streamPath string) bool {
|
||
return r.AutoRecord && (r.filterReg == nil || r.filterReg.MatchString(streamPath))
|
||
}
|
||
|
||
func (r *Record) Init() {
|
||
os.MkdirAll(r.Path, 0766)
|
||
if r.Filter != "" {
|
||
r.filterReg = regexp.MustCompile(r.Filter)
|
||
}
|
||
r.fs = http.FileServer(http.Dir(r.Path))
|
||
r.CreateFileFn = func(filename string, append bool) (file FileWr, err error) {
|
||
filePath := filepath.Join(r.Path, filename)
|
||
flag := os.O_CREATE
|
||
if append {
|
||
flag = flag | os.O_RDWR | os.O_APPEND
|
||
} else {
|
||
flag = flag | os.O_TRUNC | os.O_WRONLY
|
||
}
|
||
if err = os.MkdirAll(filepath.Dir(filePath), 0766); err != nil {
|
||
return file, err
|
||
}
|
||
file, err = os.OpenFile(filePath, flag, 0766)
|
||
return
|
||
}
|
||
}
|
||
|
||
func (r *Record) Tree(dstPath string, level int) (files []*VideoFileInfo, err error) {
|
||
var dstF *os.File
|
||
dstF, err = os.Open(dstPath)
|
||
if err != nil {
|
||
return
|
||
}
|
||
defer dstF.Close()
|
||
fileInfo, err := dstF.Stat()
|
||
if err != nil {
|
||
return
|
||
}
|
||
if !fileInfo.IsDir() { //如果dstF是文件
|
||
if r.Ext == "." || path.Ext(fileInfo.Name()) == r.Ext {
|
||
p := strings.TrimPrefix(dstPath, r.Path)
|
||
p = strings.ReplaceAll(p, "\\", "/")
|
||
var duration uint32
|
||
if r.GetDurationFn != nil {
|
||
duration = r.GetDurationFn(dstF)
|
||
}
|
||
files = append(files, &VideoFileInfo{
|
||
Path: strings.TrimPrefix(p, "/"),
|
||
Size: fileInfo.Size(),
|
||
Duration: duration,
|
||
})
|
||
}
|
||
return
|
||
} else { //如果dstF是文件夹
|
||
var dir []os.FileInfo
|
||
dir, err = dstF.Readdir(0) //获取文件夹下各个文件或文件夹的fileInfo
|
||
if err != nil {
|
||
return
|
||
}
|
||
for _, fileInfo = range dir {
|
||
var _files []*VideoFileInfo
|
||
_files, err = r.Tree(filepath.Join(dstPath, fileInfo.Name()), level+1)
|
||
if err != nil {
|
||
return
|
||
}
|
||
files = append(files, _files...)
|
||
}
|
||
return
|
||
}
|
||
|
||
}
|