mirror of
https://github.com/langhuihui/monibuca.git
synced 2026-05-08 05:31:03 +08:00
174 lines
6.3 KiB
Go
174 lines
6.3 KiB
Go
package plugin_mp4
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/shirou/gopsutil/v4/disk"
|
|
"gorm.io/gorm"
|
|
"m7s.live/v5"
|
|
"m7s.live/v5/pkg/task"
|
|
)
|
|
|
|
// mysql数据库里Exception 定义异常结构体
|
|
type Exception struct {
|
|
CreateTime string `json:"createTime" gorm:"type:varchar(50)"`
|
|
AlarmType string `json:"alarmType" gorm:"type:varchar(50)"`
|
|
AlarmDesc string `json:"alarmDesc" gorm:"type:varchar(50)"`
|
|
ServerIP string `json:"serverIP" gorm:"type:varchar(50)"`
|
|
StreamPath string `json:"streamPath" gorm:"type:varchar(50)"`
|
|
}
|
|
|
|
// // 向第三方发送异常报警
|
|
// func (p *MP4Plugin) SendToThirdPartyAPI(exception *Exception) {
|
|
// exception.CreateTime = time.Now().Format("2006-01-02 15:04:05")
|
|
// exception.ServerIP = p.GetCommonConf().PublicIP
|
|
// data, err := json.Marshal(exception)
|
|
// if err != nil {
|
|
// p.Error("SendToThirdPartyAPI", " marshalling exception error", err.Error())
|
|
// return
|
|
// }
|
|
// err = p.DB.Create(&exception).Error
|
|
// if err != nil {
|
|
// p.Error("SendToThirdPartyAPI", "insert into db error", err.Error())
|
|
// return
|
|
// }
|
|
// resp, err := http.Post(p.ExceptionPostUrl, "application/json", bytes.NewBuffer(data))
|
|
// if err != nil {
|
|
// p.Error("SendToThirdPartyAPI", "Error sending exception to third party API error", err.Error())
|
|
// return
|
|
// }
|
|
// defer resp.Body.Close()
|
|
|
|
// if resp.StatusCode != http.StatusOK {
|
|
// p.Error("SendToThirdPartyAPI", "Failed to send exception, status code:", resp.StatusCode)
|
|
// } else {
|
|
// p.Info("SendToThirdPartyAPI", "Exception sent successfully!")
|
|
// }
|
|
// }
|
|
|
|
// // 磁盘超上限报警
|
|
// func (p *DeleteRecordTask) getDisckException(streamPath string) bool {
|
|
// if p.getDiskOutOfSpace(p.DiskMaxPercent) {
|
|
// exceptionChannel <- &Exception{AlarmType: "disk alarm", AlarmDesc: "disk is full", StreamPath: streamPath}
|
|
// return true
|
|
// }
|
|
// return false
|
|
// }
|
|
|
|
// 判断磁盘使用量是否中超限
|
|
func (p *DeleteRecordTask) getDiskOutOfSpace(filePath string) bool {
|
|
exePath := filepath.Dir(filePath)
|
|
d, err := disk.Usage(exePath)
|
|
if err != nil || d == nil {
|
|
p.Error("getDiskOutOfSpace", "error", err)
|
|
return false
|
|
}
|
|
p.plugin.Debug("getDiskOutOfSpace", "current path", exePath, "disk UsedPercent", d.UsedPercent, "total disk space", d.Total,
|
|
"disk free", d.Free, "disk usage", d.Used, "AutoOverWriteDiskPercent", p.AutoOverWriteDiskPercent, "DiskMaxPercent", p.DiskMaxPercent)
|
|
return d.UsedPercent >= p.AutoOverWriteDiskPercent
|
|
}
|
|
|
|
func (p *DeleteRecordTask) deleteOldestFile() {
|
|
//当当前磁盘使用量大于AutoOverWriteDiskPercent自动覆盖磁盘使用量配置时,自动删除最旧的文件
|
|
//连续录像删除最旧的文件
|
|
// 创建一个数组来存储所有的conf.FilePath
|
|
var filePaths []string
|
|
if len(p.plugin.GetCommonConf().OnPub.Record) > 0 {
|
|
for _, conf := range p.plugin.GetCommonConf().OnPub.Record {
|
|
// 处理路径,去掉最后的/$0部分,只保留目录部分
|
|
dirPath := filepath.Dir(conf.FilePath)
|
|
p.Info("deleteOldestFile", "original filepath", conf.FilePath, "processed filepath", dirPath)
|
|
filePaths = append(filePaths, dirPath)
|
|
}
|
|
}
|
|
if p.plugin.EventRecordFilePath != "" {
|
|
// 同样处理EventRecordFilePath
|
|
dirPath := filepath.Dir(p.plugin.EventRecordFilePath)
|
|
filePaths = append(filePaths, dirPath)
|
|
}
|
|
for _, filePath := range filePaths {
|
|
for p.getDiskOutOfSpace(filePath) {
|
|
queryRecord := m7s.RecordStream{
|
|
EventLevel: m7s.EventLevelLow, // 查询条件:event_level = 1,非重要事件
|
|
}
|
|
var eventRecords []m7s.RecordStream
|
|
// 使用不同的方法进行路径匹配,避免ESCAPE语法问题
|
|
// 解决方案:用MySQL能理解的简单方式匹配路径前缀
|
|
basePath := filePath
|
|
// 直接替换所有反斜杠,不需要判断是否包含
|
|
basePath = strings.Replace(basePath, "\\", "\\\\", -1)
|
|
searchPattern := basePath + "%"
|
|
p.Info("deleteOldestFile", "searching with path pattern", searchPattern)
|
|
|
|
err := p.DB.Where(&queryRecord).Where("end_time IS NOT NULL").
|
|
Where("file_path LIKE ?", searchPattern).
|
|
Order("end_time ASC").Find(&eventRecords).Error
|
|
if err == nil {
|
|
if len(eventRecords) > 0 {
|
|
p.Info("deleteOldestFile", "found %d records", len(eventRecords))
|
|
for _, record := range eventRecords {
|
|
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 {
|
|
p.Error("deleteOldestFile", "delete file from disk error", err)
|
|
continue
|
|
} else {
|
|
err = p.DB.Delete(&record).Error
|
|
if err != nil {
|
|
p.Error("deleteOldestFile", "delete record from disk error", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
p.Error("deleteOldestFile", "search record from db error", err)
|
|
}
|
|
time.Sleep(time.Second * 3)
|
|
}
|
|
}
|
|
}
|
|
|
|
type DeleteRecordTask struct {
|
|
task.TickTask
|
|
DiskMaxPercent float64
|
|
AutoOverWriteDiskPercent float64
|
|
RecordFileExpireDays int
|
|
DB *gorm.DB
|
|
plugin *MP4Plugin
|
|
}
|
|
|
|
func (t *DeleteRecordTask) GetTickInterval() time.Duration {
|
|
return 1 * time.Minute
|
|
}
|
|
|
|
func (t *DeleteRecordTask) Tick(any) {
|
|
t.deleteOldestFile()
|
|
if t.RecordFileExpireDays <= 0 {
|
|
return
|
|
}
|
|
//搜索event_records表中event_level值为1的(非重要)数据,并将其create_time与当前时间比对,大于RecordFileExpireDays则进行删除,数据库标记is_delete为1,磁盘上删除录像文件
|
|
var eventRecords []m7s.RecordStream
|
|
expireTime := time.Now().AddDate(0, 0, -t.RecordFileExpireDays)
|
|
t.Debug("RecordFileExpireDays is set to auto delete oldestfile", "expireTime", expireTime.Format("2006-01-02 15:04:05"))
|
|
queryRecord := m7s.RecordStream{
|
|
EventLevel: m7s.EventLevelLow, // 查询条件:event_level = low,非重要事件
|
|
}
|
|
err := t.DB.Where(&queryRecord).Find(&eventRecords, "end_time < ? AND end_time IS NOT NULL", expireTime).Error
|
|
if err == nil {
|
|
for _, record := range eventRecords {
|
|
t.Info("RecordFileExpireDays is set to auto delete oldestfile", "ID", record.ID, "create time", record.EndTime, "filepath", record.FilePath)
|
|
err = os.Remove(record.FilePath)
|
|
if err != nil {
|
|
t.Error("RecordFileExpireDays set to auto delete oldestfile", "delete file from disk error", err)
|
|
}
|
|
err = t.DB.Delete(&record).Error
|
|
if err != nil {
|
|
t.Error("RecordFileExpireDays set to auto delete oldestfile", "delete record from db error", err)
|
|
}
|
|
}
|
|
}
|
|
}
|