EasyDSS是支持接入RTMP推流摄像头的视频流媒体平台,新版EasyDSS互联网直播点播平台支持创建录像计划,用户可以设定周一至周日中,某天某个时间段内开启录像,其他时间不录像。
EasyDSS包含一个根据录像计划清理录像的功能,是我们在添加录像计划后同步添加的功能,功能实现代码大家可以参考以下:
for _, streamID := range deviceList {
// 遍历所有录像设备
live := &dao.TLive{}
db.First(live, consts.SqlWhereID, streamID)
log.Println("直播id:", streamID)
vlive := &dao.TVlive{}
db.First(vlive, consts.SqlWhereID, streamID)
//如果是负数表示永久保存
//对应设备id的目录
recordPath := filepath.Join(recordRoot, streamID)
// days 已排序
days := efile.GetDirNames(recordPath)
today := time.Now().Format("20060102")
for i := 0; i < len(days); i++ {
dayDir := days[i]
dayPath := filepath.Join(recordPath, dayDir)
// 已经升序排序的秒文件夹
secondDirs := efile.GetDirNamesAsc(dayPath)
secondDirsLen := len(secondDirs)
for ii := 0; ii < secondDirsLen; ii++ {
secondDirPath := filepath.Join(dayPath, secondDirs[ii])
importantPath := filepath.Join(secondDirPath, "important")
// 1. 如果存在 import 文件夹, 不删除文件
if efile.Exisit(importantPath) {
continue
}
// 2. 如果是今天的录像,正在直播,并且是最后一个秒文件夹, 说明是直播的 ts 保留位置,保留配置文件中保留的直播个数 ts 文件
// 暂时不删除,直接 continute,后面优化
if today == dayDir && mediaserver.HasLive(streamID) && ii == secondDirsLen-1 {
continue
}
secondTime := etime.StrYYYYMMDDHHmmssToTime(secondDirs[ii])
week := int(secondTime.Weekday())
// 防止误删,默认可以保存录像
canRecord := true
recordM3u8 := filepath.Join(secondDirPath, fmt.Sprintf("%s_record.m3u8", streamID))
if efile.Exisit(recordM3u8) {
// hV6wpxVnR-20211011220748-436.ts
tsName := efile.GetLastTsName(filepath.Join(secondDirPath, fmt.Sprintf("%s_record.m3u8", streamID)))
tsTimeStrs := strings.Split(tsName, "-")
if len(tsTimeStrs) == 3 {
tsRecordTime, _ := strconv.Atoi(tsTimeStrs[1][8:])
canRecord = CanRecordByPlan(live, week, tsRecordTime)
}
}
if !canRecord {
log.Println("remove record time path : ", secondDirPath)
err := os.RemoveAll(secondDirPath)
if err != nil {
log.Println("删除文件夹 ", secondDirPath, " 失败, error = ", err.Error())
return
}
}
}
secondDirs = efile.GetDirNamesAsc(dayPath)
// 如果所有的子文件夹为空,可以删除天文件夹
if len(secondDirs) == 0 {
efile.RemoveAll(dayPath)
}
}
//如果设备下所有录像都删除了该设备目录也同时删除
allDays := efile.GetDirNames(recordPath)
if len(allDays) == 0 {
//如果不是软连接才删除
if !efile.IsLinkWithPath(recordPath) {
err := os.RemoveAll(recordPath)
log.Println("remove record path : ", recordPath)
if err != nil {
log.Println("删除文件夹 ", recordPath, " 失败, error = ", err.Error())
return
}
}
//删除录像记录
db.Delete(&do.TRecord{}, consts.SqlWhereID, streamID)
}
}
以上代码主要遍历文件夹进行删除操作,其中有几个逻辑如下:
1.如果有 import 文件夹,用户认为是重要视频,则不删除该文件夹
2.如果是正在直播的文件夹,则不删除
3.如果是可以删除的文件夹,则读取 m3u8 文件的最后一个 ts 文件的时间。如果是在需要保留的时间节点内,则不删除,其余情况下进行删除操作。