Compare commits
6 Commits
520e29fbf9
...
5efb9cd735
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5efb9cd735 | ||
|
|
796c4c4171 | ||
|
|
690f28381f | ||
|
|
36490c4797 | ||
|
|
d06f1c1d5a | ||
|
|
a0a93fd347 |
@ -3,7 +3,7 @@ import { carConfigurationInfo, uploadExamCarCheckResult } from '../api/checkCar'
|
||||
import TopLogo from './compontents/TopLogo';
|
||||
import testNapi from '@ohos.hiserialsdk';
|
||||
import { DwMapData, PassData, RealNumData, StackValueData, WarnFlagData, WarnFlagTipData } from '../mock';
|
||||
import { BaseInfoType, RouteParamsType } from '../model/Common';
|
||||
import { RouteParamsType } from '../model/Common';
|
||||
import { CarCheckDataType, CarConfigurationParams, CarInfoType } from '../model';
|
||||
import { BusinessError } from '@ohos.base';
|
||||
import { voiceService } from '../utils/Voice';
|
||||
@ -149,12 +149,12 @@ struct Index {
|
||||
this.checkListCopy = JSON.parse(JSON.stringify(this.checkList))
|
||||
return
|
||||
}
|
||||
const baseInfo = AppStorage.get<BaseInfoType>("baseInfo")
|
||||
const deviceNo = AppStorage.get<string>("deviceNo")
|
||||
//模拟真实数据
|
||||
const param: CarConfigurationParams = {
|
||||
body: {
|
||||
"carIdString": this.carInfo.carId || "", //考车ID
|
||||
"deviceNo": baseInfo?.deviceNo || ""
|
||||
"deviceNo": deviceNo || ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -76,17 +76,11 @@ struct Index {
|
||||
}
|
||||
|
||||
async onPageShow(): Promise<void> {
|
||||
this.baseInfo = AppStorage.get<BaseInfoType>('baseInfo')!
|
||||
await UseAuth(this.context)
|
||||
this.avPlayer.playAudio(['welcome.wav'])
|
||||
this.baseInfo = AppStorage.get<BaseInfoType>('baseInfo')!
|
||||
this.initParams()
|
||||
AppStorage.setOrCreate('singlePlay', false)
|
||||
this.context.resourceManager.getRawFileContent("welcome.wav")
|
||||
.then(() => {
|
||||
this.avPlayer.playAudio(['welcome.wav'])
|
||||
})
|
||||
.catch((error: BusinessError) => {
|
||||
console.log("getRawFileContent promise error is " + error);
|
||||
});
|
||||
this.num = 0
|
||||
AppStorage.setOrCreate('lsh', '1111111111111')
|
||||
}
|
||||
|
||||
@ -126,7 +126,6 @@ struct Index {
|
||||
const folderPath = await fileUtil.initFolder(`/config`);
|
||||
fileUtil.addFile(`${folderPath}/deviceNo.txt`, JSON.stringify(param))
|
||||
AppStorage.setOrCreate<string>('deviceNo', this.ip)
|
||||
// upDateTableByArray('DeviceInfoTable', [{ deviceId: this.ip }])
|
||||
registrationDeviceNo(param).then((res: ApiResponseType) => {
|
||||
if (res.registrationDeviceNoRsp && res.registrationDeviceNoRsp.head &&
|
||||
res.registrationDeviceNoRsp.head.resultCode == '0') {
|
||||
|
||||
@ -1,631 +1,243 @@
|
||||
|
||||
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 { 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'
|
||||
|
||||
@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 oldVideoConfig: VideoConfig = VideoConfigData
|
||||
@State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X
|
||||
@State inputFontSize: number = 10 //12
|
||||
@State rocordHandleObj: RecordHandleType = {
|
||||
@State openFlag: boolean = true
|
||||
// 是否自动播放
|
||||
@State isAutoPlay: boolean = true
|
||||
@State showControls: boolean = false
|
||||
// 弹窗
|
||||
dialogController: CustomDialogController = new CustomDialogController({
|
||||
builder: VideoConfigComponent({
|
||||
videoConfig: this.videoConfig,
|
||||
back: () => {
|
||||
console.log("返回")
|
||||
this.videoConfig = this.oldVideoConfig
|
||||
},
|
||||
save: (config: VideoConfig) => {
|
||||
console.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
|
||||
}
|
||||
@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;
|
||||
// 视频控制器
|
||||
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(): 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`);
|
||||
console.log(this.oldVideoConfig.videoNum, this.videoConfig.videoNum, "查看")
|
||||
this.fileUtil.addFile(`${folderPath}/config3.txt`, JSON.stringify(this.videoConfig))
|
||||
}
|
||||
|
||||
async getFileHandleCode(td: number): Promise<Boolean> {
|
||||
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() {
|
||||
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)
|
||||
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,
|
||||
'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)
|
||||
})
|
||||
}.margin({ top: 37 * this.ratio, left: 30 * this.ratio }).width(600 * this.ratio).height(600 * this.ratio)
|
||||
}.width("70%").height("100%").padding(40)
|
||||
|
||||
// 右边视频配置区域
|
||||
|
||||
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({
|
||||
// 设置
|
||||
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
|
||||
}
|
||||
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);
|
||||
if (Reflect.get(this.videoConfig, 'videoRecord' + i)) {
|
||||
await this.getFileHandleCode(i)
|
||||
}
|
||||
}
|
||||
this.videoStartFlag = false
|
||||
promptAction.showToast({
|
||||
message: '录像开始',
|
||||
// 录像开始
|
||||
Prompt.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
|
||||
// }
|
||||
// }
|
||||
}
|
||||
})
|
||||
// 停止
|
||||
ButtonComponent({
|
||||
type: "2",
|
||||
click: () => {
|
||||
for (let i = 1; i <= 4; i++) {
|
||||
if (Reflect.get(this.rocordHandleObj, 'rocord_handle' + i)) {
|
||||
Reflect.set(this.rocordHandleObj, 'rocord_handle' + i, 0);
|
||||
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)
|
||||
}
|
||||
}
|
||||
endRecordVideo(this.rocordHandleObj);
|
||||
|
||||
promptAction.showToast({
|
||||
message: '录像结束',
|
||||
Prompt.showToast({
|
||||
message: '录像已停止!',
|
||||
duration: 3000
|
||||
})
|
||||
})
|
||||
Image($r('app.media.zhuatu'))
|
||||
.width(215 * this.ratio)
|
||||
.height(64 * this.ratio)
|
||||
.onClick(async () => {
|
||||
}
|
||||
})
|
||||
// 抓图
|
||||
ButtonComponent({
|
||||
type: "3",
|
||||
click: async () => {
|
||||
const arr = ['1', '2', '3', '4']
|
||||
if (!arr.includes(this.param.pztd||"")) {
|
||||
promptAction.showToast({
|
||||
if (!arr.includes(this.videoConfig.pztd)) {
|
||||
Prompt.showToast({
|
||||
message: '请填写正确的拍照通道',
|
||||
duration: 3000
|
||||
})
|
||||
return
|
||||
}
|
||||
if (this.takePhotoFlag) {
|
||||
return
|
||||
}
|
||||
this.takePhotoFlag = true
|
||||
try {
|
||||
await takePhoto(this.param, this.context, 'pz/')
|
||||
promptAction.showToast({
|
||||
await takePhoto(this.videoConfig, this.context, 'pz/')
|
||||
Prompt.showToast({
|
||||
message: '抓图完成',
|
||||
duration: 3000
|
||||
})
|
||||
this.takePhotoFlag = false
|
||||
// }).catch((err) => {
|
||||
// console.log('daihai err: ' + err)
|
||||
// })
|
||||
|
||||
} catch (error) {
|
||||
console.log('daihai', error)
|
||||
console.log("抓图失败", 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 } })
|
||||
.width("30%")
|
||||
.height("100%")
|
||||
.padding(100)
|
||||
.justifyContent(FlexAlign.End)
|
||||
.alignItems(HorizontalAlign.Center)
|
||||
}
|
||||
|
||||
}.backgroundColor('#1A1A1A').width('100%').height('100%')
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
.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<string, Resource> = {
|
||||
"3": $r('app.media.zhuatu'),
|
||||
"2": $r('app.media.tingzhi'),
|
||||
"1": $r('app.media.luxiang'),
|
||||
"0": $r('app.media.shezhi')
|
||||
}
|
||||
|
||||
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
|
||||
build() {
|
||||
Image(this.imageResources[this.type])
|
||||
.width(500)
|
||||
.height(100)
|
||||
.objectFit(ImageFit.Contain)
|
||||
.margin({
|
||||
top: 20
|
||||
})
|
||||
.onClick(() => {
|
||||
this.click && this.click()
|
||||
})
|
||||
}
|
||||
}
|
||||
17
entry/src/main/ets/pages/VideoConfig/CheckBox.ets
Normal file
17
entry/src/main/ets/pages/VideoConfig/CheckBox.ets
Normal file
@ -0,0 +1,17 @@
|
||||
@Component
|
||||
export default 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);
|
||||
})
|
||||
}
|
||||
}
|
||||
342
entry/src/main/ets/pages/VideoConfig/Config.ets
Normal file
342
entry/src/main/ets/pages/VideoConfig/Config.ets
Normal file
@ -0,0 +1,342 @@
|
||||
import { VideoConfig } from '../../model';
|
||||
import CheckboxComponent from './CheckBox';
|
||||
import LabelComponent from './Label';
|
||||
import RouteSettingComponent from './RouteSetting';
|
||||
import TextInputComponent from './TextInput';
|
||||
|
||||
|
||||
@CustomDialog
|
||||
export default struct VideoConfigComponent {
|
||||
@Prop videoConfig: VideoConfig
|
||||
save?: (value: VideoConfig) => void;
|
||||
back?: () => void;
|
||||
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()
|
||||
this.back?.();
|
||||
})
|
||||
Image($r('app.media.bc')).height(55).objectFit(ImageFit.Contain).onClick(() => {
|
||||
this.controller?.close()
|
||||
this.save?.(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: "第一路",
|
||||
num: 1,
|
||||
videoConfig: this.videoConfig,
|
||||
change: (value: VideoConfig) => {
|
||||
this.videoConfig = value;
|
||||
}
|
||||
})
|
||||
blockComponent({
|
||||
label: "第二路",
|
||||
num: 2,
|
||||
videoConfig: this.videoConfig,
|
||||
change: (value: VideoConfig) => {
|
||||
this.videoConfig = value;
|
||||
}
|
||||
})
|
||||
blockComponent({
|
||||
label: "第三路",
|
||||
num: 3,
|
||||
videoConfig: this.videoConfig,
|
||||
change: (value: VideoConfig) => {
|
||||
this.videoConfig = value;
|
||||
}
|
||||
})
|
||||
blockComponent({
|
||||
label: "第四路",
|
||||
num: 4,
|
||||
videoConfig: this.videoConfig,
|
||||
change: (value: VideoConfig) => {
|
||||
this.videoConfig = value;
|
||||
}
|
||||
})
|
||||
}.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 blockComponent {
|
||||
@State label: string = "第一路"
|
||||
@Prop videoConfig: VideoConfig
|
||||
@State num: number = 1
|
||||
change?: (value: VideoConfig) => void;
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
Row() {
|
||||
Text(this.label).fontSize(20)
|
||||
}.width(100)
|
||||
|
||||
// IP地址
|
||||
TextInputComponent({
|
||||
value: this.videoConfig.ip,
|
||||
widthValue: 200,
|
||||
change: (value: string) => {
|
||||
this.videoConfig.ip = value;
|
||||
this.change?.(this.videoConfig);
|
||||
}
|
||||
})
|
||||
|
||||
// 通道号
|
||||
TextInputComponent({
|
||||
value: Reflect.get(this.videoConfig, `td${this.num}`) || '',
|
||||
widthValue: 100,
|
||||
change: (value: string) => {
|
||||
Reflect.set(this.videoConfig, `td${this.num}`, value);
|
||||
this.change?.(this.videoConfig);
|
||||
}
|
||||
})
|
||||
// 用户名
|
||||
TextInputComponent({
|
||||
value: this.videoConfig.userName,
|
||||
widthValue: 200,
|
||||
change: (value: string) => {
|
||||
this.videoConfig.userName = value;
|
||||
this.change?.(this.videoConfig);
|
||||
}
|
||||
})
|
||||
// 密码
|
||||
TextInputComponent({
|
||||
value: this.videoConfig.pwd,
|
||||
widthValue: 200,
|
||||
change: (value: string) => {
|
||||
this.videoConfig.pwd = value;
|
||||
this.change?.(this.videoConfig);
|
||||
}
|
||||
})
|
||||
// 端口号
|
||||
TextInputComponent({
|
||||
value: this.videoConfig.port,
|
||||
widthValue: 100,
|
||||
change: (value: string) => {
|
||||
this.videoConfig.port = value;
|
||||
this.change?.(this.videoConfig);
|
||||
}
|
||||
})
|
||||
}.margin({
|
||||
top: 10
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Component
|
||||
struct partitionSpace {
|
||||
build() {
|
||||
Row() {
|
||||
}.width(20).height(20)
|
||||
}
|
||||
}
|
||||
|
||||
@Component
|
||||
struct titleComponent {
|
||||
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)
|
||||
}
|
||||
}
|
||||
11
entry/src/main/ets/pages/VideoConfig/Label.ets
Normal file
11
entry/src/main/ets/pages/VideoConfig/Label.ets
Normal file
@ -0,0 +1,11 @@
|
||||
@Component
|
||||
export default struct LabelComponent {
|
||||
@State text: string = "视频路数"
|
||||
|
||||
build() {
|
||||
Text(this.text)
|
||||
.fontSize(24)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
}
|
||||
}
|
||||
|
||||
129
entry/src/main/ets/pages/VideoConfig/RouteSetting.ets
Normal file
129
entry/src/main/ets/pages/VideoConfig/RouteSetting.ets
Normal file
@ -0,0 +1,129 @@
|
||||
import { VideoConfig } from '../../model'
|
||||
import CheckboxComponent from './CheckBox'
|
||||
import LabelComponent from './Label'
|
||||
|
||||
|
||||
@Component
|
||||
export default 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)
|
||||
}
|
||||
}
|
||||
22
entry/src/main/ets/pages/VideoConfig/TextInput.ets
Normal file
22
entry/src/main/ets/pages/VideoConfig/TextInput.ets
Normal file
@ -0,0 +1,22 @@
|
||||
@Component
|
||||
export default 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);
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -16,6 +16,8 @@ export default struct HeaderComponent {
|
||||
@State shortLogo: boolean = true
|
||||
@State time: string = ""
|
||||
@State timer: number = 0
|
||||
@State shouBackArea: boolean = false
|
||||
@State customizeReturnArea: boolean = false
|
||||
// 自定义返回区域
|
||||
@BuilderParam
|
||||
backAreaBuilder?: () => void = this.customBuilder
|
||||
@ -66,45 +68,45 @@ export default struct HeaderComponent {
|
||||
left: 10
|
||||
})
|
||||
}
|
||||
if (this.shortLogo) {
|
||||
if (this.backAreaBuilder) {
|
||||
this.backAreaBuilder()
|
||||
} else {
|
||||
if (this.customizeReturnArea && this.backAreaBuilder) {
|
||||
this.backAreaBuilder()
|
||||
} else {
|
||||
if (this.shouBackArea) {
|
||||
Image($r('app.media.topB_back')).height(100).onClick(() => {
|
||||
router.back()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
|
||||
Row() {
|
||||
Image($r('app.media.btn_setting')).height(100).onClick(() => {
|
||||
console.log("点击设置")
|
||||
router.pushUrl({
|
||||
url: 'pages/Settings',
|
||||
}, router.RouterMode.Single);
|
||||
})
|
||||
Image($r('app.media.btn_back')).height(100).onClick(() => {
|
||||
Prompt.showDialog({
|
||||
title: "提示",
|
||||
message: "确定要退出吗?",
|
||||
buttons: [
|
||||
{
|
||||
text: '取消',
|
||||
color: '#666666'
|
||||
},
|
||||
{
|
||||
text: '退出',
|
||||
color: '#666666'
|
||||
}
|
||||
],
|
||||
success: () => {
|
||||
(getContext(this) as common.UIAbilityContext).terminateSelf()
|
||||
}
|
||||
} else {
|
||||
Row() {
|
||||
Image($r('app.media.btn_setting')).height(100).onClick(() => {
|
||||
console.log("点击设置")
|
||||
router.pushUrl({
|
||||
url: 'pages/Settings',
|
||||
}, router.RouterMode.Single);
|
||||
})
|
||||
})
|
||||
Image($r('app.media.btn_back')).height(100).onClick(() => {
|
||||
Prompt.showDialog({
|
||||
title: "提示",
|
||||
message: "确定要退出吗?",
|
||||
buttons: [
|
||||
{
|
||||
text: '取消',
|
||||
color: '#666666'
|
||||
},
|
||||
{
|
||||
text: '退出',
|
||||
color: '#666666'
|
||||
}
|
||||
],
|
||||
success: () => {
|
||||
(getContext(this) as common.UIAbilityContext).terminateSelf()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}.width("100%")
|
||||
.height(100)
|
||||
}
|
||||
}
|
||||
@ -29,6 +29,7 @@ export default class VoiceAnnounce {
|
||||
async playAudio(urls: string[], shit?: boolean, callbackFn?: Function) {
|
||||
const isStopped = this.isStopped;
|
||||
const queue = this.queue;
|
||||
console.log(TAG, "播放")
|
||||
|
||||
const tempUrls: Queue[] = urls.map((url, index) => {
|
||||
const callback: Function | undefined = (index === urls.length - 1) ? callbackFn : undefined
|
||||
@ -94,6 +95,7 @@ class AVPlayer {
|
||||
|
||||
// 以下为使用资源管理接口获取打包在HAP内的媒体资源文件并通过fdSrc属性进行播放示例
|
||||
async play(name: string, callback: Function): Promise<boolean> {
|
||||
console.log(TAG, 'play => 开始播放语音')
|
||||
try {
|
||||
//检查SD中的语音
|
||||
// console.info('surenjun name',name)
|
||||
@ -128,7 +130,7 @@ class AVPlayer {
|
||||
this.endCallback = callback
|
||||
this.avPlayer = await media.createAVPlayer();
|
||||
return new Promise(async (resolve, reject) => {
|
||||
await this.setAVPlayerCallback(() => {
|
||||
this.setAVPlayerCallback(() => {
|
||||
resolve(true)
|
||||
});
|
||||
try {
|
||||
@ -148,8 +150,7 @@ class AVPlayer {
|
||||
|
||||
async queryFile(displayName: string): Promise<mediaLibrary.FileAsset> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const context = AppStorage.get<common.UIAbilityContext>('context')
|
||||
const mediaLib = mediaLibrary.getMediaLibrary(context);
|
||||
const mediaLib = mediaLibrary.getMediaLibrary(this.context);
|
||||
let fileResult = await mediaLib.getFileAssets({
|
||||
selections: `media_type=? AND display_name = ?`,
|
||||
selectionArgs: [`${mediaLibrary.MediaType.AUDIO}`, displayName],
|
||||
@ -197,14 +198,14 @@ class AVPlayer {
|
||||
case 'prepared': // prepare调用成功后上报该状态机
|
||||
console.info(TAG, '播放资源播放')
|
||||
this.avPlayer!.play();
|
||||
// this.voiceStatus = 'playing'
|
||||
// this.voiceStatus = 'playing'
|
||||
break;
|
||||
case 'playing': // play成功调用后触发该状态机上报
|
||||
break;
|
||||
case 'paused': // pause成功调用后触发该状态机上报
|
||||
break;
|
||||
case 'completed': // 播放结束后触发该状态机上报
|
||||
// this.voiceStatus = 'completed'
|
||||
// this.voiceStatus = 'completed'
|
||||
this.avPlayer!.stop(); //调用播放结束接口
|
||||
break;
|
||||
case 'stopped': // stop接口成功调用后触发该状态机上报
|
||||
|
||||
@ -34,8 +34,8 @@ const FILE_ASSET_FETCH_COLUMNS = [
|
||||
|
||||
|
||||
export async function startRecordVideo(param: VideoConfig, td: number, context: common.UIAbilityContext, dir: string,
|
||||
path?: string,
|
||||
index?: number): Promise<number> {
|
||||
path?: string,
|
||||
index?: number): Promise<number> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let video_uri = `rtsp://${param.userName}:${param.pwd}@${param.ip}:${param.port}/h264/ch${td}/main/av_stream`;
|
||||
if (rtsp_server != null) {
|
||||
@ -168,7 +168,7 @@ export async function takePhoto(
|
||||
|
||||
if (flag === 0) {
|
||||
return new Promise<takePhotoParam>((resolve, reject) => {
|
||||
rtsp_server.detectVideoSnapshotSize(video_uri, fileName, false,(err: BusinessError, snapResult: record.RtspResult) => {
|
||||
rtsp_server.detectVideoSnapshotSize(video_uri, fileName, false, (err: BusinessError, snapResult: record.RtspResult) => {
|
||||
if (snapResult && snapResult.errorCode === 0) {
|
||||
const result: takePhotoParam = {
|
||||
fileSize: snapResult.fileSize,
|
||||
@ -197,7 +197,7 @@ export async function takePhoto(
|
||||
const time = GetCurrentTime();
|
||||
const date = time.split(' ')[0];
|
||||
const dirName = dir || date;
|
||||
rtsp_server.detectVideoSnapshotSize(video_uri, fileName, true,(err: BusinessError, snapResult: record.RtspResult) => {
|
||||
rtsp_server.getVideoSnapshot(context, video_uri, fileName, dirName, true, (err: BusinessError, snapResult: record.RtspResult) => {
|
||||
if (snapResult && snapResult.errorCode === 0) {
|
||||
const result: takePhotoParam = {
|
||||
fileSize: snapResult.fileSize,
|
||||
@ -234,7 +234,7 @@ export async function deleteAllFileByPiC(dirName: string, type = 1, context: com
|
||||
}
|
||||
|
||||
export async function deleteAllVideos(context: common.UIAbilityContext, type: photoAccessHelper.AlbumType,
|
||||
subType: photoAccessHelper.AlbumSubtype): Promise<void> {
|
||||
subType: photoAccessHelper.AlbumSubtype): Promise<void> {
|
||||
let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.Album> | null = null;
|
||||
let count = 0;
|
||||
try {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user