工控安卓无人柜视频按需录制:开柜触发录制、循环覆写、存储管控方案

发布时间:2026/10/26 6:52:24

工控安卓无人柜视频按需录制:开柜触发录制、循环覆写、存储管控方案 工控安卓无人柜视频按需录制开柜触发录制、循环覆写、存储管控方案大家好我是黒漂技术佬。从今天开始进入第五篇章视频录制与上传专题。无人售货柜为什么要录像两个原因一是丢货了能溯源二是出现纠纷有证据。但24小时录肯定不现实存储和流量都扛不住。所以就有了按需录制——开门的时候录平时待机。今天咱们就把售货柜的视频录制方案从硬件到软件讲清楚。一、售货柜视频录制的需求特点先明确需求售货柜的视频监控跟普通家用监控不一样。核心需求对比维度普通家用监控无人售货柜录制模式24小时连续录制事件触发按需录制存储周期存7天~30天存3~7天循环覆写清晰度要求越高越好能看清人脸和拿了什么就行上传要求实时预览回放异常时才上传平时本地存功耗要求插电无所谓要考虑整体功耗和散热稳定性偶尔死机没事必须稳定关键时刻不能掉链子核心一句话只在需要的时候录录了存本地出问题再上传。二、摄像头选型与接入方式常见的摄像头方案方案接口优点缺点USB摄像头USB便宜接入简单免驱画质一般长距离不行内置IPCRJ45/RTSP画质好功能多成本高需要网络MIPI摄像头MIPI接口集成度高功耗低需要驱动适配定制化强工业相机USB3.0/GigE画质最好专业贵大材小用主流方案USB摄像头性价比最高安卓免驱直接用。安卓摄像头API选择API说明适用场景Camera1老API简单基础录制兼容性好Camera2新API功能强需要精细控制参数CameraXJetpack库封装好快速开发兼容性好工控设备一般用Camera1或者直接封装好的库稳定最重要。三、事件触发录制机制触发源设计哪些事件触发录像触发事件优先级录制时长说明开门事件高开门后录30~60秒核心每次开门必录异常开门最高2分钟持续没指令门开了多录一会儿震动/倾倒高1分钟有人碰柜子、踹柜子人脸检测中有人的时候录有人靠近就录增加安防手动触发高自定义后台远程触发录像定时巡检低10秒每天拍几秒确认摄像头没坏开门触发录制流程收到开门指令 ↓ 开始录像提前2秒开门瞬间不能漏 ↓ 门打开开始交易 ↓ 门关上 ↓ 继续录10~15秒确认人走了 ↓ 停止录像保存文件 ↓ 关联订单号存入数据库录制管理器实现publicclassVideoRecordManager{privateMediaRecordermediaRecorder;privateCameracamera;privatebooleanisRecordingfalse;privateStringcurrentRecordFile;/** * 开始录制 * param eventType 触发事件类型 * param relatedId 关联ID比如订单号 * param duration 预计录制时长毫秒 */publicsynchronizedbooleanstartRecord(StringeventType,StringrelatedId,intduration){if(isRecording){Log.w(Video,已经在录制中追加时长);extendRecord(duration);returntrue;}try{// 1. 打开摄像头cameraCamera.open(Camera.CameraInfo.CAMERA_FACING_BACK);Camera.Parametersparamscamera.getParameters();params.setPreviewSize(1280,720);// 720P够了camera.setParameters(params);// 2. 创建输出文件currentRecordFilegenerateVideoFilePath(eventType,relatedId);// 3. 配置MediaRecordermediaRecordernewMediaRecorder();camera.unlock();mediaRecorder.setCamera(camera);mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 视频参数720P15帧码率1Mbps文件不大也够用mediaRecorder.setVideoSize(1280,720);mediaRecorder.setVideoFrameRate(15);mediaRecorder.setVideoEncodingBitRate(1024*1024);mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);// 音频参数mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);mediaRecorder.setAudioEncodingBitRate(64000);mediaRecorder.setAudioSamplingRate(8000);mediaRecorder.setOutputFile(currentRecordFile);mediaRecorder.setMaxDuration(duration);// 最大录制时长// 4. 准备并开始mediaRecorder.prepare();mediaRecorder.start();isRecordingtrue;Log.i(Video,开始录制: currentRecordFile);// 5. 记录到数据库VideoRecordDb.getInstance().insert(currentRecordFile,eventType,relatedId,System.currentTimeMillis());returntrue;}catch(Exceptione){Log.e(Video,开始录制失败,e);releaseCamera();returnfalse;}}/** * 停止录制 */publicsynchronizedvoidstopRecord(){if(!isRecording){return;}try{mediaRecorder.stop();mediaRecorder.reset();isRecordingfalse;// 更新文件大小和结束时间VideoRecordDb.getInstance().updateFileInfo(currentRecordFile);Log.i(Video,停止录制: currentRecordFile);}catch(Exceptione){Log.e(Video,停止录制失败,e);}finally{releaseCamera();}}}预录制功能进阶开门事件触发的时候再开始录开门那一瞬间可能已经漏了。可以做个循环缓冲区一直保留最近几秒的画面循环缓冲区一直存最近5秒的画面 ↓ 触发开门事件 ↓ 先把缓冲区的5秒写进文件 ↓ 再继续录后面的 ↓ 这样开门前几秒的画面也能保留实现起来复杂一点需要自己编码管理缓冲区对安防要求高的场景可以做。四、视频参数调优分辨率、帧率、码率怎么选这三个参数直接决定了文件大小和画质要平衡好。参数推荐值说明分辨率720P (1280x720)售货柜足够了看清人脸和商品没问题帧率15fps不用太高15帧够看省空间省算力视频码率1Mbps720P 15帧 1Mbps画质可以接受音频8kHz 64kbps AAC能听清声音就行文件大小估算按上面的参数每秒视频大约1Mbps / 8 125KB每分钟大约125KB × 60 7.5MB每次开门录1分钟约7.5MB每天开门50次约375MB存7天约2.6GB配个8G的TF卡循环存7天完全够用。五、循环存储与自动清理循环覆写机制存储空间有限满了就自动删最老的publicclassVideoStorageManager{privatestaticfinallongMAX_STORAGE_SIZE4L*1024*1024*1024;// 最多用4GprivatestaticfinallongMIN_FREE_SPACE500*1024*1024;// 最少留500M/** * 检查存储空间不够就删老视频 */publicvoidcheckAndCleanStorage(){longusedSizegetUsedSize();longfreeSpacegetFreeSpace();// 用超了或者剩余太少就清理if(usedSizeMAX_STORAGE_SIZE||freeSpaceMIN_FREE_SPACE){cleanOldVideos();}}privatevoidcleanOldVideos(){// 按时间从老到新排序ListVideoRecordrecordsVideoRecordDb.getInstance().queryAllOrderByTime();for(VideoRecordrecord:records){// 还没上传的先别删if(record.getUploadStatus()UPLOAD_STATUS_PENDING){continue;}// 删除文件FilefilenewFile(record.getFilePath());if(file.exists()){file.delete();VideoRecordDb.getInstance().delete(record.getId());}// 删到空间够了就停if(getFreeSpace()MIN_FREE_SPACEgetUsedSize()MAX_STORAGE_SIZE){break;}}}}清理策略注意事项未上传的不删还没传到云端的视频不能删不然丢了重要事件的不删异常开门、告警视频单独标记保留时间长一点定时清理不用每次录完都清每天凌晨清理一次就行预留空间一定要留富余别存满了才删录的时候写失败就麻烦了六、存储空间监控磁盘空间监控定期检查存储状态快满了提前告警publicclassStorageMonitor{publicvoidcheckStorageStatus(){FilevideoDirgetVideoDirectory();longtotalvideoDir.getTotalSpace();longfreevideoDir.getFreeSpace();longusedtotal-free;intusagePercent(int)(used*100/total);if(usagePercent90){// 严重告警存储快满了reportStorageAlarm(usagePercent);}elseif(usagePercent80){// 预警reportStorageWarning(usagePercent);}}}TF卡异常检测TF卡很容易坏要能检测到publicbooleancheckSdCardHealth(){// 1. 检查是否挂载if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){Log.e(Storage,TF卡未挂载);returnfalse;}// 2. 尝试读写测试FiletestFilenewFile(getVideoDirectory(),.test);try{FileOutputStreamfosnewFileOutputStream(testFile);fos.write(test.getBytes());fos.close();if(!testFile.exists()||testFile.length()!4){returnfalse;}testFile.delete();returntrue;}catch(IOExceptione){Log.e(Storage,TF卡读写测试失败,e);returnfalse;}}TF卡坏了要及时告警不然关键时刻录不了像就麻烦了。七、视频文件管理文件命名规范文件名要包含关键信息方便排查视频目录/ ├── 20260708/ │ ├── open_20260708_153022_O123456.mp4 开门录像_订单号 │ ├── abnormal_20260708_160000.mp4 异常开门录像 │ └── shake_20260708_170000.mp4 震动触发录像 └── 20260709/ └── ...按天分目录文件名包含事件类型、时间、关联ID找起来方便。视频数据库存一份数据库记录方便查询和管理CREATETABLEvideo_record(idINTEGERPRIMARYKEYAUTOINCREMENT,file_pathVARCHAR(256),-- 文件路径file_sizeINTEGER,-- 文件大小字节event_typeVARCHAR(32),-- 事件类型related_idVARCHAR(64),-- 关联ID订单号等start_timeBIGINT,-- 开始时间durationINTEGER,-- 时长秒upload_statusINTEGERDEFAULT0,-- 上传状态0未上传 1上传中 2已上传 3上传失败upload_timeBIGINT,-- 上传时间is_importantINTEGERDEFAULT0-- 是否重要重要的不自动删);八、后台录像与功耗优化后台录制保活录像的时候APP退后台了不能被系统杀了启动前台服务挂个通知加入系统白名单工控机一般可以录制期间提高进程优先级// 用前台服务保证录制不被杀publicclassRecordServiceextendsService{OverridepublicintonStartCommand(Intentintent,intflags,intstartId){NotificationnotificationbuildNotification();startForeground(NOTIFICATION_ID,notification);returnSTART_STICKY;}}功耗优化不用摄像头的时候赶紧释放别一直占着预览能不开就不开只录制不预览省资源帧率和码率按需调整不用太高散热不好的设备长时间录制要注意温度九、踩坑经验坑1录制一半APP被杀文件损坏现象异常中断的MP4文件打不开原因MediaRecorder没正常stop文件头没写完整解决用MP4Box或者其他工具修复或者录制时先写临时文件正常结束再改名重要的话用分片录制坑2USB摄像头热插拔识别问题现象摄像头松了再插上APP识别不到原因APP启动时打开的摄像头断开重连后需要重新初始化解决监听USB设备插拔事件断开时释放连接时重新初始化坑3TF卡速度不够录制丢帧现象高速录制时画面卡顿、丢帧原因用了低速TF卡写入速度跟不上解决用Class10以上的卡降低码率和分辨率先写内存再刷盘坑4长时间运行摄像头发热现象设备跑久了摄像头温度很高画质下降甚至死机原因工控机散热不好摄像头持续工作发热解决按需录制不用就关摄像头加强散热温度过高时暂停录制十、总结售货柜视频录制的核心按需录、存得下、找得到、靠得住。触发录制事件驱动开门必录异常多录参数调优720P 15帧 1Mbps平衡画质和体积循环存储满了自动删最老的重要文件单独保留存储监控空间告警、TF卡健康检测文件管理规范命名数据库记录方便溯源稳定可靠后台保活、异常处理、热插拔支持把录制这块做好了售货柜的安防溯源就有保障了出了纠纷也有证据。我是黒漂技术佬专注无人零售物联网实战。下一篇讲《弱网下视频分片上传》录好的视频怎么在4G弱网环境下稳定传到云端。有视频录制的坑欢迎私信交流大家一起踩坑~
延伸阅读

更多相关文章

2026/10/24 3:07:08

BUUCTFYoungter-drive

考点:多线程 查壳脱壳 进入ida,直接进入main函数 sub_4110FF是输入flag的部分,flag有36个字符 main函数8-13行:有两个线程hObject、Thread 这段代码是使用C语言风格的Windows API函数来创建互斥体(Mutex)、…

2026/10/23 13:19:28

BUUCTF [UTCTF2020]basic-re

查壳 没有 进入ida看了之后发现与flag好像没关系,shiftF12发现可疑字符串,提交试一下成功了,flag{str1ngs_1s_y0ur_fr13nd}

2026/10/26 7:51:22

深度学习设备故障诊断:从数据链路到PyTorch实现与部署

简介:这是一套面向毕业设计、课程实践与工业研发场景的机械设备故障诊断Python实现,基于深度学习网络分析滚动轴承、齿轮箱等振动频谱特征,完成故障类型智能识别。代码按数据预处理、特征提取、模型训练、性能评估模块化组织,包含…

2026/10/26 7:51:22

Xcode与iOS版本兼容性全解析及实战指南

1. Xcode与iOS版本兼容性全景解析作为苹果生态的核心开发工具,Xcode版本与iOS系统版本的匹配关系直接影响着开发者的工作效率和项目兼容性。我在实际团队协作中经常遇到这样的场景:新同事用最新版Xcode编译的项目,在老版本设备上出现各种兼容…

2026/10/26 7:51:22

固定翼容错控制与控制分配:QP分配器与Simulink仿真全解析

简介:面向固定翼飞行器容错控制与控制分配研究的MATLAB代码与Simulink模型套件,适用于航空控制领域的研究生、工程师及对多操纵面重构控制感兴趣的技术人员。资源共99个文件、约5.84MB,以mat数据文件为主(60个)&#x…

2026/10/26 7:51:22

分布式事务核心原理与实践指南

1. 分布式事务的本质挑战在单体应用时代,我们习惯用数据库的ACID特性来保证数据一致性。但当我们把系统拆分成多个服务后,一个业务操作可能涉及多个数据库的修改,这就引出了分布式事务的核心问题:如何确保跨服务的多个数据操作要么…

2026/10/26 7:51:22

OpenMontage 深度解析:用智能体重构视频生产流水线

1. 当视频剪辑遇上智能体:OpenMontage 到底在解决什么问题第一次看到 OpenMontage 这个名字,我下意识把它归类成又一个"套壳剪辑工具"。真正翻完它的设计思路之后才发现,这东西的野心根本不在"帮你剪得快一点"&#xff0…

2026/10/26 7:46:22

MATLAB手写CNN实现:从零搭建可调试卷积神经网络

简介:本资源是一份面向深度学习初学者与MATLAB实践者的CNN原理教学与模拟实现包,聚焦卷积神经网络的核心机制理解与基础训练流程复现。压缩包共30个文件,全部为MATLAB源码(.m文件),涵盖网络初始化&#xff…

2026/10/26 0:20:20

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/26 1:53:47

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/26 0:20:17

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/26 0:00:48

Nested Learning:解决AI灾难性遗忘的分层记忆架构

1. 为什么AI需要"记忆"能力?在传统深度学习模型中,我们常遇到一个根本性问题:模型在处理新任务时,往往会完全遗忘之前学到的知识。这种现象被业界称为"灾难性遗忘"(Catastrophic Forgetting)。想象一下&#…

2026/10/26 0:00:48

企业级大模型应用:OCR预处理、Dify编排与DeepSeek落地实战

1. 这不是“用大模型”,而是重构工作流的起点“大模型的应用和工具”——这八个字现在被贴在无数技术分享、招聘JD、内部立项书的标题栏里,但绝大多数人点进去后看到的,是零散的API调用示例、几个开源UI截图、或者一句“接入LLM就能降本增效”…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