用Golang搞定sh365智能摄像头的视频拷贝,这事儿其实没那么玄乎

说实话,我第一次拿到sh365智能摄像头的时候,心里想的就是:这玩意儿能不能把视频直接拷出来?毕竟家里有娃,每天得记录点成长瞬间,总不能...

说实话,我第一次拿到sh365智能摄像头的时候,心里想的就是:这玩意儿能不能把视频直接拷出来?毕竟家里有娃,每天得记录点成长瞬间,总不能老盯着手机屏幕截图吧,后来折腾了一圈,发现用Golang写个小工具,其实挺顺手的。

为什么非要自己写代码?

你可能觉得,买个摄像头不就是为了省事吗?但sh365的官方APP有个坑——导出的视频要么压缩得厉害,要么就是带着水印,我试过用手机直接存,结果空间没几天就满了,后来一查,sh365其实支持本地存储和网络存储,但官方没给PC端好用的工具。

这时候Golang就派上用场了,它编译出来就一个二进制文件,丢到Linux服务器、Windows笔记本甚至树莓派上都能跑,不挑环境,而且并发处理能力不错,适合多路视频流。

第一步:搞清楚sh365的视频存在哪

sh365的存储逻辑其实挺朴素的:

用Golang搞定sh365智能摄像头的视频拷贝,这事儿其实没那么玄乎

  • 本地SD卡:直接插卡,格式一般是FAT32,视频文件按日期分文件夹
  • 云端:通过RTMP或者私有协议推流
  • NAS:部分型号支持SMB或NFS挂载

我们的目标是把SD卡里的视频拷贝到电脑,但有个问题:sh365默认会把视频切成5分钟一段的MP4文件,而且文件名是一串时间戳 + 随机数,看着像20250315_143022_AB3C.mp4这种。

第二步:Golang代码核心思路

写代码前,先理一下需求:

  1. 自动挂载摄像头的SD卡共享目录(如果摄像头支持SMB)
  2. 扫描指定目录,过滤出MP4文件
  3. 按日期归类拷贝到本地
  4. 避免重复拷贝——已经存在的就跳过

我当时写了个大概结构,大概长这样:

package main
import (
    "io"
    "os"
    "path/filepath"
    "time"
)

这只是个骨架,真正的难点在于处理摄像头网络不稳定的情况,sh365有时候会掉线,你得加个重试机制。

我跟你说个坑:一开始我用HTTP方式拉流,结果发现sh365的HTTP接口返回的是实时流,不是文件,后来查了官方文档(其实也就一页PDF),才知道得用SMB协议访问SD卡,于是用了samaritan库,模拟Windows文件共享那种方式。

关键代码片段

// 遍历文件夹,按日期创建本地目录
func copyVideo(source, dest string) error {
    err := filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }
        if info.IsDir() {
            return nil
        }
        if filepath.Ext(path) != ".mp4" {
            return nil
        }
        // 按文件修改时间归类
        t := info.ModTime()
        dirName := t.Format("2006-01-02")
        targetDir := filepath.Join(dest, dirName)
        os.MkdirAll(targetDir, 0755)
        // 拷贝文件
        srcFile, _ := os.Open(path)
        defer srcFile.Close()
        dstFile, _ := os.Create(filepath.Join(targetDir, info.Name()))
        defer dstFile.Close()
        io.Copy(dstFile, srcFile)
        return nil
    })
    return err
}

这段代码看起来简单吧?但实际跑的时候,sh365的SMB服务经常超时,我加了3次重试,每次间隔5秒,才稳定下来。

第三步:处理sh365特有的文件格式

sh365的MP4文件有点特别——它里面封装的视频编码是H.265,但文件扩展名还是.mp4,有些播放器不认,拷贝后还得转码,不过我没在工具里做转码,因为Golang处理视频编码比较吃力,我建议用ffmpeg做后处理。

我搞了个简单的配置表,方便你调整参数:

参数 说明 默认值
source sh365 SD卡挂载路径 /mnt/sh365
dest 本地存储路径 ./videos
retry 拷贝失败重试次数 3
filter 文件类型过滤 .mp4
organize 是否按日期归类 true

踩过的几个大坑

  1. 权限问题:sh365的SMB默认用户是admin,密码留空,但有些固件版本必须设密码,最好手动设一个。

  2. 文件名乱码:sh365的文件名里带了中文字符?不,它全是英文和数字,但文件夹名可能是中文(录像”),在Golang里用basepath得注意UTF-8编码。

  3. 视频文件损坏:有时候摄像头断电,SD卡上的视频没写完,拷贝时得校验文件大小,我这个版本直接跳过了小于1MB的文件——大概率是残片。

  4. 网络速度:用SMB拷贝,百兆局域网大概能跑12MB/s,够用,但如果你用Wi-Fi,sh365的2.4G频段可能会掉速,建议用有线连接或者5G频段。

提升效率的小技巧

后来我加了点功能:过滤掉太老的视频,比如默认只拷贝7天内的,避免把一年前的监控视频也拉下来——那东西占空间还没用。

// 只拷贝最近7天的视频
if time.Since(t) > 7*24*time.Hour {
    return nil
}

还加了一个总进度条,虽然Golang标准库没有,但我用了第三方包pb,每次拷贝文件都显示百分比。用起来感觉像是真正的工具,而不是临时脚本。

实际运行效果

我现在每天晚上10点跑一次这个程序,大概3分钟能拷贝完一天的视频(大约2GB),然后我用crontab定时执行,完全不用管,sh365的SD卡满了之后,会自动覆盖最早的视频,但我的本地硬盘已经存好了,不慌

我还在程序里记了log,哪些文件拷贝失败,哪些跳过,写成个文本文件,第二天看一眼就心里有数。

这个方案比起用手机APP一个一个下载,省了大概80%的时间,而且Golang写的程序,我丢到一台旧笔记本上跑,功耗才10瓦,24小时开着也没事。

对了,刚开始我还想加个远程控制摄像头的功能,后来发现sh365的API没开放,只给了视频流地址,不过这东西本来就不是让你编程的,能用就行。

现在每天回家,打开电脑看看白天的监控片段,一边撸猫一边手动删掉那些没用的(比如对着一堵墙录了半小时的)。也没必要太自动化,留点手工活儿反而踏实。

本文来自作者[kyadmin]投稿,不代表be365立场,如若转载,请注明出处:http://www.uss1.cn/lvyou/548.html

(2)

文章推荐

发表回复

本站作者才能评论

评论列表(4条)

  • kyadmin
    kyadmin 2026-06-29

    我是be365的签约作者“kyadmin”!

  • kyadmin
    kyadmin 2026-06-29

    希望本篇文章《用Golang搞定sh365智能摄像头的视频拷贝,这事儿其实没那么玄乎》能对你有所帮助!

  • kyadmin
    kyadmin 2026-06-29

    本站[be365]内容主要涵盖:be365,be365网站,be365网址,ball365体育,Be365排名

  • kyadmin
    kyadmin 2026-06-29

    本文概览:说实话,我第一次拿到sh365智能摄像头的时候,心里想的就是:这玩意儿能不能把视频直接拷出来?毕竟家里有娃,每天得记录点成长瞬间,总不能...

    联系我们

    工作时间:周一至周五,9:30-18:30,节假日休息

    关注我们