import { VideoConfigData } from '../mock' import { RecordHandleType, VideoConfig, VideoItemType } from '../model' import FileUtils from '../utils/FileUtils' import HeaderComponent from './compontents/Header' import VideoConfigComponent from './VideoConfig/Config' import common from '@ohos.app.ability.common' import { GlobalConfig } from '../config' import Prompt from '@system.prompt' import { endRecordVideo, startRecordVideo, takePhoto } from '../utils/Video' import { dConsole } from '../utils/LogWorker' @Entry @Component struct VideoConfigPage { @State videoConfig: VideoConfig = VideoConfigData @State oldVideoConfig: VideoConfig = VideoConfigData @State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X @State openFlag: boolean = true // 是否自动播放 @State isAutoPlay: boolean = true @State showControls: boolean = false // 弹窗 dialogController: CustomDialogController = new CustomDialogController({ builder: VideoConfigComponent({ videoConfig: this.videoConfig, back: () => { dConsole.log("返回") this.videoConfig = this.oldVideoConfig }, save: (config: VideoConfig) => { dConsole.log("保存", config) this.videoConfig = config this.saveVideoConfig() }, }), alignment: DialogAlignment.Bottom, customStyle: true }) @State recordHandleObj: RecordHandleType = { rocord_handle1: 0, rocord_handle2: 0, rocord_handle3: 0, rocord_handle4: 0 } // 文件操作 private fileUtil!: FileUtils private context = getContext(this) as common.UIAbilityContext; // 视频控制器 private controller1: VideoController = new VideoController() private controller2: VideoController = new VideoController() private controller3: VideoController = new VideoController() private controller4: VideoController = new VideoController() // 视频列表 @State videoList: Array = [ { td: 'td1', controller: this.controller1, src: '' }, { td: 'td2', controller: this.controller2, src: '' }, { td: 'td3', controller: this.controller3, src: '' }, { td: 'td4', controller: this.controller4, src: '' }, ] aboutToAppear(): void { this.fileUtil = new FileUtils(this.context) this.readVideoConfig() } // 读取视频配置 async readVideoConfig() { const data = await this.fileUtil.readFile(GlobalConfig.commonFileWriteAddress + '/config/config3.txt'); this.videoConfig = JSON.parse(data) this.oldVideoConfig = JSON.parse(data); } // 保存视频配置 async saveVideoConfig() { const folderPath = await this.fileUtil.initFolder(`/config`); dConsole.log(this.oldVideoConfig.videoNum, this.videoConfig.videoNum, "查看") this.fileUtil.addFile(`${folderPath}/config3.txt`, JSON.stringify(this.videoConfig)) } async getFileHandleCode(td: number): Promise { return new Promise(async (resolve, reject) => { try { const record_handle = await startRecordVideo(this.videoConfig, td, this.context, 'lp') Reflect.set(this.recordHandleObj, 'rocord_handle' + td, record_handle) resolve(true) } catch (error) { reject(false) } }) } build() { Flex({ justifyContent: FlexAlign.SpaceBetween, direction: FlexDirection.Column }) { HeaderComponent({ shortLogo: true, shouBackArea: true }) Flex() { // 左边视频监控区域 Flex({ wrap: FlexWrap.Wrap }) { ForEach(this.videoList, (item: VideoItemType) => { Row() { Video({ src: this.openFlag ? `rtsp://${this.videoConfig.userName}:${this.videoConfig.pwd}@${this.videoConfig.ip}:${this.videoConfig.port}/h264/ch${Reflect.get(this.videoConfig, item.td)}/main/av_stream` : '', currentProgressRate: this.curRate, controller: item.controller }) .muted(true) .autoPlay(this.isAutoPlay) .controls(this.showControls) .width("100%") .height("100%") }.width("50%").height("50%").padding(20) }) }.width("70%").height("100%").padding(40) // 右边视频配置区域 Column() { // 设置 ButtonComponent({ type: "0", click: () => { this.dialogController.open() } }) // 录像 ButtonComponent({ type: "1", click: async () => { if (!this.videoConfig.videoRecord4 && !this.videoConfig.videoRecord3 && !this.videoConfig.videoRecord2 && !this.videoConfig.videoRecord1) { Prompt.showToast({ message: '请选择录像通道', duration: 3000 }) return } for (let i = 1; i <= 4; i++) { if (Reflect.get(this.videoConfig, 'videoRecord' + i)) { await this.getFileHandleCode(i) } } // 录像开始 Prompt.showToast({ message: '录像开始!', duration: 3000 }) } }) // 停止 ButtonComponent({ type: "2", click: () => { for (let i = 1; i <= 4; i++) { if (Reflect.get(this.recordHandleObj, 'rocord_handle' + i) !== 0) { endRecordVideo(Reflect.get(this.recordHandleObj, 'rocord_handle' + i)) Reflect.set(this.recordHandleObj, 'rocord_handle' + i, 0) } } Prompt.showToast({ message: '录像已停止!', duration: 3000 }) } }) // 抓图 ButtonComponent({ type: "3", click: async () => { const arr = ['1', '2', '3', '4'] if (!arr.includes(this.videoConfig.pztd)) { Prompt.showToast({ message: '请填写正确的拍照通道', duration: 3000 }) return } try { await takePhoto(this.videoConfig, this.context, 'pz/') Prompt.showToast({ message: '抓图完成', duration: 3000 }) } catch (error) { dConsole.log("抓图失败", error) } } }) } .width("30%") .height("100%") .padding(100) .justifyContent(FlexAlign.End) .alignItems(HorizontalAlign.Center) } } .width("100%") .height("100%") .backgroundImage($r('app.media.index_bg')) .backgroundImageSize({ width: "100%", height: "100%" }) } } @Component struct ButtonComponent { @State type: string = "0" click?: () => void // 使用映射表来存储类型与图片资源的对应关系 private readonly imageResources: Record = { "3": $r('app.media.zhuatu'), "2": $r('app.media.tingzhi'), "1": $r('app.media.luxiang'), "0": $r('app.media.shezhi') } build() { Image(this.imageResources[this.type]) .width(500) .height(100) .objectFit(ImageFit.Contain) .margin({ top: 20 }) .onClick(() => { this.click && this.click() }) } }