fix: delete oldest mp4 file

This commit is contained in:
pggiroro
2025-07-23 17:04:41 +08:00
parent 15d830f1eb
commit e4810e9c55
4 changed files with 60 additions and 22 deletions

View File

@@ -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",
},
})
}

View File

@@ -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 {

View File

@@ -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:"事件录像存放地址"`
}

View File

@@ -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
}