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

  • 相关阅读:
    Factorial Trailing Zeroes
    Convert Integer A to Integer B
    函数防抖、函数节流
    localstorage sessionstorage和cookie的区别
    element中表格中的表头与表格内容边框错位的解决方法
    解决Minio生成图片文件的分享链接无法正常下载的问题
    gin编写后端API的使用技巧
    YOLOV5源码解读-export.py网络结构、配置文件
    《三、YOLOV3细节原理全解析》
    《二、YOLOV2细节原理全解析》
  • 原文地址:https://www.cnblogs.com/easydss/p/15525260.html
Copyright © 2020-2023  润新知