123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- package record
- import (
- "bufio"
- "io"
- "path/filepath"
- "strconv"
- "time"
- //"fmt"
- "go.uber.org/zap"
- . "m7s.live/engine/v4"
- )
- type IRecorder interface {
- ISubscriber
- GetRecorder() *Recorder
- Start(streamPath string) error
- io.Closer
- CreateFile() (FileWr, error)
- }
- type Recorder struct {
- Subscriber
- SkipTS uint32
- Record `json:"-" yaml:"-"`
- File FileWr `json:"-" yaml:"-"`
- FileName string // 自定义文件名,分段录像无效
- filePath string // 文件路径
- append bool // 是否追加模式
- }
- func (r *Recorder) GetRecorder() *Recorder {
- return r
- }
- func (r *Recorder) CreateFile() (f FileWr, err error) {
- //fmt.Println("00000000000000000000 CREATE FILE:",r.Stream.Path)
- r.filePath = r.getFileName(r.Stream.Path) + r.Ext
- f, err = r.CreateFileFn(r.filePath, r.append)
- logFields := []zap.Field{zap.String("path", r.filePath)}
- if fw, ok := f.(*FileWriter); ok && r.Config != nil {
- if r.Config.WriteBufferSize > 0 {
- logFields = append(logFields, zap.Int("bufferSize", r.Config.WriteBufferSize))
- fw.bufw = bufio.NewWriterSize(fw.Writer, r.Config.WriteBufferSize)
- fw.Writer = fw.bufw
- }
- }
- if err == nil {
- r.Info("create file", logFields...)
- } else {
- logFields = append(logFields, zap.Error(err))
- r.Error("create file", logFields...)
- }
- return
- }
- func (r *Recorder) getFileName(streamPath string) (filename string) {
- filename = streamPath
- if r.Fragment == 0 {
- if r.FileName != "" {
- filename = filepath.Join(filename, r.FileName)
- }
- } else {
- filename = filepath.Join(filename, strconv.FormatInt(time.Now().Unix(), 10))
- }
- return
- }
- func (r *Recorder) start(re IRecorder, streamPath string, subType byte) (err error) {
- //fmt.Println("SSSSSSSSSSSSSSSSSSSSSSSSSSSSS")
- err = plugin.Subscribe(streamPath, re)
- //fmt.Println("SSSSSSSSSSSSSSSSSSSSSSSSSSSSS:",err)
- if err == nil {
- if _, loaded := RecordPluginConfig.recordings.LoadOrStore(r.ID, re); loaded {
- //fmt.Println("SSSSSSSSSSSSSSSSSSSSSSSSSSSSS:",ErrRecordExist)
- return ErrRecordExist
- }
- r.Closer = re
- go func() {
- //fmt.Println("SSSSSSSSSSSSSSSSSSSSSSSSSSSSS play block:")
- r.PlayBlock(subType)
- RecordPluginConfig.recordings.Delete(r.ID)
- }()
- }
- return
- }
- func (r *Recorder) cut(absTime uint32) {
- if ts := absTime - r.SkipTS; time.Duration(ts)*time.Millisecond >= r.Fragment {
- //fmt.Println("111111111111111111 cut new file:",absTime,r.Fragment)
- r.SkipTS = absTime
- r.Close()
- if file, err := r.Spesific.(IRecorder).CreateFile(); err == nil {
- r.File = file
- r.Spesific.OnEvent(file)
- } else {
- r.Stop(zap.Error(err))
- }
- }
- }
- // func (r *Recorder) Stop(reason ...zap.Field) {
- // r.Close()
- // r.Subscriber.Stop(reason...)
- // }
- func (r *Recorder) OnEvent(event any) {
- switch v := event.(type) {
- case IRecorder:
- //fmt.Println("ONENVET IRecorder 111111111111111111111111111:", *r)
- if file, err := r.Spesific.(IRecorder).CreateFile(); err == nil {
- r.File = file
- r.Spesific.OnEvent(file)
- } else {
- r.Stop(zap.Error(err))
- }
- case AudioFrame:
- // 纯音频流的情况下需要切割文件
- if r.Fragment > 0 && r.VideoReader == nil {
- r.cut(v.AbsTime)
- }
- case VideoFrame:
- //.Println("record on video frame aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:")
- if r.Fragment > 0 && v.IFrame {
- //fmt.Println("ONENVET CUT 111111111111111111111111111:",r.Fragment,v.IFrame,"rrrrrrrrrrr:",*r )
- r.cut(v.AbsTime)
- }
- default:
- r.Subscriber.OnEvent(event)
- }
- }
|