fix: 视频界面设置重构

This commit is contained in:
wangzhongjie 2025-06-05 14:46:39 +08:00
parent a0a93fd347
commit d06f1c1d5a
3 changed files with 593 additions and 607 deletions

View File

@ -1,630 +1,144 @@
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';
import TopLogo from './compontents/TopLogo';
import { VideoConfigData } from '../mock'
import { VideoConfig, VideoItemType } from '../model'
import HeaderComponent from './compontents/Header'
import VideoConfigComponent from './VideoConfig/Config'
@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')
struct VideoConfigPage {
@State videoConfig: VideoConfig = VideoConfigData
@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<CommonType> = [
{ key: '第一路' },
{ key: '第二路' },
{ key: '第三路' },
{ key: '第四路' },
]
private fileUtil!: FileUtils
private context = getContext(this) as common.UIAbilityContext;
// 是否自动播放
@State isAutoPlay: boolean = true
@State showControls: boolean = false
// 弹窗
dialogController: CustomDialogController = new CustomDialogController({
builder: VideoConfigComponent({
videoConfig: this.videoConfig
}),
alignment: DialogAlignment.Bottom,
customStyle: true
})
// 视频控制器
private controller1: VideoController = new VideoController()
private controller2: VideoController = new VideoController()
private controller3: VideoController = new VideoController()
private controller4: VideoController = new VideoController()
@State videoArr: Array<VideoItemType> = [
// 视频列表
@State videoList: Array<VideoItemType> = [
{ 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()
aboutToAppear() {
// this.ratio = globalThis.ratio
this.ratio = AppStorage.get<number>('ratio') || 0
this.openFlag = true
const fileUtil = new FileUtils(this.context)
this.fileUtil = fileUtil
this.getVideoConfig()
}
build() {
Flex({
justifyContent: FlexAlign.SpaceBetween,
direction: FlexDirection.Column
}) {
HeaderComponent({
shortLogo: false
})
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,
'port')}/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%").border({
color: "red",
width: 1
}).padding(20)
})
}.width("70%").height("100%").padding(40)
async getFileHandleCode(td: number): Promise<void> {
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()
// 右边视频配置区域
Column() {
// 设置
ButtonComponent({
type: "0",
click: () => {
this.dialogController.open()
}
})
// 录像
ButtonComponent({
type: "1",
click: () => {
this.dialogController.open()
}
})
// 停止
ButtonComponent({
type: "2",
click: () => {
this.dialogController.open()
}
})
// 抓图
ButtonComponent({
type: "3",
click: () => {
this.dialogController.open()
}
})
}
.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%"
})
}
}
outClick() {
this.openFlag = false
}
async onPageShow() {
}
async getVideoConfig() {
const data = await this.fileUtil.readFile(GlobalConfig.commonFileWriteAddress + '/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
@Component
struct ButtonComponent {
@State type: string = "0"
click?: () => void
// 使用映射表来存储类型与图片资源的对应关系
private readonly imageResources: Record<string, Resource> = {
"3": $r('app.media.zhuatu'),
"2": $r('app.media.tingzhi'),
"1": $r('app.media.luxiang'),
"0": $r('app.media.shezhi')
}
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 || false)
.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 || false)
.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 || false)
.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 || false)
.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 || false)
.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 || false)
.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 || false)
.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 || false)
.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 || false)
.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 || false)
.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%')
Image(this.imageResources[this.type])
.width(500)
.height(100)
.objectFit(ImageFit.Contain)
.margin({
top: 20
})
.onClick(() => {
this.click && this.click()
})
}
}

View File

