EasyDSS录像计划清理功能的实现分享

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 文件的时间。如果是在需要保留的时间节点内,则不删除,其余情况下进行删除操作。

原文地址:https://www.cnblogs.com/easydss/p/15525260.html