前段时间给家里装了个YCC365plus摄像头,结果发现最头疼的不是摄像头本身,而是那张小小的内存卡,装进去容易,但想把它拍的那些视频好好用起来,却折腾了我好几个晚上,作为一个写Go语言的程序员,我习惯性地想:能不能用代码来搞定这些视频文件?还真让我摸索出一些门道。

为什么YCC365plus的内存卡视频这么“难搞”?
先说说这张卡,我买的是一张64GB的Class 10存储卡,装进YCC365plus后,摄像头会自己格式化,然后就开始录,但问题来了——录出来的视频文件,不是普通手机直接能播放的格式。
- 视频文件是 .mp4 格式,但编码方式特殊
- 文件按时间片段存储,一段大概5分钟
- 文件名是一串数字,mp4
- 直接用Windows播放器打开,有时会卡住
我试过把卡拔出来插电脑上,用资源管理器一看,好家伙,根目录下有个 DCIM 文件夹,里面又按日期分了子文件夹,这种目录结构,跟Go语言里的 os.File 操作简直是绝配。
用Go语言写个工具,批量处理视频
作为Go语言老用户,我第一反应就是写个小程序,先列个需求清单:
- 遍历所有日期文件夹
- 筛选出视频文件(后缀名是.mp4)
- 按照时间顺序合并成一个大文件
- 顺便修复一下播放兼容性
下面是我写的核心代码片段,Go的 filepath.Walk 函数太好用了,遍历目录就跟喝水一样简单:
package main
import (
"fmt"
"io"
"os"
"path/filepath"
"sort"
"strings"
)
func main() {
root := "E:/DCIM" // 内存卡盘符
var files []string
filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && strings.HasSuffix(info.Name(), ".mp4") {
files = append(files, path)
}
return nil
})
sort.Strings(files) // 按文件名排序,就是按时间排序
outFile, _ := os.Create("merged_video.mp4")
defer outFile.Close()
for _, f := range files {
inFile, _ := os.Open(f)
io.Copy(outFile, inFile)
inFile.Close()
fmt.Println("合并了:", f)
}
fmt.Println("搞定!")
}
这段代码跑起来后,看着控制台一行行输出文件名,我还有点小激动,不过后来发现直接拼接MP4文件有个大问题——音视频同步会乱,因为每个片段有自己的时间戳。
进阶方案:用ffmpeg配合Go
既然纯拼接不行,我换了个思路:用Go调用 ffmpeg 来处理,ffmpeg这个开源工具,处理视频简直是神器。
import "os/exec"
func mergeWithFFmpeg(fileList []string, output string) {
// 先生成一个文件列表
listFile, _ := os.Create("filelist.txt")
for _, f := range fileList {
listFile.WriteString(fmt.Sprintf("file '%s'\n", f))
}
listFile.Close()
cmd := exec.Command("ffmpeg",
"-f", "concat",
"-safe", "0",
"-i", "filelist.txt",
"-c", "copy",
output)
cmd.Run()
}
这次跑出来的视频,播放起来丝滑多了,YCC365plus录的每段视频之间衔接得严丝合缝,就跟原生录制的一样。后来查资料才知道,这是因为ffmpeg的concat协议能正确处理时间戳。
内存卡里的视频,哪些值得留?
折腾了这么久,我也总结出一些经验:
| 视频类型 | 保留建议 | 处理方式 |
|---|---|---|
| 运动检测触发片段 | 保留一周 | 按事件分类存储 |
| 24小时连续录制 | 只留关键时段 | 用Go脚本按天压缩 |
| 报警前后3分钟 | 永久保留 | 自动备份到NAS |
特别注意:YCC365plus的内存卡写入速度不能低于 Class 10,不然录4K视频会丢帧,我一开始用的老卡,经常出现视频文件损坏,换卡后才正常。
顺带解决播放器兼容问题
有的朋友说视频在手机上打不开,这个其实跟内存卡没关系,YCC365plus生成的视频是 H.265编码,老款手机硬解不支持,解决办法:
- 用上面写的Go工具,加一行转码命令:
-c:v libx264 - 或者装个 VLC播放器,什么格式通吃
- 也可以像我一样,写个简单的 HTTP服务器,用浏览器播放
Go标准库里的 net/http 直接就能当文件服务器用,把内存卡目录挂上去,手机扫码就能看,这比什么私有云都来得直接。
写代码的时候我还在想,要是YCC365plus能直接支持 RTSP 协议就好了,省得每次拔卡,后来转念一想,拔卡跑代码,不正是程序员的浪漫么?
本文来自作者[kyadmin]投稿,不代表be365立场,如若转载,请注明出处:http://www.hljbesthome.com/nba/1153.html
评论列表(4条)
我是be365的签约作者“kyadmin”!
希望本篇文章《装YCC365plus的内存卡的视频,从买到用,一个Go语言程序员的手记》能对你有所帮助!
本站[be365]内容主要涵盖:be365,be365网站,be365网址,ball365体育,Be365排名
本文概览:前段时间给家里装了个YCC365plus摄像头,结果发现最头疼的不是摄像头本身,而是那张小小的内存卡,装进去容易,但想把它拍的那些视频好...