diff --git a/config.go b/config.go index 708e928..61d8bab 100644 --- a/config.go +++ b/config.go @@ -76,7 +76,7 @@ func (r *Record) Tree(dstPath string, level int) (files []*VideoFileInfo, err er return } if !fileInfo.IsDir() { //如果dstF是文件 - if path.Ext(fileInfo.Name()) == r.Ext { + if r.Ext == "." || path.Ext(fileInfo.Name()) == r.Ext { p := strings.TrimPrefix(dstPath, r.Path) p = strings.ReplaceAll(p, "\\", "/") var duration uint32 diff --git a/flv.go b/flv.go index 4a2319c..274b2b1 100644 --- a/flv.go +++ b/flv.go @@ -13,7 +13,14 @@ type FLVRecorder struct { Recorder } -func (r *FLVRecorder) Start() { +func (r *FLVRecorder) Start(streamPath string) (err error){ + r.Record = &recordConfig.Flv + r.ID = streamPath + "/flv" + return plugin.Subscribe(streamPath, r) +} + +func (r *FLVRecorder) start() { + recordConfig.recordings.Store(r.ID, r) r.PlayFLV() recordConfig.recordings.Delete(r.ID) r.Close() @@ -35,7 +42,7 @@ func (r *FLVRecorder) OnEvent(event any) { if !r.append { r.Write(codec.FLVHeader) } - go r.Start() + go r.start() case FLVFrame: if ts := r.Video.Frame.AbsTime - r.SkipTS; r.Video.Frame.IFrame && int64(ts-r.FirstAbsTS) >= int64(r.Fragment*1000) { r.FirstAbsTS = ts diff --git a/hls.go b/hls.go index 29cabbe..154682c 100644 --- a/hls.go +++ b/hls.go @@ -22,6 +22,12 @@ type HLSRecorder struct { tsWriter io.WriteCloser } +func (h *HLSRecorder) Start(streamPath string) error { + h.Record = &recordConfig.Hls + h.ID = streamPath + "/hls" + return plugin.Subscribe(streamPath, h) +} + func (h *HLSRecorder) OnEvent(event any) { var err error defer func() { @@ -45,7 +51,7 @@ func (h *HLSRecorder) OnEvent(event any) { if err = h.createHlsTsSegmentFile(); err != nil { return } - go h.Start() + go h.start() case AudioDeConf: h.asc, err = hls.DecodeAudioSpecificConfig(v.AVCC[0]) case *AudioFrame: diff --git a/main.go b/main.go index 34f6849..614fa92 100644 --- a/main.go +++ b/main.go @@ -60,23 +60,18 @@ func (conf *RecordConfig) OnEvent(event any) { case SEpublish: if conf.Flv.NeedRecord(v.Stream.Path) { var flv FLVRecorder - flv.Record = &conf.Flv - plugin.Subscribe(v.Stream.Path, &flv) + flv.Start(v.Stream.Path) } if conf.Mp4.NeedRecord(v.Stream.Path) { - mp4 := NewMP4Recorder() - mp4.Record = &conf.Mp4 - plugin.Subscribe(v.Stream.Path, mp4) + NewMP4Recorder().Start(v.Stream.Path) } if conf.Hls.NeedRecord(v.Stream.Path) { var hls HLSRecorder - hls.Record = &conf.Hls - plugin.Subscribe(v.Stream.Path, &hls) + hls.Start(v.Stream.Path) } if conf.Raw.NeedRecord(v.Stream.Path) { var raw RawRecorder - raw.Record = &conf.Raw - plugin.Subscribe(v.Stream.Path, &raw) + raw.Start(v.Stream.Path) } } } @@ -133,39 +128,33 @@ func (conf *RecordConfig) API_start(w http.ResponseWriter, r *http.Request) { t := query.Get("type") var sub ISubscriber var filePath string + var err error switch t { case "": t = "flv" fallthrough case "flv": var flvRecoder FLVRecorder - flvRecoder.Record = &conf.Flv - sub = &flvRecoder flvRecoder.append = query.Get("append") != "" && util.Exist(filePath) + err = flvRecoder.Start(streamPath) case "mp4": - recorder := NewMP4Recorder() - recorder.Record = &conf.Mp4 - sub = recorder + err = NewMP4Recorder().Start(streamPath) case "hls": - recorder := &HLSRecorder{} - recorder.Record = &conf.Hls - sub = recorder + var recorder HLSRecorder + err = recorder.Start(streamPath) case "raw": - recorder := &RawRecorder{} - recorder.Record = &conf.Raw + var recorder RawRecorder recorder.append = query.Get("append") != "" && util.Exist(filePath) - sub = recorder + err = recorder.Start(streamPath) default: http.Error(w, "type not supported", http.StatusBadRequest) + return } - if err := plugin.Subscribe(streamPath, sub); err != nil { + if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - id := streamPath + "/" + t - sub.GetIO().ID = id - conf.recordings.Store(id, sub) - w.Write([]byte(id)) + w.Write([]byte(sub.GetIO().ID)) } func (conf *RecordConfig) API_list_recording(w http.ResponseWriter, r *http.Request) { @@ -182,6 +171,7 @@ func (conf *RecordConfig) API_list_recording(w http.ResponseWriter, r *http.Requ func (conf *RecordConfig) API_stop(w http.ResponseWriter, r *http.Request) { if recorder, ok := conf.recordings.Load(r.URL.Query().Get("id")); ok { recorder.(ISubscriber).Stop() + w.Write([]byte("ok")) return } http.Error(w, "no such recorder", http.StatusBadRequest) diff --git a/mp4.go b/mp4.go index 08c8bc1..a339eb1 100644 --- a/mp4.go +++ b/mp4.go @@ -67,6 +67,12 @@ func NewMP4Recorder() *MP4Recorder { return r } +func (r *MP4Recorder) Start(streamPath string) (err error) { + r.Record = &recordConfig.Mp4 + r.ID = streamPath + "/mp4" + return plugin.Subscribe(streamPath, r) +} + func (r *MP4Recorder) Close() error { if r.Writer != nil { if r.video.fragment != nil { @@ -135,7 +141,7 @@ func (r *MP4Recorder) OnEvent(event any) { case ISubscriber: defaultFtyp.Encode(r) r.Moov.Encode(r) - go r.Start() + go r.start() case *AudioFrame: if r.audio.trackId != 0 { r.audio.push(r, v.AbsTime, v.DeltaTime, util.ConcatBuffers(v.Raw), mp4.SyncSampleFlags) diff --git a/raw.go b/raw.go index 042f4d9..8b099b8 100644 --- a/raw.go +++ b/raw.go @@ -14,11 +14,17 @@ type RawRecorder struct { Recorder } +func (r *RawRecorder) Start(streamPath string) error { + r.Record = &recordConfig.Raw + r.ID = streamPath + "/raw" + return plugin.Subscribe(streamPath, r) +} + func (r *RawRecorder) OnEvent(event any) { r.Recorder.OnEvent(event) switch v := event.(type) { case *RawRecorder: - go r.Start() + go r.start() case *track.Video: if r.Ext == "." { if v.CodecID == codec.CodecID_H264 { diff --git a/subscriber.go b/subscriber.go index 58e6fc4..72c0e0e 100644 --- a/subscriber.go +++ b/subscriber.go @@ -15,7 +15,8 @@ type Recorder struct { append bool // 是否追加模式 } -func (r *Recorder) Start() { +func (r *Recorder) start() { + recordConfig.recordings.Store(r.ID, r) r.PlayRaw() recordConfig.recordings.Delete(r.ID) r.Close()