From 690f28381f18b14df2bd3095ee8747c6737c690d Mon Sep 17 00:00:00 2001 From: wangzhongjie Date: Fri, 6 Jun 2025 13:37:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=86=E9=A2=91=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entry/src/main/ets/pages/Index.ets | 10 +- entry/src/main/ets/pages/VideoConfig.ets | 112 ++++++++++++++++-- .../src/main/ets/pages/VideoConfig/Config.ets | 86 ++++++++++---- .../judgeSDK/utils/voiceAnnouncements.ets | 11 +- 4 files changed, 176 insertions(+), 43 deletions(-) diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index 302f27b..3c55ff2 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -76,17 +76,11 @@ struct Index { } async onPageShow(): Promise { - this.baseInfo = AppStorage.get('baseInfo')! await UseAuth(this.context) + this.avPlayer.playAudio(['welcome.wav']) + this.baseInfo = AppStorage.get('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') } diff --git a/entry/src/main/ets/pages/VideoConfig.ets b/entry/src/main/ets/pages/VideoConfig.ets index 8c26cfb..001b1e2 100644 --- a/entry/src/main/ets/pages/VideoConfig.ets +++ b/entry/src/main/ets/pages/VideoConfig.ets @@ -1,12 +1,18 @@ import { VideoConfigData } from '../mock' -import { VideoConfig, VideoItemType } from '../model' +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 VideoConfigPage { @State videoConfig: VideoConfig = VideoConfigData + @State oldVideoConfig: VideoConfig = VideoConfigData @State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X @State openFlag: boolean = true // 是否自动播放 @@ -15,11 +21,29 @@ struct VideoConfigPage { // 弹窗 dialogController: CustomDialogController = new CustomDialogController({ builder: VideoConfigComponent({ - videoConfig: this.videoConfig + 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 + } + // 文件操作 + private fileUtil: FileUtils + private context = getContext(this) as common.UIAbilityContext; // 视频控制器 private controller1: VideoController = new VideoController() private controller2: VideoController = new VideoController() @@ -33,6 +57,37 @@ struct VideoConfigPage { { td: 'td4', controller: this.controller4, src: '' }, ] + aboutToAppear(): void { + this.fileUtil = new FileUtils(this.context) + this.readVideoConfig() + } + + // 读取视频配置 + async readVideoConfig() { + const data = await this.fileUtil.readFile(GlobalConfig.commonFileWriteAddress + '/config/config3.txt'); + this.videoConfig = JSON.parse(data) + this.oldVideoConfig = JSON.parse(data); + } + + // 保存视频配置 + async saveVideoConfig() { + const folderPath = await this.fileUtil.initFolder(`/config`); + console.log(this.oldVideoConfig.videoNum, this.videoConfig.videoNum, "查看") + this.fileUtil.addFile(`${folderPath}/config3.txt`, JSON.stringify(this.videoConfig)) + } + + async getFileHandleCode(td: number): Promise { + return new Promise(async (resolve, reject) => { + try { + const record_handle = await startRecordVideo(this.videoConfig, td, this.context, 'lp') + Reflect.set(this.recordHandleObj, 'rocord_handle' + td, record_handle) + resolve(true) + } catch (error) { + reject(false) + } + }) + } + build() { Flex({ justifyContent: FlexAlign.SpaceBetween, @@ -80,22 +135,65 @@ struct VideoConfigPage { // 录像 ButtonComponent({ type: "1", - click: () => { - this.dialogController.open() + click: async () => { + if (!this.videoConfig.videoRecord4 && !this.videoConfig.videoRecord3 && !this.videoConfig.videoRecord2 && !this.videoConfig.videoRecord1) { + Prompt.showToast({ + message: '请选择录像通道', + duration: 3000 + }) + return + } + + for (let i = 1; i <= 4; i++) { + if (Reflect.get(this.videoConfig, 'videoRecord' + i)) { + await this.getFileHandleCode(i) + } + } + // 录像开始 + Prompt.showToast({ + message: '录像开始!', + duration: 3000 + }) + } }) // 停止 ButtonComponent({ type: "2", click: () => { - this.dialogController.open() + for (let i = 1; i <= 4; i++) { + if (Reflect.get(this.recordHandleObj, 'rocord_handle' + i) !== 0) { + endRecordVideo(Reflect.get(this.recordHandleObj, 'rocord_handle' + i)) + Reflect.set(this.recordHandleObj, 'rocord_handle' + i, 0) + } + } + Prompt.showToast({ + message: '录像已停止!', + duration: 3000 + }) } }) // 抓图 ButtonComponent({ type: "3", - click: () => { - this.dialogController.open() + click: async () => { + const arr = ['1', '2', '3', '4'] + if (!arr.includes(this.videoConfig.pztd)) { + Prompt.showToast({ + message: '请填写正确的拍照通道', + duration: 3000 + }) + return + } + try { + await takePhoto(this.videoConfig, this.context, 'pz/') + Prompt.showToast({ + message: '抓图完成', + duration: 3000 + }) + } catch (error) { + console.log("抓图失败", error) + } } }) } diff --git a/entry/src/main/ets/pages/VideoConfig/Config.ets b/entry/src/main/ets/pages/VideoConfig/Config.ets index 6242c03..269a84d 100644 --- a/entry/src/main/ets/pages/VideoConfig/Config.ets +++ b/entry/src/main/ets/pages/VideoConfig/Config.ets @@ -8,6 +8,8 @@ import TextInputComponent from './TextInput'; @CustomDialog export default struct VideoConfigComponent { @Prop videoConfig: VideoConfig + save?: (value: VideoConfig) => void; + back?: () => void; private controller?: CustomDialogController; build() { @@ -20,9 +22,11 @@ export default struct VideoConfigComponent { 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(() => { - console.log(JSON.stringify(this.videoConfig)) + this.controller?.close() + this.save?.(this.videoConfig); }) } }.padding({ @@ -93,16 +97,36 @@ export default struct VideoConfigComponent { Column() { titleComponent() blockComponent({ - label: "第一路" + label: "第一路", + num: 1, + videoConfig: this.videoConfig, + change: (value: VideoConfig) => { + this.videoConfig = value; + } }) blockComponent({ - label: "第二路" + label: "第二路", + num: 2, + videoConfig: this.videoConfig, + change: (value: VideoConfig) => { + this.videoConfig = value; + } }) blockComponent({ - label: "第三路" + label: "第三路", + num: 3, + videoConfig: this.videoConfig, + change: (value: VideoConfig) => { + this.videoConfig = value; + } }) blockComponent({ - label: "第四路" + label: "第四路", + num: 4, + videoConfig: this.videoConfig, + change: (value: VideoConfig) => { + this.videoConfig = value; + } }) }.width("75%") @@ -215,6 +239,9 @@ export default struct VideoConfigComponent { @Component struct blockComponent { @State label: string = "第一路" + @Prop videoConfig: VideoConfig + @State num: number = 1 + change?: (value: VideoConfig) => void; build() { Row() { @@ -224,28 +251,49 @@ struct blockComponent { // IP地址 TextInputComponent({ - value: "", - widthValue: 200 + value: this.videoConfig.ip, + widthValue: 200, + change: (value: string) => { + this.videoConfig.ip = value; + this.change?.(this.videoConfig); + } }) + // 通道号 TextInputComponent({ - value: "", - widthValue: 100 + 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: "", - widthValue: 200 + value: this.videoConfig.userName, + widthValue: 200, + change: (value: string) => { + this.videoConfig.userName = value; + this.change?.(this.videoConfig); + } }) // 密码 TextInputComponent({ - value: "", - widthValue: 200 + value: this.videoConfig.pwd, + widthValue: 200, + change: (value: string) => { + this.videoConfig.pwd = value; + this.change?.(this.videoConfig); + } }) // 端口号 TextInputComponent({ - value: "", - widthValue: 100 + value: this.videoConfig.port, + widthValue: 100, + change: (value: string) => { + this.videoConfig.port = value; + this.change?.(this.videoConfig); + } }) }.margin({ top: 10 @@ -264,14 +312,6 @@ struct partitionSpace { @Component struct titleComponent { - @Styles - commStyle(){ - .width(220) - .height(69) - .backgroundImage($r('app.media.button_nor')) - .backgroundImageSize({ width: '100%', height: '100%' }) - } - build() { Row() { Row() { diff --git a/entry/src/main/ets/pages/judgeSDK/utils/voiceAnnouncements.ets b/entry/src/main/ets/pages/judgeSDK/utils/voiceAnnouncements.ets index 0017a10..58e4562 100644 --- a/entry/src/main/ets/pages/judgeSDK/utils/voiceAnnouncements.ets +++ b/entry/src/main/ets/pages/judgeSDK/utils/voiceAnnouncements.ets @@ -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 { + 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 { return new Promise(async (resolve, reject) => { - const context = AppStorage.get('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接口成功调用后触发该状态机上报