最近帮邻居老王折腾他那个监控摄像头的时候,突然发现icam365这个软件里存了不少视频,但有些片段明显是没用的——比如他家的猫在镜头前发呆的那十分钟,老王问我:“icam365怎么删除一段视频啊?我这手机里存了快3个G了。”
我想着,这事儿既然能用代码解决,不如就用Golang写个小工具来批量处理,说实话,刚开始我也以为这软件会很复杂,结果研究了一下,发现它其实就是把视频文件按时间戳存在特定目录下,比如/storage/icam365/records/2025/03/21/14_30_00.mp4这种格式,那删除特定时间段内的视频,本质上就是按文件名匹配时间范围再执行删除操作。
理解icam365的视频存储结构
我们先得搞清楚视频文件到底存在哪,以我在老王手机上看到的为例,icam365会把视频文件放在:

- 内部存储:Android/data/com.icam365/files/Records/
- 外部SD卡:path可能类似/storage/XXXX-XXXX/ICAM365/Record/
每个文件名包含日期和时间,格式通常是YYYYMMDD_HHMMSS.mp4,比如20250321_143000.mp4就代表2025年3月21日14点30分00秒开始的那段视频。
| 文件名组成部分 | 示例 | 含义 |
|---|---|---|
| YYYYMMDD | 20250321 | 日期 |
| HHMMSS | 143000 | 时间(24小时制) |
| 扩展名 | .mp4 | 视频文件格式 |
用Golang写一个删除指定段落的脚本
我写的时候其实踩了好几个坑,比如时间解析的时区问题,还有文件名大小写的坑,下面是我最终跑通的版本:
package main
import (
"fmt"
"io/ioutil"
"path/filepath"
"strings"
"time"
"os"
)
func main() {
// 这里要改成你自己的icam365存储路径
basePath := "/storage/emulated/0/ICAM365/record"
// 定义要删除的时间段:2025年3月21日14:30:00到14:40:00
startTime, _ := time.Parse("2006-01-02 15:04:05", "2025-03-21 14:30:00")
endTime, _ := time.Parse("2006-01-02 15:04:05", "2025-03-21 14:40:00")
files, err := ioutil.ReadDir(basePath)
if err != nil {
fmt.Println("读取目录失败:", err)
return
}
for _, file := range files {
if file.IsDir() {
continue
}
// 只处理.mp4文件
if !strings.HasSuffix(strings.ToLower(file.Name()), ".mp4") {
continue
}
// 解析文件名中的时间戳
// 假设文件名格式:20250321_143000.mp4
namePart := strings.TrimSuffix(file.Name(), ".mp4")
parts := strings.Split(namePart, "_")
if len(parts) != 2 {
continue // 格式不符就跳过
}
datePart := parts[0] // 20250321
timePart := parts[1] // 143000
// 拼接成完整时间字符串
timeStr := fmt.Sprintf("%s-%s-%s %s:%s:%s",
datePart[0:4], datePart[4:6], datePart[6:8],
timePart[0:2], timePart[2:4], timePart[4:6])
fileTime, err := time.Parse("2006-01-02 15:04:05", timeStr)
if err != nil {
fmt.Printf("解析时间失败:%s -> %s\n", file.Name(), err)
continue
}
// 如果文件时间在目标区间内,就删除
if (fileTime.Equal(startTime) || fileTime.After(startTime)) &&
(fileTime.Equal(endTime) || fileTime.Before(endTime)) {
fullPath := filepath.Join(basePath, file.Name())
err := os.Remove(fullPath)
if err != nil {
fmt.Printf("删除失败:%s - %s\n", fullPath, err)
} else {
fmt.Printf("已删除:%s\n", file.Name())
}
}
}
}
注意事项和常见问题
写这个脚本的时候,我其实忽略了几个细节,后来调试了半小时才发现,首先是时间区间判断——如果你只想删除14:30:00到14:40:00之间的,那包含起始点和终点吗?我上面代码用的是>=和<=,也就是包含两端,如果你想只删中间不包含端点,把Equal去掉就行。
还有一个容易翻车的点:icam365的文件名有时候会带后缀,比如20250321_143000_A.mp4这种情况,上述代码的len(parts) != 2判断就会跳过这类文件,因为下划线分割后得到3部分,解决办法?可以在循环里再加一个分支逻辑,判断parts[0]是否是纯数字日期、parts[1]是否是纯数字时间。
实际跑一遍看看
我拿老王的手机连到电脑上试了一次,首先用adb shell进去,定位到目录:
$ ls /storage/emulated/0/ICAM365/record/ 20250321_142900.mp4 20250321_143000.mp4 20250321_143500.mp4 20250321_144000.mp4 20250321_144500.mp4
然后交叉编译这个Golang脚本(因为目标设备是ARM架构),GOOS=linux GOARCH=arm64 go build -o del_video,拷贝到手机里运行后,输出:
已删除:20250321_143000.mp4
已删除:20250321_143500.mp4
已删除:20250321_144000.mp4
我回头再检查,发现142900(14:29:00)和144500(14:45:00)没被删,刚好符合预期。
如果连不上电脑怎么办?
有不少朋友可能手边没有电脑,或者不想用ADB,那可以试试直接在手机上用Termux这种终端模拟器,一样能跑Golang,安装Go环境后,把脚本放进去编译执行,不过要注意,有些手机权限比较严,可能读不了Android/data下的目录,这时候就得root或者用adb shell来提权。
对了,还有一种更简单粗暴的办法——写一个Shell脚本,用find命令配合正则匹配,但说实话Golang写起来更安全,尤其是文件名里万一有特殊字符的时候。
关于精确删除的思考
写到这儿,我发现一个问题:icam365的视频长度不固定,有的片段是30秒,有的可能2分钟,如果你只想删除其中某一段,比如14:32:00到14:35:00之间的画面,那靠文件名匹配就不太行了,因为文件名只记录开始时间,无法知道视频内部的时间轴。
这时候就得用FFmpeg来先切视频再删,思路是:找到包含目标时段的视频文件,用ffmpeg -i input.mp4 -ss 00:01:30 -t 00:03:00 -c copy output.mp4提取出不要的部分,然后删除原文件,再把剩余片段合并,不过这个就涉及到更复杂的视频处理了,Golang里可以用os/exec包调用FFmpeg命令行,或者用github.com/asticode/go-astits这种库来解析MP4容器,有点复杂,下次可以单独写一篇。
最后聊两句
其实icam365官方APP里自带了片段删除功能,但只能一段一段删,不能按时间段批量操作,像我帮老王清掉那3G视频,如果一个个点,得点几百次,用这个Golang脚本,几秒钟搞定,而且代码写完了还能复用——只要改改路径和时间参数,下次用直接跑就行。
操作前建议先备份重要视频,比如用cp -r复制整个Record目录到别处,毕竟删错了就找不回来了,别问我怎么知道的。
本文来自作者[kyadmin]投稿,不代表be365立场,如若转载,请注明出处:http://www.uss1.cn/jiankang/1019.html
评论列表(4条)
我是be365的签约作者“kyadmin”!
希望本篇文章《用Golang写一篇关于icam365怎么删除一段视频的实用指南》能对你有所帮助!
本站[be365]内容主要涵盖:be365,be365网站,be365网址,ball365体育,Be365排名
本文概览:最近帮邻居老王折腾他那个监控摄像头的时候,突然发现icam365这个软件里存了不少视频,但有些片段明显是没用的——比如他家的猫在镜头前发...