@ -0,0 +1,472 @@
import { VideoConfig } from '../../model';
@CustomDialog
export default struct VideoConfigComponent {
@Prop videoConfig: VideoConfig
private controller?: CustomDialogController;
build() {
Column() {
Flex({
justifyContent: FlexAlign.SpaceBetween,
alignItems: ItemAlign.Center
}) {
Text("视频参数设置").fontSize(30).fontWeight(FontWeight.Bold)
Row() {
Image($r('app.media.fh')).height(55).objectFit(ImageFit.Contain).onClick(() => {
this.controller?.close()
})
Image($r('app.media.bc')).height(55).objectFit(ImageFit.Contain).onClick(() => {
console.log(JSON.stringify(this.videoConfig))
})
}
}.padding({
left: 20,
right: 20
}).height(60)
Column() {
// 第一行
Row() {
labelComponent({
text: "视频路数",
})
textInputComponent({
value: this.videoConfig?.videoNum,
change: (value: string) => {
this.videoConfig.videoNum = value;
}
})
partitionSpace()
checkboxComponent({
value: this.videoConfig.faceFlag,
change: (value: boolean) => {
this.videoConfig.faceFlag = value;
}
})
labelComponent({
text: "启用人脸对比"
})
textInputComponent({
value: this.videoConfig.rlls,
change: (value: string) => {
this.videoConfig.rlls = value;
}
})
partitionSpace()
labelComponent({
text: "拍照通道"
})
textInputComponent({
value: this.videoConfig.pztd,
change: (value: string) => {
this.videoConfig.pztd = value;
}
})
partitionSpace()
labelComponent({
text: "设备类型"
})
textInputComponent({
value: "海康"
})
partitionSpace()
labelComponent({
text: "视频遮挡报警阈值"
})
textInputComponent({
value: this.videoConfig.zdyz,
change: (value: string) => {
this.videoConfig.zdyz = value;
}
})
}
// 第二行
Flex() {
Column() {
titleComponent()
blockComponent({
label: "第一路"
})
blockComponent({
label: "第二路"
})
blockComponent({
label: "第三路"
})
blockComponent({
label: "第四路"
})
}.width("75%")
Column() {
routeSettingComponent({
videoConfig: this.videoConfig,
change: (value: VideoConfig) => {
this.videoConfig = value;
},
})
routeSettingComponent({
title: "视频遮挡",
videoConfig: this.videoConfig,
change: (value: VideoConfig) => {
this.videoConfig = value;
},
})
}.width("25%")
.padding({
top: 50
})
}
// 第三行
Row() {
checkboxComponent({
value: this.videoConfig.shuiying,
change: (value: boolean) => {
this.videoConfig.shuiying = value;
}
})
labelComponent({
text: "照片叠加文字"
})
partitionSpace()
labelComponent({
text: "位置"
})
textInputComponent({
value: this.videoConfig.wz,
change: (value: string) => {
this.videoConfig.wz = value;
}
})
partitionSpace()
labelComponent({
text: "叠加内容"
})
textInputComponent({
value: this.videoConfig.text1,
change: (value: string) => {
this.videoConfig.text1 = value;
}
})
labelComponent({
text: "+"
})
textInputComponent({
value: this.videoConfig.text2,
change: (value: string) => {
this.videoConfig.text2 = value;
}
})
labelComponent({
text: "+"
})
textInputComponent({
value: this.videoConfig.text3,
change: (value: string) => {
this.videoConfig.text3 = value;
}
})
partitionSpace()
partitionSpace()
labelComponent({
text: "分隔符"
})
textInputComponent({
value: this.videoConfig.dolt,
change: (value: string) => {
this.videoConfig.dolt = value;
}
})
partitionSpace()
labelComponent({
text: "文字大小"
})
textInputComponent({
value: this.videoConfig.fontSize,
change: (value: string) => {
this.videoConfig.fontSize = value;
}
})
}.margin({
top: 20
})
}.backgroundColor("#E3E2DE").width("100%").height("100%").margin(10)
}.height("60%")
.width("100%")
.backgroundColor("#C9C4B9")
.borderRadius({
topLeft: 20,
topRight: 20
})
}
}
@Component
struct routeSettingComponent {
@State title: string = "录像范围"
@Prop videoConfig: VideoConfig
change?: (value: VideoConfig) => void
build() {
Row() {
Row() {
Text(this.title).fontSize(24)
}.width(150).justifyContent(FlexAlign.End)
Flex({
wrap: FlexWrap.Wrap
}) {
if (this.title === "录像范围") {
Row() {
labelComponent({
text: "一路"
})
checkboxComponent({
value: this.videoConfig.videoRecord1,
change: (value: boolean) => {
this.videoConfig.videoRecord1 = value;
this.change?.(this.videoConfig);
}
})
}
Row() {
labelComponent({
text: "二路"
})
checkboxComponent({
value: this.videoConfig.videoRecord2,
change: (value: boolean) => {
this.videoConfig.videoRecord2 = value;
this.change?.(this.videoConfig);
}
})
}
Row() {
labelComponent({
text: "三路"
})
checkboxComponent({
value: this.videoConfig.videoRecord3,
change: (value: boolean) => {
this.videoConfig.videoRecord3 = value;
this.change?.(this.videoConfig);
}
})
}
Row() {
labelComponent({
text: "四路"
})
checkboxComponent({
value: this.videoConfig.videoRecord4,
change: (value: boolean) => {
this.videoConfig.videoRecord4 = value;
this.change?.(this.videoConfig);
}
})
}
} else {
Row() {
labelComponent({
text: "一路"
})
checkboxComponent({
value: this.videoConfig.spzd1,
change: (value: boolean) => {
this.videoConfig.spzd1 = value;
this.change?.(this.videoConfig);
}
})
}
Row() {
labelComponent({
text: "二路"
})
checkboxComponent({
value: this.videoConfig.spzd2,
change: (value: boolean) => {
this.videoConfig.spzd2 = value;
this.change?.(this.videoConfig);
}
})
}
Row() {
labelComponent({
text: "三路"
})
checkboxComponent({
value: this.videoConfig.spzd3,
change: (value: boolean) => {
this.videoConfig.spzd3 = value;
this.change?.(this.videoConfig);
}
})
}
Row() {
labelComponent({
text: "四路"
})
checkboxComponent({
value: this.videoConfig.spzd4,
change: (value: boolean) => {
this.videoConfig.spzd4 = value;
this.change?.(this.videoConfig);
}
})
}
}
}.width(300)
}.justifyContent(FlexAlign.Start)
}
}
@Component
struct checkboxComponent {
@State value: boolean = false
change?: (value: boolean) => void
build() {
Checkbox({ name: 'checkbox1', group: 'checkboxGroup' })
.width(40)
.height(40)
.select(this.value)
.onChange((value: boolean) => {
console.info('Checkbox1 change is' + value)
this.value = value;
this.change?.(value);
})
}
}
@Component
struct blockComponent {
@State label: string = "第一路"
build() {
Row() {
Row() {
Text(this.label).fontSize(20)
}.width(100)
// IP地址
textInputComponent({
value: "",
widthValue: 200
})
// 通道号
textInputComponent({
value: "",
widthValue: 100
})
// 用户名
textInputComponent({
value: "",
widthValue: 200
})
// 密码
textInputComponent({
value: "",
widthValue: 200
})
// 端口号
textInputComponent({
value: "",
widthValue: 100
})
}.margin({
top: 10
})
}
}
@Component
struct labelComponent {
@State text: string = "视频路数"
build() {
Text(this.text)
.fontSize(24)
.fontWeight(FontWeight.Bold)
}
}
@Component
struct textInputComponent {
@Prop value: string
@State widthValue: number = 120
change?: (value: string) => void
build() {
TextInput({
text: this.value,
})
.type(InputType.Normal)
.borderRadius(0)
.fontSize(20)
.width(this.widthValue)
.height(50)
.margin({ left: 15, right: 15 })
.onChange((value) => {
this.value = value;
this.change?.(value);
})
}
}
@Component
struct partitionSpace {
build() {
Row() {
}.width(20).height(20)
}
}
@Component
struct titleComponent {
@Styles
commStyle(){
.width(220)
.height(69)
.backgroundImage($r('app.media.button_nor'))
.backgroundImageSize({ width: '100%', height: '100%' })
}
build() {
Row() {
Row() {
}.width(100)
Row() {
Text("IP地址")
}.width(200).margin({ left: 15, right: 15 }).alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Center)
Row() {
Text("通道号")
}.width(100).margin({ left: 15, right: 15 }).alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Center)
Row() {
Text("用户名")
}.width(200).margin({ left: 15, right: 15 }).alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Center)
Row() {
Text("密码")
}.width(200).margin({ left: 15, right: 15 }).alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Center)
Row() {
Text("端口号")
}.width(100).margin({ left: 15, right: 15 }).alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Center)
}.height(50)
}
}

View File

@ -104,7 +104,7 @@ export default struct HeaderComponent {
})
}
}
}
}.width("100%")
.height(100)
}
}