import TopLogo from './compontents/topLogo'; import common from '@ohos.app.ability.common'; import promptAction from '@ohos.promptAction'; import { GlobalConfig } from '../config/index'; import { VideoConfigData } from '../mock'; import { CommonType, RecordHandleType, VideoConfig, VideoItemType } from '../model'; import { endRecordVideo, startRecordVideo, takePhoto } from '../utils/Video'; import FileUtils from '../utils/FileUtils'; @Entry @Component struct Index { @State ratio: number = 1700 / 960 @State videoSrc: string = 'rtsp://admin12345qwe@192.168.36.94:554/h264/ch3/main/av_stream' @State previewUri: Resource = $r('app.media.2_nor') @State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X @State inputFontSize: number = 10 //12 @State rocordHandleObj: RecordHandleType = { rocord_handle1: 0, rocord_handle2: 0, rocord_handle3: 0, rocord_handle4: 0 } @State isAutoPlay: boolean = true @State showFlag: boolean = false @State videoStartFlag: boolean = false @State takePhotoFlag: boolean = false @State showControls: boolean = false @State @Watch('outClick') outFlag: boolean = false; @State oldParam: VideoConfig = VideoConfigData @State param: VideoConfig = VideoConfigData @State openFlag: boolean = true @State lsArr: Array = [ { key: '第一路' }, { key: '第二路' }, { key: '第三路' }, { key: '第四路' }, ] 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 videoArr: 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: '' }, ] private inputController: TextInputController = new TextInputController() build() { Column() { TopLogo({ outFlag: $outFlag }) Flex({ justifyContent: FlexAlign.SpaceBetween }) { Flex({ wrap: FlexWrap.Wrap, direction: FlexDirection.Row }) { ForEach(this.videoArr, (item: VideoItemType) => { Video({ src: this.openFlag ? // `rtsp://${this.param.userName}:${this.param.pwd}@${this.param.ip}:${this.param.port}/h264/ch${this.param[item.td]}/main/av_stream` : '', `rtsp://${this.param.userName}:${this.param.pwd}@${this.param.ip}:${this.param.port}/h264/ch${Reflect.get(this.param, 'port')}/main/av_stream` : '', currentProgressRate: this.curRate, controller: item.controller }) .width(200 * this.ratio) .muted(true) .height(180 * this.ratio) .autoPlay(this.isAutoPlay) .controls(this.showControls) .margin(10 * this.ratio) }) }.margin({ top: 37 * this.ratio, left: 30 * this.ratio }).width(600 * this.ratio).height(600 * this.ratio) Column() { Image($r('app.media.shezhi')) .width(215 * this.ratio) .height(64 * this.ratio) .margin({ bottom: 10 * this.ratio }) .onClick(() => { this.showFlag = true }) Image($r('app.media.luxiang')) .width(215 * this.ratio) .height(64 * this.ratio) .margin({ bottom: 10 * this.ratio }) .onClick(async () => { if (!this.param.videoRecord4 && !this.param.videoRecord3 && !this.param.videoRecord2 && !this.param.videoRecord1) { promptAction.showToast({ message: '请选择录像通道', duration: 3000 }) return } if (this.videoStartFlag) { return } if (this.rocordHandleObj.rocord_handle1 || this.rocordHandleObj.rocord_handle2 || this.rocordHandleObj.rocord_handle3 || this.rocordHandleObj.rocord_handle4) { return } this.videoStartFlag = true // for (let i = 1; i <= 4; i++) { // if (this.param['videoRecord'+i]) { // await this.getfilehandleCode(i) // } // } for (let i = 1; i <= 4; i++) { if (Reflect.get(this.param, 'videoRecord' + i)) { await this.getFileHandleCode(i); } } this.videoStartFlag = false promptAction.showToast({ message: '录像开始', duration: 3000 }) }) Image($r('app.media.tingzhi')) .width(215 * this.ratio) .height(64 * this.ratio) .margin({ bottom: 10 * this.ratio }) .onClick(() => { // for (let i = 1; i <= 4; i++) { // console.log('rocord_handle', i, JSON.stringify(this.rocordHandleObj)) // if (this.rocordHandleObj['rocord_handle'+i]) { // endRecordVideo(this.rocordHandleObj) // this.rocordHandleObj['rocord_handle'+i] = 0 // } // } for (let i = 1; i <= 4; i++) { if (Reflect.get(this.rocordHandleObj, 'rocord_handle' + i)) { Reflect.set(this.rocordHandleObj, 'rocord_handle' + i, 0); } } endRecordVideo(this.rocordHandleObj); promptAction.showToast({ message: '录像结束', duration: 3000 }) }) Image($r('app.media.zhuatu')) .width(215 * this.ratio) .height(64 * this.ratio) .onClick(async () => { const arr = ['1', '2', '3', '4'] if (!arr.includes(this.param.pztd)) { promptAction.showToast({ message: '请填写正确的拍照通道', duration: 3000 }) return } if (this.takePhotoFlag) { return } this.takePhotoFlag = true try { await takePhoto(this.param, this.context, 'pz/') promptAction.showToast({ message: '抓图完成', duration: 3000 }) this.takePhotoFlag = false // }).catch((err) => { // console.log('daihai err: ' + err) // }) } catch (error) { console.log('daihai', error) } }) .margin({ bottom: 10 * this.ratio }) }.margin({ right: 38 * this.ratio, top: 110 * this.ratio }) }.backgroundColor('#1A1A1A') // Column() { // Text('提示信息:') // .fontSize(18 * this.ratio) // .fontColor('#fff') // .margin({ left: 29 * this.ratio, top: 13 * this.ratio }) // .align(Alignment.Start) // .width('100%') // }.width('100%').height(70 * this.ratio).backgroundColor('#333230').position({ x: 0, y: 470 * this.ratio }) if (this.showFlag) { Column() { Flex({ justifyContent: FlexAlign.SpaceBetween }) { Text('视频参数设置') .width('100%') .align(Alignment.Start) .fontSize(24 * this.ratio) .fontColor('#333333') .margin({ left: 20 * this.ratio, top: 22 * this.ratio }) Row() { Image($r('app.media.fh')).width(117 * this.ratio).height(50 * this.ratio).onClick(() => { // this.oldParam = JSON.parse(JSON.stringify(this.param)) this.param = JSON.parse(JSON.stringify(this.oldParam)) this.showFlag = false }) Image($r('app.media.bc')) .width(117 * this.ratio) .height(50 * this.ratio) .margin({ left: 15 * this.ratio }) .onClick(() => { console.log('111111') this.writeConfig() }) }.margin({ right: 135 * this.ratio, top: 10 * this.ratio }) } Column() { Row() { Text('视频路数').fontColor('#333333').fontSize(16 * this.ratio).margin({ left: 13 * this.ratio }) TextInput({ text: this.param.videoNum, controller: this.inputController }) .type(InputType.Normal) .borderRadius(0) .width(34 * this.ratio) .height(26 * this.ratio) .padding({ top: 0, bottom: 0 }) .margin({ left: 10 * this.ratio }) .fontSize(this.inputFontSize * this.ratio) .onChange((value) => { this.param.spls = value }) Column() { Image($r('app.media.shang')).width(15 * this.ratio).height(15 * this.ratio).onClick(() => { this.param.videoNum = (parseInt(this.param.videoNum) + 1).toString() }) Image($r('app.media.xia')).width(15 * this.ratio).height(15 * this.ratio).onClick(() => { this.param.videoNum = (parseInt(this.param.videoNum) - 1).toString() }) }.margin({ left: 5 * this.ratio, right: 10 * this.ratio }) Checkbox({ name: 'checkbox1', group: 'checkboxGroup' }) .select(this.param.faceFlag) .width(22 * this.ratio) .height(22 * this.ratio) .onChange((value: boolean) => { this.param.faceFlag = value console.info('Checkbox1 change is' + value) }) Text('启用人脸比对').fontColor('#333333').fontSize(16 * this.ratio) TextInput({ text: this.param.rlls, controller: this.inputController }) .type(InputType.Normal) .borderRadius(0) .width(34 * this.ratio) .fontSize(this.inputFontSize * this.ratio) .height(26 * this.ratio) .padding({ top: 0, bottom: 0 }) .margin({ left: 10 * this.ratio, right: 15 * this.ratio }) .onChange((value) => { this.param.rlls = value }) Text('过程拍照通道').fontColor('#333333').fontSize(16 * this.ratio) TextInput({ text: this.param.pztd, controller: this.inputController }) .type(InputType.Normal) .borderRadius(0) .padding({ top: 0, bottom: 0 }) .width(34 * this.ratio) .height(26 * this.ratio) .fontSize(this.inputFontSize * this.ratio) .margin({ left: 10 * this.ratio, right: 15 * this.ratio }) .onChange((value: string) => { this.param.pztd = value }) Text('设备类型').fontColor('#333333').fontSize(16 * this.ratio) TextInput({ text: '海康', controller: this.inputController }) .borderRadius(0) .padding({ bottom: 0, top: 0 }) .width(67 * this.ratio) .height(26 * this.ratio) .fontSize(this.inputFontSize * this.ratio) .margin({ left: 10 * this.ratio, right: 15 * this.ratio }) Text('视频遮挡报警阀值:').fontColor('#333333').fontSize(16 * this.ratio) TextInput({ text: this.param.zdyz, controller: this.inputController }) .type(InputType.Normal) .borderRadius(0) .padding({ top: 0, bottom: 0 }) .width(34 * this.ratio) .height(26 * this.ratio) .fontSize(this.inputFontSize * this.ratio) .margin({ left: 10 * this.ratio, right: 15 * this.ratio }) .onChange((value: string) => { this.param.zdyz = value }) // Text('k').fontColor('#333333').fontSize(16 * this.ratio) // Text('链接类型').fontColor('#333333').fontSize(16 * this.ratio) // TextInput({ text: this.param.ljlx, controller: this.inputController }) // .type(InputType.Normal) // .borderRadius(0) // .padding({ top: 0, bottom: 0 }) // .width(34 * this.ratio) // .height(26 * this.ratio) // .fontSize(this.inputFontSize * this.ratio) // .margin({ left: 10 * this.ratio, right: 5 * this.ratio }) }.width('100%').align(Alignment.Start).backgroundColor('#E5E3DF') Row() { Column() { Row() { Row() { }.width(70 * this.ratio) Text('IP地址') .width(158 * this.ratio) .fontSize(16 * this.ratio) .fontColor('#666666') .margin({ right: 10 * this.ratio }) .textAlign(TextAlign.Center) Text('通道号') .width(96 * this.ratio) .fontSize(16 * this.ratio) .fontColor('#666666') .margin({ right: 10 * this.ratio }) .textAlign(TextAlign.Center) Text('用户名') .width(120 * this.ratio) .fontSize(16 * this.ratio) .fontColor('#666666') .margin({ right: 10 * this.ratio }) .textAlign(TextAlign.Center) Text('密码') .width(120 * this.ratio) .fontSize(16 * this.ratio) .fontColor('#666666') .margin({ right: 10 * this.ratio }) .textAlign(TextAlign.Center) Text('端口号') .width(60 * this.ratio) .fontSize(16 * this.ratio) .fontColor('#666666') .margin({ right: 10 * this.ratio }) .textAlign(TextAlign.Center) } ForEach(this.lsArr, (item: CommonType, index) => { Row() { Text(item.key) .width(70 * this.ratio) .fontColor('#333333') .fontSize(16 * this.ratio) .textAlign(TextAlign.Center) TextInput({ text: this.param.ip, controller: this.inputController }) .type(InputType.Normal) .borderRadius(2) .width(158 * this.ratio) .height(26 * this.ratio) .fontSize(this.inputFontSize * this.ratio) .padding({ top: 0, bottom: 0 }) .margin({ right: 10 * this.ratio }) .onChange((value: string) => { this.param.ip = value }) // TextInput({ text: this.param['td'+(Number(index) + 1)], controller: this.inputController }) TextInput({ text: Reflect.get(this.param, 'td' + (Number(index) + 1)), controller: this.inputController }) .type(InputType.Normal) .borderRadius(2) .width(96 * this.ratio) .height(26 * this.ratio) .padding({ top: 0, bottom: 0 }) .margin({ right: 10 * this.ratio }) .fontSize(this.inputFontSize * this.ratio) .onChange((value: string) => { // this.param['td'+(Number(index) + 1)] = value Reflect.set(this.param, 'td' + (Number(index) + 1), value); }) TextInput({ text: this.param.userName, controller: this.inputController }) .type(InputType.Normal) .borderRadius(2) .width(120 * this.ratio) .height(26 * this.ratio) .margin({ right: 10 * this.ratio }) .padding({ top: 0, bottom: 0 }) .fontSize(this.inputFontSize * this.ratio) .onChange((value: string) => { this.param.userName = value }) TextInput({ text: this.param.pwd, controller: this.inputController }) .type(InputType.Normal) .borderRadius(2) .width(120 * this.ratio) .height(26 * this.ratio) .fontSize(this.inputFontSize * this.ratio) .margin({ right: 10 * this.ratio }) .padding({ top: 0, bottom: 0 }) .onChange((value: string) => { this.param.pwd = value }) TextInput({ text: this.param.port, controller: this.inputController }) .type(InputType.Normal) .borderRadius(2) .width(60 * this.ratio) .height(26 * this.ratio) .padding({ top: 0, bottom: 0 }) .margin({ right: 10 * this.ratio }) .fontSize(this.inputFontSize * this.ratio) .onChange((value: string) => { this.param.port = value }) }.margin({ top: 10 * this.ratio }) }) }.width(672 * this.ratio).height(174 * this.ratio).backgroundColor('#EDEBE8') Column() { Row() { Text('录像范围').fontSize(16 * this.ratio).fontColor('#333333').margin({ top: 10 * this.ratio }) Row() { Column() { Row() { Checkbox({ name: 'checkbox1', group: 'checkboxGroup' }) .select(this.param.videoRecord1) .width(22 * this.ratio) .height(22 * this.ratio) .onChange((value: boolean) => { this.param.videoRecord1 = value console.info('Checkbox1 change is' + value) }) Text('一路').fontSize(16 * this.ratio).fontColor('#333333') Checkbox({ name: 'checkbox2', group: 'checkboxGroup' }) .select(this.param.videoRecord2) .width(22 * this.ratio) .height(22 * this.ratio) .onChange((value: boolean) => { this.param.videoRecord2 = value console.info('Checkbox1 change is' + value) }) Text('二路').fontSize(16 * this.ratio).fontColor('#333333') } Row() { Checkbox({ name: 'checkbox3', group: 'checkboxGroup' }) .select(this.param.videoRecord3) .width(22 * this.ratio) .height(22 * this.ratio) .onChange((value: boolean) => { this.param.videoRecord3 = value console.info('Checkbox1 change is' + value) }) Text('三路').fontSize(16 * this.ratio).fontColor('#333333') Checkbox({ name: 'checkbox4', group: 'checkboxGroup' }) .select(this.param.videoRecord4) .width(22 * this.ratio) .height(22 * this.ratio) .onChange((value: boolean) => { this.param.videoRecord4 = value console.info('Checkbox1 change is' + value) }) Text('四路').fontSize(16 * this.ratio).fontColor('#333333') } } } }.alignItems(VerticalAlign.Top).justifyContent(FlexAlign.Start) Row() { Text('视频遮挡').fontSize(16 * this.ratio).fontColor('#333333').margin({ top: 10 * this.ratio }) Row() { Column() { Row() { Checkbox({ name: 'checkbox1', group: 'checkboxGroup' }) .select(this.param.spzd1) .width(22 * this.ratio) .height(22 * this.ratio) .onChange((value: boolean) => { this.param.spzd1 = value }) Text('一路').fontSize(16 * this.ratio).fontColor('#333333') Checkbox({ name: 'checkbox1', group: 'checkboxGroup' }) .select(this.param.spzd2) .width(22 * this.ratio) .height(22 * this.ratio) .onChange((value: boolean) => { this.param.spzd2 = value }) Text('二路').fontSize(16 * this.ratio).fontColor('#333333') } Row() { Checkbox({ name: 'checkbox1', group: 'checkboxGroup' }) .select(this.param.spzd3) .width(22 * this.ratio) .height(22 * this.ratio) .onChange((value: boolean) => { this.param.spzd3 = value }) Text('三路').fontSize(16 * this.ratio).fontColor('#333333') Checkbox({ name: 'checkbox1', group: 'checkboxGroup' }) .select(this.param.spzd4) .width(22 * this.ratio) .height(22 * this.ratio) .onChange((value: boolean) => { this.param.spzd4 = value }) Text('四路').fontSize(16 * this.ratio).fontColor('#333333') } } } }.alignItems(VerticalAlign.Top).justifyContent(FlexAlign.Start) }.width(267 * this.ratio).height(174 * this.ratio).margin({ left: 7 * this.ratio, top: 10 * this.ratio }) }.width('100%') Row() { Checkbox({ name: 'checkbox1', group: 'checkboxGroup' }) .select(this.param.shuiying) .width(22 * this.ratio) .height(22 * this.ratio) .onChange((value: boolean) => { console.info('Checkbox1 change is' + value) }) Text('照片叠加文字').fontColor('#333333').fontSize(16 * this.ratio) Text('位置').fontColor('#333333').fontSize(16 * this.ratio).margin({ left: 24 * this.ratio }) TextInput({ text: this.param.wz, controller: this.inputController }) .type(InputType.Normal) .borderRadius(0) .width(79 * this.ratio) .height(26 * this.ratio) .padding({ top: 0, bottom: 0 }) .fontSize(this.inputFontSize * this.ratio) .margin({ left: 10 * this.ratio }) Text('叠加内容').fontColor('#333333').fontSize(16 * this.ratio).margin({ left: 24 * this.ratio }) TextInput({ text: this.param.text1, controller: this.inputController }) .type(InputType.Normal) .borderRadius(0) .width(79 * this.ratio) .height(26 * this.ratio) .padding({ top: 0, bottom: 0 }) .margin({ left: 10 * this.ratio }) .fontSize(this.inputFontSize * this.ratio) Text('+').fontColor('#333333').fontSize(16 * this.ratio).margin({ left: 5 * this.ratio }) TextInput({ text: this.param.text2, controller: this.inputController }) .type(InputType.Normal) .borderRadius(0) .width(79 * this.ratio) .height(26 * this.ratio) .padding({ top: 0, bottom: 0 }) .margin({ left: 10 * this.ratio }) .fontSize(this.inputFontSize * this.ratio) Text('+').fontColor('#333333').fontSize(16 * this.ratio).margin({ left: 5 * this.ratio }) TextInput({ text: this.param.text3, controller: this.inputController }) .type(InputType.Normal) .borderRadius(0) .width(79 * this.ratio) .padding({ top: 0, bottom: 0 }) .height(26 * this.ratio) .margin({ left: 10 * this.ratio }) .fontSize(this.inputFontSize * this.ratio) Text('分隔符').fontColor('#333333').fontSize(16 * this.ratio).margin({ left: 24 * this.ratio }) TextInput({ text: this.param.dolt, controller: this.inputController }) .type(InputType.Normal) .borderRadius(0) .width(67 * this.ratio) .height(26 * this.ratio) .margin({ left: 10 * this.ratio }) .padding({ top: 0, bottom: 0 }) .fontSize(this.inputFontSize * this.ratio) Text('文字大小').fontColor('#333333').fontSize(16 * this.ratio).margin({ left: 24 * this.ratio }) TextInput({ text: this.param.fontSize, controller: this.inputController }) .type(InputType.Normal) .borderRadius(0) .width(34 * this.ratio) .height(26 * this.ratio) .margin({ left: 10 * this.ratio }) .fontSize(this.inputFontSize * this.ratio) .padding({ top: 0, bottom: 0 }) }.width('100%').align(Alignment.Start).backgroundColor('#E5E3DF') }.width(946 * this.ratio).height(336 * this.ratio).backgroundColor('#E5E3DF').margin({ top: 13 * this.ratio }) } .width('100%') .height(395 * this.ratio) .backgroundColor('#CCC4B8') .position({ x: 0, y: 146 * this.ratio }) .border({ radius: { topLeft: 24 * this.ratio, topRight: 24 * this.ratio } }) } }.backgroundColor('#1A1A1A').width('100%').height('100%') } aboutToAppear() { // this.ratio = globalThis.ratio this.ratio = AppStorage.get('ratio') this.openFlag = true const fileUtil = new FileUtils(this.context) this.fileUtil = fileUtil this.getVideoConfig() } async getFileHandleCode(td: number): Promise { return new Promise(async (resolve, reject) => { const record_handle = await startRecordVideo(this.param, td, this.context, 'lp') // this.rocordHandleObj['rocord_handle'+td] = record_handle Reflect.set(this.rocordHandleObj, 'rocord_handle' + td, record_handle); resolve() }) } outClick() { this.openFlag = false } async onPageShow() { } async getVideoConfig() { const data = await this.fileUtil.readFile(GlobalConfig.comoonfileWriteAddress + '/config/config3.txt'); this.oldParam = JSON.parse(data) this.param = JSON.parse(data) } async writeConfig() { this.oldParam = JSON.parse(JSON.stringify(this.param)) this.videoArr = JSON.parse(JSON.stringify(this.videoArr)) const folderPath = await this.fileUtil.initFolder(`/config`); this.fileUtil.addFile(`${folderPath}/config3.txt`, JSON.stringify(this.param)) this.showFlag = false } }