鸿蒙行车记录仪查看(实时画面/历史视频回放)详解
【摘要】 一、引言在智能驾驶时代,行车记录仪不仅是事故责任判定的关键工具,更是驾驶过程的安全守护者。用户对行车记录仪的需求已从“单纯录像”升级为“实时监控+便捷回放”——例如,车主在行驶中想通过手机查看车前实时画面(如确认后方车辆跟车距离),或在停车后快速回放特定时间段的历史视频(如检查是否刮蹭)。鸿蒙操作系统(HarmonyOS)凭借其 分布式设备互联、实时视频流传输 和 ...
一、引言
二、技术背景
1. 鸿蒙行车记录仪查看架构
-
实时画面传输:行车记录仪(车机/独立设备)通过鸿蒙 媒体流API(@ohos.multimedia.mediaStream) 捕获车前摄像头的高清视频流(如1080P/30fps),并通过分布式软总线(Distributed SoftBus)低延迟(<200ms)传输至手机端,实现“车前画面实时同步”; -
历史视频管理:行车记录仪按时间戳(如每分钟一个视频片段)或事件(如急刹车、碰撞检测)自动存储视频文件(格式如MP4/H.264)至本地存储(车机硬盘或SD卡),手机端通过鸿蒙 分布式文件系统(@ohos.distributedFileSystem) 或 本地存储API(@ohos.file.fs) 按时间/事件筛选并回放; -
多设备协同:支持手机端与车机端(或独立行车记录仪设备)的互联,手机可作为“查看终端”远程控制记录仪(如开始/停止录制、切换摄像头视角),车机端则负责视频采集与存储; -
安全与隐私:视频流传输通过鸿蒙 端到端加密(E2EE) 保障数据安全,历史视频文件仅对授权设备(如车主手机)可见,防止隐私泄露。
2. 核心技术点
-
低延迟视频流:通过鸿蒙媒体流API实现摄像头原始数据的实时编码(如H.264)与传输,结合分布式软总线的QoS(服务质量)保障,确保手机端画面延迟<200ms; -
分布式文件访问:行车记录仪存储的视频文件通过鸿蒙分布式文件系统共享至手机端,支持按时间范围(如“今天上午10:00-11:00”)、事件标签(如“碰撞”)快速检索; -
事件触发存储:记录仪内置传感器(如加速度计、陀螺仪)检测急刹车(加速度>5m/s²)、碰撞(冲击力>10G)等事件,自动标记并存储对应时间段的视频(便于事后重点回放); -
多分辨率适配:根据网络环境(如Wi-Fi/4G)动态调整视频流分辨率(如Wi-Fi下1080P,4G下720P),平衡画质与传输流畅性。
三、应用使用场景
1. 行驶中实时监控
-
场景描述:车主在拥堵路段行驶时,通过手机APP点击“实时画面”按钮,查看车前摄像头的高清画面(如确认后方车辆是否跟车过近),辅助判断变道时机; -
需求:低延迟视频流传输(<200ms)、高清画质(1080P/30fps)、实时控制(如切换广角/窄角镜头)。
2. 停车后历史回放
-
场景描述:车主停车后发现车辆可能有刮蹭,通过手机APP选择“历史视频回放”,按时间筛选“今天下午14:00-15:00”的视频,或通过事件标签(如“轻微震动”)快速定位可能相关的片段; -
需求:按时间/事件快速检索、流畅视频回放(支持暂停/快进/截图)、本地存储管理(避免云端依赖)。
3. 事故责任判定
-
场景描述:发生交通事故后,车主通过手机APP立即回放碰撞前5秒至碰撞后10秒的视频(记录仪自动标记碰撞事件),将关键片段分享给保险公司或交警,明确责任; -
需求:事件触发自动存储(碰撞/急刹车)、高精度时间戳(精确到毫秒)、视频防篡改(数字签名)。
4. 多设备协同查看
-
场景描述:家庭多辆车(如夫妻各开一辆车)的行车记录仪通过鸿蒙互联,车主可在同一手机APP中切换查看不同车辆的实时画面或历史视频(如查看孩子驾驶的车辆状况); -
需求:多设备绑定与管理、统一的视频检索界面、跨设备权限控制(如仅车主可查看)。
四、不同场景下详细代码实现
场景 1:手机APP查看实时画面(基础版)
1.1 项目结构
DrivingRecorderApp/
├── entry/src/main/ets/pages/
│ ├── Index.ets // 主页面(实时画面查看入口)
│ ├── VideoStreamManager.ets // 视频流传输逻辑(鸿蒙媒体流API)
│ └── DeviceManager.ets // 车机设备连接管理(分布式软总线)
├── entry/src/main/module.json5 // 模块配置(声明媒体流与分布式权限)
└── build-profile.json5
1.2 权限配置(module.json5)
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone", // 手机端查看
"car" // 车机端记录仪
],
"deliveryWithInstall": true,
"installationFree": false,
"requestPermissions": [
{
"name": "ohos.permission.CAMERA", // 摄像头访问权限(车机端)
"reason": "$string:camera_permission_reason"
},
{
"name": "ohos.permission.DISTRIBUTED_DEVICE", // 分布式设备连接权限
"reason": "$string:distributed_device_permission_reason"
},
{
"name": "ohos.permission.MULTIMEDIA_STREAM", // 媒体流传输权限
"reason": "$string:multimedia_stream_permission_reason"
}
],
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ts",
"description": "$string:EntryAbility_desc",
"icon": "$media:icon",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
]
}
}
1.3 车机设备连接管理(DeviceManager.ets)
// entry/src/main/ets/pages/DeviceManager.ets
import distributedDevice from '@ohos.distributed.device'; // 鸿蒙分布式设备管理
export class DeviceManager {
private recordDeviceId: string = 'car_recorder_001'; // 车机记录仪设备ID
// 连接车机端的行车记录仪设备
async connectRecordDevice() {
try {
// 获取所有设备列表(筛选类型为“车机记录仪”)
const devices = await distributedDevice.getDevicesByType('recorder');
const targetDevice = devices.find(device => device.deviceId === this.recordDeviceId);
if (!targetDevice) {
console.error('未找到车机记录仪设备!');
return false;
}
// 建立分布式连接
await distributedDevice.connect(targetDevice.deviceId);
console.log('✅ 已连接车机记录仪设备:', this.recordDeviceId);
return true;
} catch (error) {
console.error('连接车机设备失败:', error);
return false;
}
}
}
1.4 视频流传输逻辑(VideoStreamManager.ets)
// entry/src/main/ets/pages/VideoStreamManager.ets
import mediaStream from '@ohos.multimedia.mediaStream'; // 鸿蒙媒体流API
import { DeviceManager } from './DeviceManager.ets';
export class VideoStreamManager {
private deviceManager: DeviceManager = new DeviceManager();
private mediaStream: mediaStream.MediaStream | null = null; // 媒体流对象
private isStreaming: boolean = false; // 是否正在传输视频流
// 初始化并开始实时视频流传输
async startRealTimeStream() {
try {
// 1. 连接车机记录仪设备
const connected = await this.deviceManager.connectRecordDevice();
if (!connected) {
console.error('设备连接失败,无法启动视频流');
return;
}
// 2. 创建媒体流(从车机摄像头捕获视频)
this.mediaStream = await mediaStream.createMediaStream({
source: mediaStream.MediaStreamSource.CAMERA, // 摄像头源
cameraId: 'front_camera', // 前置摄像头(车前视角)
resolution: { width: 1920, height: 1080 }, // 1080P分辨率
frameRate: 30 // 30fps帧率
});
// 3. 通过分布式软总线传输视频流至手机端
await this.mediaStream.start(); // 开始捕获视频
this.isStreaming = true;
console.log('📹 实时视频流已启动(1080P/30fps)');
// 4. 监听视频帧数据(示例:实际需将帧数据渲染到手机APP的UI组件)
this.mediaStream.on('frameData', (frame: Uint8Array) => {
this.renderVideoFrame(frame); // 渲染视频帧到UI(需结合eTS UI组件)
});
} catch (error) {
console.error('启动视频流失败:', error);
this.isStreaming = false;
}
}
// 停止视频流传输
async stopRealTimeStream() {
if (this.mediaStream && this.isStreaming) {
await this.mediaStream.stop(); // 停止捕获视频
this.isStreaming = false;
console.log('⏹️ 实时视频流已停止');
}
}
// 渲染视频帧到UI(简化示例:实际需使用eTS的Image或Video组件)
private renderVideoFrame(frame: Uint8Array) {
// 将帧数据(Uint8Array)转换为图片或视频流(需结合鸿蒙UI组件)
// 示例:通过eTS的@State绑定视频帧数据,动态更新Image组件的src
console.log('🔄 接收到视频帧(长度:', frame.length, '字节)');
}
}
1.5 主页面(Index.ets)
// entry/src/main/ets/pages/Index.ets
import { VideoStreamManager } from './VideoStreamManager.ets';
@Entry
@Component
struct Index {
@State private videoStreamManager: VideoStreamManager = new VideoStreamManager();
@State private isStreaming: boolean = false;
// 开始实时画面查看
private async startStream() {
await this.videoStreamManager.startRealTimeStream();
this.isStreaming = true;
}
// 停止实时画面查看
private async stopStream() {
await this.videoStreamManager.stopRealTimeStream();
this.isStreaming = false;
}
build() {
Column() {
Text('行车记录仪实时画面查看')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 30 });
// 实时画面显示区域(简化:实际需嵌入Video或Image组件)
Rectangle()
.width('100%')
.height(300)
.fill('#f0f0f0')
.stroke('#ddd')
.margin({ bottom: 20 })
.annotation({
value: '📹 实时视频流显示区域(需绑定视频帧数据)'
});
// 控制按钮
Row() {
Button('开始实时画面')
.onClick(() => this.startStream())
.backgroundColor(this.isStreaming ? '#ccc' : '#007AFF')
.disabled(this.isStreaming);
Button('停止实时画面')
.onClick(() => this.stopStream())
.backgroundColor(this.isStreaming ? '#f44336' : '#ccc')
.disabled(!this.isStreaming);
}
.width('80%')
.justifyContent(FlexAlign.SpaceEvenly);
}
.width('100%')
.height('100%')
.padding(20)
.justifyContent(FlexAlign.Start);
}
aboutToDisappear() {
this.stopStream(); // 页面退出时停止视频流
}
}
-
手机端启动应用后,点击“开始实时画面”按钮,通过鸿蒙分布式软总线连接车机端的行车记录仪; -
车机端摄像头捕获的1080P/30fps高清视频流实时传输至手机端,显示在页面的视频区域内(延迟<200ms); -
用户可随时点击“停止实时画面”结束查看。
场景 2:历史视频回放(进阶版)
2.1 历史视频管理逻辑(扩展 VideoStreamManager.ets)
// 在 VideoStreamManager.ets 中添加历史视频回放方法
import fileSystem from '@ohos.file.fs'; // 鸿蒙本地文件系统API
import { DeviceManager } from './DeviceManager.ets';
export class VideoStreamManager {
// ... 原有代码 ...
// 查询历史视频文件(按时间范围)
async queryHistoryVideos(startTime: Date, endTime: Date): Promise<string[]> {
try {
// 连接车机设备
const connected = await this.deviceManager.connectRecordDevice();
if (!connected) {
console.error('设备连接失败,无法查询历史视频');
return [];
}
// 构建视频文件存储路径(示例:车机端路径为 /storage/recordings/)
const remotePath = '/storage/recordings/';
const files = await fileSystem.getFiles(remotePath, {
filter: (file: fileSystem.FileInfo) => {
const fileName = file.name;
// 筛选MP4格式文件(示例:实际可能包含时间戳前缀如 20250211_140000.mp4)
const isMp4 = fileName.endsWith('.mp4');
if (!isMp4) return false;
// 解析文件名中的时间戳(示例:20250211_140000.mp4 -> 2025-02-11 14:00:00)
const timestampStr = fileName.split('.')[0]; // 去掉.mp4
const year = parseInt(timestampStr.substring(0, 4));
const month = parseInt(timestampStr.substring(4, 6)) - 1;
const day = parseInt(timestampStr.substring(6, 8));
const hour = parseInt(timestampStr.substring(9, 11));
const minute = parseInt(timestampStr.substring(11, 13));
const second = parseInt(timestampStr.substring(13, 15));
const fileTime = new Date(year, month, day, hour, minute, second);
// 判断是否在查询的时间范围内
return fileTime >= startTime && fileTime <= endTime;
}
});
return files.map(file => file.path); // 返回符合条件的视频文件路径
} catch (error) {
console.error('查询历史视频失败:', error);
return [];
}
}
// 回放指定历史视频
async playHistoryVideo(videoPath: string) {
try {
// 通过分布式文件系统读取视频文件流
const fileStream = await fileSystem.openFile(videoPath, fileSystem.OpenMode.READ_ONLY);
const videoData = await fileStream.read(); // 读取视频数据(示例:实际需流式传输)
// 调用手机端视频播放组件(示例:eTS的Video组件)
this.renderHistoryVideo(videoData); // 渲染视频到UI
console.log('🎬 开始回放历史视频:', videoPath);
} catch (error) {
console.error('回放历史视频失败:', error);
}
}
// 渲染历史视频到UI(简化示例:实际需使用eTS的Video组件)
private renderHistoryVideo(videoData: Uint8Array) {
// 将视频数据绑定到eTS的Video组件的src属性(需结合鸿蒙媒体播放API)
console.log('🔄 加载历史视频数据(长度:', videoData.length, '字节)');
}
}
2.2 主页面扩展(Index.ets)
// 在 Index.ets 中添加历史视频回放按钮和逻辑
@State private selectedVideoPath: string = '';
// 查询并显示历史视频(示例:查询今天14:00-15:00的视频)
private async queryAndShowHistoryVideos() {
const startTime = new Date(); // 当前时间(示例:实际需设置为今天14:00)
startTime.setHours(14, 0, 0, 0);
const endTime = new Date();
endTime.setHours(15, 0, 0, 0);
const videos = await this.videoStreamManager.queryHistoryVideos(startTime, endTime);
if (videos.length > 0) {
this.selectedVideoPath = videos[0]; // 选择第一个视频(示例)
await this.videoStreamManager.playHistoryVideo(this.selectedVideoPath);
} else {
console.log('📭 未找到指定时间范围内的历史视频');
}
}
// 在build()方法中添加历史回放按钮
Button('查看历史视频(14:00-15:00)')
.onClick(() => this.queryAndShowHistoryVideos())
.margin({ top: 20 });
-
车主点击“查看历史视频(14:00-15:00)”按钮后,系统查询车机端该时间段内的MP4视频文件(如 20250211_140500.mp4); -
选择第一个视频后,手机端通过分布式文件系统读取文件流并流畅回放(支持暂停/快进/截图); -
用户可检查视频内容(如是否刮蹭、事故过程)。
五、原理解释
1. 鸿蒙行车记录仪查看的核心流程
-
实时画面传输: -
车机端的行车记录仪通过内置摄像头捕获高清视频流(如1080P/30fps),利用鸿蒙 媒体流API 对视频进行编码(如H.264); -
编码后的视频流通过 分布式软总线 低延迟(<200ms)传输至手机端,手机端通过媒体流接收模块解析帧数据并渲染到UI(如eTS的Video组件);
-
-
历史视频管理: -
车机端按时间戳(如每分钟一个MP4文件)或事件(如碰撞检测触发)存储视频文件至本地存储(如SD卡或车机硬盘); -
手机端通过 分布式文件系统 或 本地存储API 连接车机存储,按用户选择的时间范围(如“今天14:00-15:00”)或事件标签(如“碰撞”)筛选视频文件; -
筛选后的视频文件通过分布式文件系统读取并回放(支持暂停/快进/截图),或直接下载至手机本地缓存后播放。
-
-
多设备协同: -
手机端与车机端通过鸿蒙分布式能力建立连接(设备发现、权限校验),手机作为“查看终端”发送控制指令(如开始/停止录制、切换摄像头),车机作为“记录终端”执行指令并反馈状态; -
视频流与文件传输均通过鸿蒙的安全机制(如端到端加密)保障数据隐私。
-
2. 关键技术点
-
低延迟视频流:通过鸿蒙媒体流API的硬件加速编码(如GPU编码H.264)和分布式软总线的QoS保障(优先传输视频流数据包),实现<200ms的实时传输; -
分布式文件共享:行车记录仪存储的视频文件通过鸿蒙分布式文件系统挂载至手机端,无需手动拷贝,支持跨设备无缝访问; -
事件触发存储:记录仪内置传感器(如加速度计)实时监测急刹车(加速度>5m/s²)、碰撞(冲击力>10G)等事件,自动标记并存储对应时间段的视频(便于事后重点回放); -
多分辨率适配:根据手机端网络环境(如Wi-Fi/4G)动态调整视频流分辨率(如Wi-Fi下1080P,4G下720P),平衡画质与传输流畅性。
六、核心特性
|
|
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
七、原理流程图及原理解释
原理流程图(鸿蒙行车记录仪查看)
+-----------------------+ +-----------------------+ +-----------------------+
| 手机APP(查看端) | | 鸿蒙软总线 | | 车机记录仪 |
| (Phone - Viewer) | | (Distributed SoftBus)| | (Recorder Device) |
+-----------------------+ +-----------------------+ +-----------------------+
| | |
| 1. 连接车机设备 | |
|-------------------------->| |
| (分布式设备发现) | |
| 2. 请求实时画面 | |
|<--------------------------| |
| (通过媒体流API) | |
| 3. 接收视频流 | | 4. 摄像头捕获视频 |
|<--------------------------| (车机摄像头采集) |
| (低延迟传输) | | (编码为H.264) |
| 5. 渲染实时画面 | | 6. 传输至手机端 |
| (显示在手机UI) | |-----------------------> |
| | |
| 7. 查询历史视频 | | 8. 按时间/事件筛选 |
|-------------------------->| (本地存储检索) |
| (分布式文件系统) | | (返回MP4文件路径) |
| 9. 读取视频文件 | | 10. 传输文件流 |
|<--------------------------|-----------------------> |
| 11. 回放视频 | |
| (支持暂停/快进) | |
原理解释
-
实时画面传输:手机APP通过鸿蒙分布式软总线发现并连接车机记录仪设备,请求实时视频流;车机记录仪通过内置摄像头捕获视频,经H.264编码后通过媒体流API低延迟传输至手机端;手机端解析视频帧数据并渲染到UI(如Video组件),实现“车前画面实时同步”。 -
历史视频回放:手机APP通过分布式文件系统或本地存储API连接车机存储,按用户选择的时间范围(如“今天14:00-15:00”)或事件标签(如“碰撞”)筛选MP4视频文件;筛选后的文件通过文件系统读取并回放(支持暂停/快进/截图),或下载至手机本地后播放,确保用户可随时检查驾驶过程。 -
多设备协同:手机端与车机端通过鸿蒙分布式能力建立安全连接(设备认证、权限校验),手机作为控制终端发送指令(如开始/停止录制),车机作为执行终端反馈状态(如“录制中”“存储已满”),实现双向交互。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)