mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-12-24 13:48:04 +08:00
fix: delete oldest mp4 file
This commit is contained in:
@@ -564,10 +564,22 @@ func (p *MP4Plugin) EventStart(ctx context.Context, req *mp4pb.ReqEventRecord) (
|
||||
AfterDuration: uint32(afterDuration / time.Millisecond),
|
||||
}
|
||||
if p.DB != nil {
|
||||
// Calculate total duration as the sum of BeforeDuration and AfterDuration
|
||||
totalDuration := newEvent.BeforeDuration + newEvent.AfterDuration
|
||||
|
||||
// Calculate StartTime and EndTime based on current time and durations
|
||||
now := time.Now()
|
||||
startTime := now.Add(-time.Duration(newEvent.BeforeDuration) * time.Millisecond)
|
||||
endTime := now.Add(time.Duration(newEvent.AfterDuration) * time.Millisecond)
|
||||
|
||||
p.DB.Save(&m7s.EventRecordStream{
|
||||
RecordEvent: newEvent,
|
||||
RecordStream: m7s.RecordStream{
|
||||
StreamPath: req.StreamPath,
|
||||
Duration: totalDuration,
|
||||
StartTime: startTime,
|
||||
EndTime: endTime,
|
||||
Type: "mp4",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -84,14 +84,16 @@ func (p *DeleteRecordTask) deleteOldestFile() {
|
||||
filePaths = append(filePaths, dirPath)
|
||||
}
|
||||
}
|
||||
p.Debug("deleteOldestFile", "after get onpub.record,filePaths.length", len(filePaths))
|
||||
if p.plugin.EventRecordFilePath != "" {
|
||||
// 同样处理EventRecordFilePath
|
||||
dirPath := filepath.Dir(p.plugin.EventRecordFilePath)
|
||||
filePaths = append(filePaths, dirPath)
|
||||
}
|
||||
p.Debug("deleteOldestFile", "after get eventrecordfilepath,filePaths.length", len(filePaths))
|
||||
for _, filePath := range filePaths {
|
||||
for p.getDiskOutOfSpace(filePath) {
|
||||
var eventRecords []m7s.EventRecordStream
|
||||
var recordStreams []m7s.RecordStream
|
||||
// 使用不同的方法进行路径匹配,避免ESCAPE语法问题
|
||||
// 解决方案:用MySQL能理解的简单方式匹配路径前缀
|
||||
basePath := filePath
|
||||
@@ -100,13 +102,13 @@ func (p *DeleteRecordTask) deleteOldestFile() {
|
||||
searchPattern := basePath + "%"
|
||||
p.Info("deleteOldestFile", "searching with path pattern", searchPattern)
|
||||
|
||||
err := p.DB.Where("event_id=0 AND end_time IS NOT NULL").
|
||||
err := p.DB.Where(" record_level!='high' AND end_time IS NOT NULL").
|
||||
Where("file_path LIKE ?", searchPattern).
|
||||
Order("end_time ASC").Find(&eventRecords).Error
|
||||
Order("end_time ASC").Limit(1).Find(&recordStreams).Error
|
||||
if err == nil {
|
||||
if len(eventRecords) > 0 {
|
||||
p.Info("deleteOldestFile", "found %d records", len(eventRecords))
|
||||
for _, record := range eventRecords {
|
||||
if len(recordStreams) > 0 {
|
||||
p.Info("deleteOldestFile", "found %d records", len(recordStreams))
|
||||
for _, record := range recordStreams {
|
||||
p.Info("deleteOldestFile", "ready to delete oldestfile,ID", record.ID, "create time", record.EndTime, "filepath", record.FilePath)
|
||||
err = os.Remove(record.FilePath)
|
||||
if err != nil {
|
||||
|
||||
@@ -56,7 +56,7 @@ type MP4Plugin struct {
|
||||
RecordFileExpireDays int `desc:"录像自动删除的天数,0或未设置表示不自动删除"`
|
||||
DiskMaxPercent float64 `default:"90" desc:"硬盘使用百分之上限值,超上限后触发报警,并停止当前所有磁盘写入动作。"`
|
||||
AutoOverWriteDiskPercent float64 `default:"0" desc:"自动覆盖功能磁盘占用上限值,超过上限时连续录像自动删除日有录像,事件录像自动删除非重要事件录像,删除规则为删除距离当日最久日期的连续录像或非重要事件录像。"`
|
||||
AutoRecovery bool `default:"true" desc:"是否自动恢复"`
|
||||
AutoRecovery bool `default:"false" desc:"是否自动恢复"`
|
||||
ExceptionPostUrl string `desc:"第三方异常上报地址"`
|
||||
EventRecordFilePath string `desc:"事件录像存放地址"`
|
||||
}
|
||||
|
||||
54
recoder.go
54
recoder.go
@@ -42,18 +42,19 @@ type (
|
||||
Event EventRecordStream
|
||||
}
|
||||
RecordStream struct {
|
||||
ID uint `gorm:"primarykey"`
|
||||
StartTime time.Time `gorm:"default:NULL"`
|
||||
EndTime time.Time `gorm:"default:NULL"`
|
||||
Duration uint32 `gorm:"comment:录像时长;default:0"`
|
||||
Filename string `json:"fileName" desc:"文件名" gorm:"type:varchar(255);comment:文件名"`
|
||||
Type string `json:"type" desc:"录像文件类型" gorm:"type:varchar(255);comment:录像文件类型,flv,mp4,raw,fmp4,hls"`
|
||||
FilePath string
|
||||
StreamPath string
|
||||
AudioCodec string
|
||||
VideoCodec string
|
||||
CreatedAt time.Time
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" yaml:"-"`
|
||||
ID uint `gorm:"primarykey"`
|
||||
StartTime time.Time `gorm:"default:NULL"`
|
||||
EndTime time.Time `gorm:"default:NULL"`
|
||||
Duration uint32 `gorm:"comment:录像时长;default:0"`
|
||||
Filename string `json:"fileName" desc:"文件名" gorm:"type:varchar(255);comment:文件名"`
|
||||
Type string `json:"type" desc:"录像文件类型" gorm:"type:varchar(255);comment:录像文件类型,flv,mp4,raw,fmp4,hls"`
|
||||
FilePath string
|
||||
StreamPath string
|
||||
AudioCodec string
|
||||
VideoCodec string
|
||||
CreatedAt time.Time
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" yaml:"-"`
|
||||
RecordLevel config.EventLevel `json:"eventLevel" desc:"事件级别" gorm:"type:varchar(255);comment:事件级别,high表示重要事件,无法删除且表示无需自动删除,low表示非重要事件,达到自动删除时间后,自动删除;default:'low'"`
|
||||
}
|
||||
)
|
||||
|
||||
@@ -87,6 +88,8 @@ func (r *DefaultRecorder) CreateStream(start time.Time, customFileName func(*Rec
|
||||
if recordJob.Plugin.DB != nil {
|
||||
if recordJob.Event != nil {
|
||||
r.Event.RecordEvent = recordJob.Event
|
||||
r.Event.RecordLevel = recordJob.Event.EventLevel
|
||||
recordJob.Plugin.DB.Save(&r.Event.RecordStream)
|
||||
recordJob.Plugin.DB.Save(&r.Event)
|
||||
} else {
|
||||
recordJob.Plugin.DB.Save(&r.Event.RecordStream)
|
||||
@@ -101,6 +104,7 @@ func (r *DefaultRecorder) WriteTail(end time.Time, tailJob task.IJob) {
|
||||
// 将事件和录像记录关联
|
||||
if r.RecordJob.Event != nil {
|
||||
r.RecordJob.Plugin.DB.Save(&r.Event)
|
||||
r.RecordJob.Plugin.DB.Save(&r.Event.RecordStream)
|
||||
} else {
|
||||
r.RecordJob.Plugin.DB.Save(&r.Event.RecordStream)
|
||||
}
|
||||
@@ -124,6 +128,7 @@ func (p *RecordJob) Subscribe() (err error) {
|
||||
func (p *RecordJob) Init(recorder IRecorder, plugin *Plugin, streamPath string, conf config.Record, subConf *config.Subscribe) *RecordJob {
|
||||
p.Plugin = plugin
|
||||
p.RecConf = &conf
|
||||
p.Event = conf.Event
|
||||
p.StreamPath = streamPath
|
||||
if subConf == nil {
|
||||
conf := p.Plugin.config.Subscribe
|
||||
@@ -203,9 +208,28 @@ type eventRecordCheck struct {
|
||||
|
||||
func (t *eventRecordCheck) Run() (err error) {
|
||||
var eventRecordStreams []EventRecordStream
|
||||
t.DB.Find(&eventRecordStreams, `type=? AND event_level='high' AND stream_path=?`, t.Type, t.streamPath) //搜索事件录像,且为重要事件(无法自动删除)
|
||||
for _, recordStream := range eventRecordStreams {
|
||||
t.DB.Model(&EventRecordStream{}).Where(`event_level='low' AND start_time <= ? and end_time >= ?`, recordStream.EndTime, recordStream.StartTime).Update("event_level", config.EventLevelHigh)
|
||||
queryRecord := EventRecordStream{
|
||||
RecordEvent: &config.RecordEvent{
|
||||
EventLevel: config.EventLevelHigh,
|
||||
},
|
||||
RecordStream: RecordStream{
|
||||
StreamPath: t.streamPath,
|
||||
Type: t.Type,
|
||||
},
|
||||
}
|
||||
t.DB.Where(&queryRecord).Find(&eventRecordStreams) //搜索事件录像,且为重要事件(无法自动删除)
|
||||
if len(eventRecordStreams) > 0 {
|
||||
for _, recordStream := range eventRecordStreams {
|
||||
var unimportantEventRecordStreams []RecordStream
|
||||
query := `start_time <= ? and end_time >= ? and stream_path=? and type=?`
|
||||
t.DB.Where(query, recordStream.EndTime, recordStream.StartTime, t.streamPath, t.Type).Find(&unimportantEventRecordStreams)
|
||||
if len(unimportantEventRecordStreams) > 0 {
|
||||
for _, unimportantEventRecordStream := range unimportantEventRecordStreams {
|
||||
unimportantEventRecordStream.RecordLevel = config.EventLevelHigh
|
||||
t.DB.Save(&unimportantEventRecordStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user