Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Xts Acts
提交
8ea871d1
X
Xts Acts
项目概览
OpenHarmony
/
Xts Acts
大约 1 年 前同步成功
通知
9
Star
22
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
X
Xts Acts
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
8ea871d1
编写于
3月 20, 2023
作者:
O
openharmony_ci
提交者:
Gitee
3月 20, 2023
浏览文件
操作
浏览文件
下载
差异文件
!8074 新增camera&audio&player validator用例
Merge pull request !8074 from 秦莉文/master
上级
1a33fb29
26f6d137
变更
36
展开全部
隐藏空白更改
内联
并排
Showing
36 changed file
with
4135 addition
and
575 deletion
+4135
-575
validator/acts_validator/AppScope/app.json
validator/acts_validator/AppScope/app.json
+1
-1
validator/acts_validator/src/main/ets/pages/Audio/AudioInputRoutingTypeC.ets
...dator/src/main/ets/pages/Audio/AudioInputRoutingTypeC.ets
+192
-0
validator/acts_validator/src/main/ets/pages/Audio/AudioInputRoutingWiredHeadset.ets
...rc/main/ets/pages/Audio/AudioInputRoutingWiredHeadset.ets
+192
-0
validator/acts_validator/src/main/ets/pages/Audio/AudioOutputRoutingBT.ets
...lidator/src/main/ets/pages/Audio/AudioOutputRoutingBT.ets
+172
-0
validator/acts_validator/src/main/ets/pages/Audio/AudioOutputRoutingTypeC.ets
...ator/src/main/ets/pages/Audio/AudioOutputRoutingTypeC.ets
+172
-0
validator/acts_validator/src/main/ets/pages/Audio/AudioOutputRoutingWiredHeadset.ets
...c/main/ets/pages/Audio/AudioOutputRoutingWiredHeadset.ets
+171
-0
validator/acts_validator/src/main/ets/pages/Audio/Audio_index.ets
...r/acts_validator/src/main/ets/pages/Audio/Audio_index.ets
+5
-1
validator/acts_validator/src/main/ets/pages/Camera/CameraFlash.ets
.../acts_validator/src/main/ets/pages/Camera/CameraFlash.ets
+132
-0
validator/acts_validator/src/main/ets/pages/Camera/CameraFormat.ets
...acts_validator/src/main/ets/pages/Camera/CameraFormat.ets
+0
-118
validator/acts_validator/src/main/ets/pages/Camera/CameraOrientation.ets
...validator/src/main/ets/pages/Camera/CameraOrientation.ets
+174
-0
validator/acts_validator/src/main/ets/pages/Camera/CameraPhotoFormat.ets
...validator/src/main/ets/pages/Camera/CameraPhotoFormat.ets
+254
-0
validator/acts_validator/src/main/ets/pages/Camera/CameraPreviewFormat.ets
...lidator/src/main/ets/pages/Camera/CameraPreviewFormat.ets
+227
-0
validator/acts_validator/src/main/ets/pages/Camera/CameraSerialPhoto.ets
...validator/src/main/ets/pages/Camera/CameraSerialPhoto.ets
+189
-0
validator/acts_validator/src/main/ets/pages/Camera/CameraVideo.ets
.../acts_validator/src/main/ets/pages/Camera/CameraVideo.ets
+233
-58
validator/acts_validator/src/main/ets/pages/Camera/Camera_index.ets
...acts_validator/src/main/ets/pages/Camera/Camera_index.ets
+6
-3
validator/acts_validator/src/main/ets/pages/Player/PlayAudio.ets
...or/acts_validator/src/main/ets/pages/Player/PlayAudio.ets
+79
-0
validator/acts_validator/src/main/ets/pages/Player/PlayVideo.ets
...or/acts_validator/src/main/ets/pages/Player/PlayVideo.ets
+80
-0
validator/acts_validator/src/main/ets/pages/Player/Player_index.ets
...acts_validator/src/main/ets/pages/Player/Player_index.ets
+2
-1
validator/acts_validator/src/main/ets/pages/common/AudioContainer.ets
...ts_validator/src/main/ets/pages/common/AudioContainer.ets
+148
-0
validator/acts_validator/src/main/ets/pages/common/CameraFlashContainer.ets
...idator/src/main/ets/pages/common/CameraFlashContainer.ets
+164
-0
validator/acts_validator/src/main/ets/pages/common/CameraOrientationContainer.ets
.../src/main/ets/pages/common/CameraOrientationContainer.ets
+161
-0
validator/acts_validator/src/main/ets/pages/common/CameraPhotoContainer.ets
...idator/src/main/ets/pages/common/CameraPhotoContainer.ets
+153
-165
validator/acts_validator/src/main/ets/pages/common/CameraPreviewFormatContainer.ets
...rc/main/ets/pages/common/CameraPreviewFormatContainer.ets
+153
-0
validator/acts_validator/src/main/ets/pages/common/CameraVideoContainer.ets
...idator/src/main/ets/pages/common/CameraVideoContainer.ets
+153
-0
validator/acts_validator/src/main/ets/pages/model/AudioCapturer.ts
.../acts_validator/src/main/ets/pages/model/AudioCapturer.ts
+113
-0
validator/acts_validator/src/main/ets/pages/model/AudioRenderer.ts
.../acts_validator/src/main/ets/pages/model/AudioRenderer.ts
+108
-0
validator/acts_validator/src/main/ets/pages/model/CameraService.ts
.../acts_validator/src/main/ets/pages/model/CameraService.ts
+475
-224
validator/acts_validator/src/main/ets/pages/model/MediaUtils.ts
...tor/acts_validator/src/main/ets/pages/model/MediaUtils.ts
+6
-1
validator/acts_validator/src/main/ets/pages/model/mediaPlay.ts
...ator/acts_validator/src/main/ets/pages/model/mediaPlay.ts
+163
-0
validator/acts_validator/src/main/ets/pages/model/timeTools.ts
...ator/acts_validator/src/main/ets/pages/model/timeTools.ts
+19
-0
validator/acts_validator/src/main/resources/base/media/icon_pause.svg
...ts_validator/src/main/resources/base/media/icon_pause.svg
+13
-0
validator/acts_validator/src/main/resources/base/media/icon_play.svg
...cts_validator/src/main/resources/base/media/icon_play.svg
+13
-0
validator/acts_validator/src/main/resources/base/profile/main_pages.json
...validator/src/main/resources/base/profile/main_pages.json
+12
-3
validator/acts_validator/src/main/resources/rawfile/H264_AAC.mkv
...or/acts_validator/src/main/resources/rawfile/H264_AAC.mkv
+0
-0
validator/acts_validator/src/main/resources/rawfile/StarWars10s-1C-44100-2SW.wav
...r/src/main/resources/rawfile/StarWars10s-1C-44100-2SW.wav
+0
-0
validator/acts_validator/src/main/resources/rawfile/test_44100_2.wav
...cts_validator/src/main/resources/rawfile/test_44100_2.wav
+0
-0
未找到文件。
validator/acts_validator/AppScope/app.json
浏览文件 @
8ea871d1
...
...
@@ -10,7 +10,7 @@
"keepAlive"
:
true
,
"singleUser"
:
true
,
"minAPIVersion"
:
9
,
"targetAPIVersion"
:
9
,
"targetAPIVersion"
:
10
,
"car"
:
{
"apiCompatibleVersion"
:
9
,
"singleUser"
:
false
...
...
validator/acts_validator/src/main/ets/pages/Audio/AudioInputRoutingTypeC.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CustomContainer} from '../common/AudioContainer';
import FirstDialog from '../model/FirstDialog';
import AudioCapturer from '../model/AudioCapturer'
import Logger from '../model/Logger'
import prompt from '@ohos.prompt';
import audio from '@ohos.multimedia.audio'
import router from '@ohos.router';
import mediaPlay from '../model/mediaPlay'
@Entry
@Component
struct audioInputRouting {
@State name: string = 'AudioInputRoutingTest(TypeC)';
@State StepTips: string = '请参考提示信息依次执行如下操作';
@State Vue: boolean = false;
private tag: string = 'qlw'
@State deviceChange: audio.DeviceChangeAction = undefined
@State audioRoutingManager: audio.AudioRoutingManager = undefined
@State yesEnable: boolean = false
@State recorderEnable: boolean = false
@State stopEnable: boolean = false
@State playEnable: boolean = false
@State inputDevice: string = ''
async aboutToAppear(){
await FirstDialog.ChooseDialog(this.StepTips,this.name);
await this.onDeviceChange()
await this.getDevices()
}
onPageHide() {
AudioCapturer.releaseCapturer()
Logger.info(this.tag, `onPageHide releaseCapturer end`)
mediaPlay.release()
Logger.info(this.tag, `onPageHide releaseAVplayer end`)
}
async onDeviceChange(){
this.audioRoutingManager = await audio.getAudioManager().getRoutingManager()
this.audioRoutingManager.on('deviceChange', audio.DeviceFlag.ALL_DEVICES_FLAG, async(DeviceChangeAction) => {
Logger.info(this.tag, `deviceChange: ` + JSON.stringify(DeviceChangeAction))
await this.getDevices()
})
}
async getDevices(){
try{
Logger.info(this.tag, `getDevices test `)
let deviceDescriptors = await this.audioRoutingManager.getDevices(audio.DeviceFlag.INPUT_DEVICES_FLAG)
Logger.info(this.tag, `getDevices: ` + JSON.stringify(deviceDescriptors))
switch (deviceDescriptors[0].deviceType) {
case 3:
this.inputDevice = "3.5mm有线耳机"
break
case 8:
this.inputDevice = "蓝牙耳机"
break
case 15:
this.inputDevice = "mic"
break
case 22:
this.inputDevice = "Type C"
break
default:
break
}
Logger.info(this.tag, `InputDeviceList: ${this.inputDevice}`)
}catch(err){
Logger.info(this.tag, `getDevices err message: ${err.message}, err code: ${err.code} `)
}
}
build() {
Column() {
Row() {
Button(){
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({left:'20vp'})
}.backgroundColor(Color.Black)
.onClick(()=>{
router.back({
url:'pages/Audio/Audio_index',
params: {result : 'None',}
})
})
Text(this.name).fontColor(Color.White).fontSize('18fp').margin({left:'-20vp'})
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
Column() {
Flex({direction:FlexDirection.Column,alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceBetween }) {
Column(){
Row(){
Text(`是否设备支持TypeC耳机?`).fontColor(Color.White).fontSize('18fp')
}
Row(){
Column(){
Button(`No`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(!this.yesEnable)
.opacity(!this.yesEnable? 1 : 0.4)
.onClick(async () => {
this.Vue = true
})
}
Column(){
Button(`Yes`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.onClick(async () => {
this.yesEnable = true
this.recorderEnable = true
})
}
}
Row(){
Text('测试目的:\n当设备连接TypeC耳机时,是否音频输入路由正确切换\n测试准备\n断连任何外设,保持设备常亮\n测试步骤:\n1. 验证设备是否支持TypeC耳机\n2. 按下RECORD按钮\n3. 连接TypeC耳机\n4. 对着耳机mic讲话\n5. 按下STOP按钮\n6. 按下PLAY按钮听录制音频正常播放\n测试标准:\n如果设备不支持TypeC耳机输入或者接收到输入路由通知、路由显示为TypeC耳机,通过TypeC可正常录制和播放,则用例pass').fontColor(Color.White).fontSize('18fp')
}
Row(){
Text(`Audio输入路由:${this.inputDevice}`).fontColor(Color.White).fontSize('18fp')
}
Row(){
Column(){
Button(`RECORD`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(this.recorderEnable)
.opacity(this.recorderEnable ? 1 : 0.4)
.onClick(async () => {
this.stopEnable = true
this.recorderEnable = false
await AudioCapturer.createAudioCapturer()
await AudioCapturer.startCapturer()
})
}
Column(){
Button(`STOP`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(this.stopEnable)
.opacity(this.stopEnable ? 1 : 0.4)
.onClick(async () => {
this.recorderEnable = true
this.stopEnable = false
this.playEnable = true
await AudioCapturer.stopCapturer()
await AudioCapturer.releaseCapturer()
})
}
Column(){
Button(`PLAY`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(this.playEnable)
.opacity(this.playEnable ? 1 : 0.4)
.onClick(async () => {
this.playEnable = false
await mediaPlay.init()
this.Vue = true
})
}
}
}
}
}.width('100%').height('80%').backgroundColor(Color.Black)
.justifyContent(FlexAlign.SpaceEvenly)
CustomContainer({
title: this.name,
Url:'pages/Audio/Audio_index',
StepTips:this.StepTips,
name:$name,
Vue: $Vue,
}).height('10%').width('100%')
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
validator/acts_validator/src/main/ets/pages/Audio/AudioInputRoutingWiredHeadset.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CustomContainer} from '../common/AudioContainer';
import FirstDialog from '../model/FirstDialog';
import AudioCapturer from '../model/AudioCapturer'
import Logger from '../model/Logger'
import prompt from '@ohos.prompt';
import audio from '@ohos.multimedia.audio'
import router from '@ohos.router';
import mediaPlay from '../model/mediaPlay'
@Entry
@Component
struct audioInputRouting {
@State name: string = 'AudioInputRoutingTest(WiredHeadset)';
@State StepTips: string = '请参考提示信息依次执行如下操作';
@State Vue: boolean = false;
private tag: string = 'qlw'
@State deviceChange: audio.DeviceChangeAction = undefined
@State audioRoutingManager: audio.AudioRoutingManager = undefined
@State yesEnable: boolean = false
@State recorderEnable: boolean = false
@State stopEnable: boolean = false
@State playEnable: boolean = false
@State inputDevice: string = ''
async aboutToAppear(){
await FirstDialog.ChooseDialog(this.StepTips,this.name);
await this.onDeviceChange()
await this.getDevices()
}
onPageHide() {
AudioCapturer.releaseCapturer()
Logger.info(this.tag, `onPageHide releaseCapturer end`)
mediaPlay.release()
Logger.info(this.tag, `onPageHide releaseAVplayer end`)
}
async onDeviceChange(){
this.audioRoutingManager = await audio.getAudioManager().getRoutingManager()
this.audioRoutingManager.on('deviceChange', audio.DeviceFlag.ALL_DEVICES_FLAG, async(DeviceChangeAction) => {
Logger.info(this.tag, `deviceChange: ` + JSON.stringify(DeviceChangeAction))
await this.getDevices()
})
}
async getDevices(){
try{
Logger.info(this.tag, `getDevices test `)
let deviceDescriptors = await this.audioRoutingManager.getDevices(audio.DeviceFlag.INPUT_DEVICES_FLAG)
Logger.info(this.tag, `getDevices: ` + JSON.stringify(deviceDescriptors))
switch (deviceDescriptors[0].deviceType) {
case 3:
this.inputDevice = "3.5mm有线耳机"
break
case 8:
this.inputDevice = "蓝牙耳机"
break
case 15:
this.inputDevice = "mic"
break
case 22:
this.inputDevice = "Type C"
break
default:
break
}
Logger.info(this.tag, `InputDeviceList: ${this.inputDevice}`)
}catch(err){
Logger.info(this.tag, `getDevices err message: ${err.message}, err code: ${err.code} `)
}
}
build() {
Column() {
Row() {
Button(){
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({left:'20vp'})
}.backgroundColor(Color.Black)
.onClick(()=>{
router.back({
url:'pages/Audio/Audio_index',
params: {result : 'None',}
})
})
Text(this.name).fontColor(Color.White).fontSize('18fp').margin({left:'-20vp'})
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
Column() {
Flex({direction:FlexDirection.Column,alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceBetween }) {
Column(){
Row(){
Text(`是否设备支持3.5mm耳机?`).fontColor(Color.White).fontSize('18fp')
}
Row(){
Column(){
Button(`No`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(!this.yesEnable)
.opacity(!this.yesEnable? 1 : 0.4)
.onClick(async () => {
this.Vue = true
})
}
Column(){
Button(`Yes`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.onClick(async () => {
this.yesEnable = true
this.recorderEnable = true
})
}
}
Row(){
Text('测试目的:\n当设备连接3.5mm有线耳机时,是否音频输入路由正确切换\n测试准备\n断连任何外设,保持设备常亮\n测试步骤:\n1. 验证设备是否支持3.5mm有线耳机\n2. 按下RECORD按钮\n3. 连接3.5mm有线耳机\n4. 对着耳机mic讲话\n5. 按下STOP按钮\n6. 按下PLAY按钮听录制音频正常播放\n测试标准:\n如果设备不支持3.5mm有线耳机输入或者接收到路由通知、路由显示为3.5mm耳机,通过3.5mm耳机可正常录制和播放,则用例pass').fontColor(Color.White).fontSize('18fp')
}
Row(){
Text(`Audio输入路由:${this.inputDevice}`).fontColor(Color.White).fontSize('18fp')
}
Row(){
Column(){
Button(`RECORD`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(this.recorderEnable)
.opacity(this.recorderEnable ? 1 : 0.4)
.onClick(async () => {
this.stopEnable = true
this.recorderEnable = false
await AudioCapturer.createAudioCapturer()
await AudioCapturer.startCapturer()
})
}
Column(){
Button(`STOP`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(this.stopEnable)
.opacity(this.stopEnable ? 1 : 0.4)
.onClick(async () => {
this.recorderEnable = true
this.stopEnable = false
this.playEnable = true
await AudioCapturer.stopCapturer()
await AudioCapturer.releaseCapturer()
})
}
Column(){
Button(`PLAY`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(this.playEnable)
.opacity(this.playEnable ? 1 : 0.4)
.onClick(async () => {
this.playEnable = false
await mediaPlay.init()
this.Vue = true
})
}
}
}
}
}.width('100%').height('80%').backgroundColor(Color.Black)
.justifyContent(FlexAlign.SpaceEvenly)
CustomContainer({
title: this.name,
Url:'pages/Audio/Audio_index',
StepTips:this.StepTips,
name:$name,
Vue: $Vue,
}).height('10%').width('100%')
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
validator/acts_validator/src/main/ets/pages/Audio/AudioOutputRoutingBT.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CustomContainer} from '../common/AudioContainer';
import FirstDialog from '../model/FirstDialog';
import AudioRenderer from '../model/AudioRenderer'
import Logger from '../model/Logger'
import prompt from '@ohos.prompt';
import audio from '@ohos.multimedia.audio'
import router from '@ohos.router';
@Entry
@Component
struct audioOutputRouting {
@State name: string = 'AudioOutputRoutingTest(BT)';
@State StepTips: string = '请参考提示信息依次执行如下操作';
@State Vue: boolean = false;
private tag: string = 'qlw'
@State audioRoutingManager: audio.AudioRoutingManager = undefined
@State yesEnable: boolean = false
@State playEnable: boolean = false
@State stopEnable: boolean = false
@State outputDevice: string = ''
async aboutToAppear(){
await FirstDialog.ChooseDialog(this.StepTips,this.name);
await this.onDeviceChange()
await this.getDevices()
}
onPageHide() {
AudioRenderer.releaseRenderer()
Logger.info(this.tag, `onPageHide releaseRenderer end`)
}
async onDeviceChange(){
this.audioRoutingManager = await audio.getAudioManager().getRoutingManager()
this.audioRoutingManager.on('deviceChange', audio.DeviceFlag.ALL_DEVICES_FLAG, async(DeviceChangeAction) => {
Logger.info(this.tag, `deviceChange: ` + JSON.stringify(DeviceChangeAction))
await this.getDevices()
})
}
async getDevices(){
let deviceDescriptors = await this.audioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG)
Logger.info(this.tag, `getDevices: ` + JSON.stringify(deviceDescriptors))
switch (deviceDescriptors[0].deviceType) {
case 2:
this.outputDevice = "Speaker"
break
case 3:
this.outputDevice = "3.5mm有线耳机"
break
case 8:
this.outputDevice = "蓝牙耳机"
break
case 22:
this.outputDevice = "Type C耳机"
break
default:
break
}
Logger.info(this.tag, `OutputDeviceList: ${this.outputDevice}`)
}
build() {
Column() {
Row() {
Button(){
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({left:'20vp'})
}.backgroundColor(Color.Black)
.onClick(()=>{
router.back({
url:'pages/Audio/Audio_index',
params: {result : 'None',}
})
})
Text(this.name).fontColor(Color.White).fontSize('18fp').margin({left:'-20vp'})
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
Column() {
Flex({direction:FlexDirection.Column,alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) {
Column(){
Row(){
Text(`是否设备支持蓝牙耳机?`).fontColor(Color.White).fontSize('18fp')
}
Row(){
Column(){
Button(`No`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(!this.yesEnable)
.opacity(!this.yesEnable? 1 : 0.4)
.onClick(async () => {
this.Vue = true
})
}
Column(){
Button(`Yes`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.onClick(async () => {
this.yesEnable = true
this.playEnable = true
})
}
}
Row(){
Text('测试目的:\n当设备连接蓝牙耳机时,音频路由是否正确切换\n测试准备:\n断连任何外设,保持设备常亮\n测试步骤:\n1. 验证设备是否支持蓝牙外设\n2. 按下PLAY按钮\n3. 连接蓝牙耳机\n4. 拔出蓝牙耳机\n5. 按下STOP按钮\n测试标准:\n如果设备不支持蓝牙耳机连接或者插拔蓝牙耳机后接收到路由通知、路由显示正确,且连接蓝牙后音频通过蓝牙耳机播放,则用例pass').fontColor(Color.White).fontSize('18fp')
}
Row(){
Text(`Audio输出路由:${this.outputDevice}`).fontColor(Color.White).fontSize('18fp')
}
Row(){
Column(){
Button(`PLAY`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(this.playEnable)
.opacity(this.playEnable? 1 : 0.4)
.onClick(async () => {
this.Vue = true
this.stopEnable = true
this.playEnable = false
await AudioRenderer.createAudioRenderer()
await AudioRenderer.startRenderer()
})
}
Column(){
Button(`STOP`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(this.stopEnable)
.opacity(this.stopEnable? 1 : 0.4)
.onClick(async () => {
await AudioRenderer.stopRenderer()
await AudioRenderer.releaseRenderer()
this.playEnable = true
this.stopEnable = false
})
}
}
}
}
}.width('100%').height('80%').backgroundColor(Color.Black)
.justifyContent(FlexAlign.SpaceEvenly)
CustomContainer({
title: this.name,
Url:'pages/Audio/Audio_index',
StepTips:this.StepTips,
name:$name,
Vue: $Vue,
}).height('10%').width('100%')
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
validator/acts_validator/src/main/ets/pages/Audio/AudioOutputRoutingTypeC.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CustomContainer} from '../common/AudioContainer';
import FirstDialog from '../model/FirstDialog';
import AudioRenderer from '../model/AudioRenderer'
import Logger from '../model/Logger'
import prompt from '@ohos.prompt';
import audio from '@ohos.multimedia.audio'
import router from '@ohos.router';
@Entry
@Component
struct audioOutputRouting {
@State name: string = 'AudioOutputRoutingTest(TypeC)';
@State StepTips: string = '请参考提示信息依次执行如下操作';
@State Vue: boolean = false;
private tag: string = 'qlw'
@State audioRoutingManager: audio.AudioRoutingManager = undefined
@State yesEnable: boolean = false
@State playEnable: boolean = false
@State stopEnable: boolean = false
@State outputDevice: string = ''
async aboutToAppear(){
await FirstDialog.ChooseDialog(this.StepTips,this.name);
await this.onDeviceChange()
await this.getDevices()
}
onPageHide() {
AudioRenderer.releaseRenderer()
Logger.info(this.tag, `onPageHide releaseRenderer end`)
}
async onDeviceChange(){
this.audioRoutingManager = await audio.getAudioManager().getRoutingManager()
this.audioRoutingManager.on('deviceChange', audio.DeviceFlag.OUTPUT_DEVICES_FLAG, async(DeviceChangeAction) => {
Logger.info(this.tag, `deviceChange: ` + JSON.stringify(DeviceChangeAction))
await this.getDevices()
})
}
async getDevices(){
let deviceDescriptors = await this.audioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG)
Logger.info(this.tag, `getDevices: ` + JSON.stringify(deviceDescriptors))
switch (deviceDescriptors[0].deviceType) {
case 2:
this.outputDevice = "Speaker"
break
case 3:
this.outputDevice = "3.5mm有线耳机"
break
case 8:
this.outputDevice = "蓝牙耳机"
break
case 22:
this.outputDevice = "Type C耳机"
break
default:
break
}
Logger.info(this.tag, `OutputDeviceList: ${this.outputDevice}`)
}
build() {
Column() {
Row() {
Button(){
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({left:'20vp'})
}.backgroundColor(Color.Black)
.onClick(()=>{
router.back({
url:'pages/Audio/Audio_index',
params: {result : 'None',}
})
})
Text(this.name).fontColor(Color.White).fontSize('18fp').margin({left:'-20vp'})
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
Column() {
Flex({direction:FlexDirection.Column,alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) {
Column(){
Row(){
Text(`是否设备支持TypeC耳机?`).fontColor(Color.White).fontSize('18fp')
}
Row(){
Column(){
Button(`No`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(!this.yesEnable)
.opacity(!this.yesEnable? 1 : 0.4)
.onClick(async () => {
this.Vue = true
})
}
Column(){
Button(`Yes`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.onClick(async () => {
this.yesEnable = true
this.playEnable = true
})
}
}
Row(){
Text('测试目的:\n当设备连接TypeC耳机时,音频路由是否正确切换\n测试准备:\n断连任何外设,保持设备常亮\n测试步骤:\n1. 验证设备是否支持TypeC外设\n2. 按下PLAY按钮\n3. 连接TypeC耳机\n4. 拔出TypeC耳机\n5. 按下STOP按钮\n测试标准:\n如果设备不支持TypeC耳机连接或者插拔TypeC耳机后接收到路由通知、路由显示正确,且连接TypeC后音频通过TypeC耳机播放,则用例pass').fontColor(Color.White).fontSize('18fp')
}
Row(){
Text(`Audio输出路由:${this.outputDevice}`).fontColor(Color.White).fontSize('18fp')
}
Row(){
Column(){
Button(`PLAY`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(this.playEnable)
.opacity(this.playEnable? 1 : 0.4)
.onClick(async () => {
this.Vue = true
this.stopEnable = true
this.playEnable = false
await AudioRenderer.createAudioRenderer()
await AudioRenderer.startRenderer()
})
}
Column(){
Button(`STOP`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(this.stopEnable)
.opacity(this.stopEnable? 1 : 0.4)
.onClick(async () => {
await AudioRenderer.stopRenderer()
await AudioRenderer.releaseRenderer()
this.playEnable = true
this.stopEnable = false
})
}
}
}
}
}.width('100%').height('80%').backgroundColor(Color.Black)
.justifyContent(FlexAlign.SpaceEvenly)
CustomContainer({
title: this.name,
Url:'pages/Audio/Audio_index',
StepTips:this.StepTips,
name:$name,
Vue: $Vue,
}).height('10%').width('100%')
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
validator/acts_validator/src/main/ets/pages/Audio/AudioOutputRoutingWiredHeadset.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CustomContainer} from '../common/AudioContainer';
import FirstDialog from '../model/FirstDialog';
import AudioRenderer from '../model/AudioRenderer'
import Logger from '../model/Logger'
import prompt from '@ohos.prompt';
import audio from '@ohos.multimedia.audio'
import router from '@ohos.router';
@Entry
@Component
struct audioOutputRouting {
@State name: string = 'AudioOutputRoutingTest(WiredHeadset)';
@State StepTips: string = '请参考提示信息依次执行如下操作';
@State Vue: boolean = false;
private tag: string = 'qlw'
@State audioRoutingManager: audio.AudioRoutingManager = undefined
@State yesEnable: boolean = false
@State playEnable: boolean = false
@State stopEnable: boolean = false
@State outputDevice: string = ''
async aboutToAppear(){
await FirstDialog.ChooseDialog(this.StepTips,this.name);
await this.onDeviceChange()
await this.getDevices()
}
onPageHide() {
AudioRenderer.releaseRenderer()
Logger.info(this.tag, `onPageHide releaseRenderer end`)
}
async onDeviceChange(){
this.audioRoutingManager = await audio.getAudioManager().getRoutingManager()
this.audioRoutingManager.on('deviceChange', audio.DeviceFlag.INPUT_DEVICES_FLAG, async(DeviceChangeAction) => {
Logger.info(this.tag, `deviceChange: ` + JSON.stringify(DeviceChangeAction))
await this.getDevices()
})
}
async getDevices(){
let deviceDescriptors = await this.audioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG)
Logger.info(this.tag, `getDevices: ` + JSON.stringify(deviceDescriptors))
switch (deviceDescriptors[0].deviceType) {
case 2:
this.outputDevice = "Speaker"
break
case 3:
this.outputDevice = "3.5mm有线耳机"
break
case 8:
this.outputDevice = "蓝牙耳机"
break
case 22:
this.outputDevice = "Type C耳机"
break
default:
break
}
Logger.info(this.tag, `OutputDeviceList: ${this.outputDevice}`)
}
build() {
Column() {
Row() {
Button(){
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({left:'20vp'})
}.backgroundColor(Color.Black)
.onClick(()=>{
router.back({
url:'pages/Audio/Audio_index',
params: {result : 'None',}
})
})
Text(this.name).fontColor(Color.White).fontSize('18fp').margin({left:'-20vp'})
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
Column() {
Flex({direction:FlexDirection.Column,alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) {
Column(){
Row(){
Text(`是否设备支持3.5mm有线耳机?`).fontColor(Color.White).fontSize('18fp')
}
Row(){
Column(){
Button(`No`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(!this.yesEnable)
.opacity(!this.yesEnable? 1 : 0.4)
.onClick(async () => {
this.Vue = true
})
}
Column(){
Button(`Yes`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.onClick(async () => {
this.yesEnable = true
this.playEnable = true
})
}
}
Row(){
Text('测试目的:\n当设备连接3.5mm有线耳机时,音频路由是否正确切换\n测试准备:\n断连任何外设,保持设备常亮\n测试步骤:\n1. 验证设备是否支持外设\n2. 按下PLAY按钮\n3. 连接3.5mm有线耳机\n4. 拔出3.5mm有线耳机\n5. 按下STOP按钮\n测试标准:\n如果设备不支持有线耳机输入或者插入和拔出有线耳机后接收到路由通知,路由显示正确,且连接外设后音频通过外设播放,则用例pass').fontColor(Color.White).fontSize('18fp')
}
Row(){
Text(`Audio输出路由:${this.outputDevice}`).fontColor(Color.White).fontSize('18fp')
}
Row(){
Column(){
Button(`PLAY`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(this.playEnable)
.opacity(this.playEnable? 1 : 0.4)
.onClick(async () => {
this.Vue = true
this.stopEnable = true
this.playEnable = false
await AudioRenderer.createAudioRenderer()
await AudioRenderer.startRenderer()
})
}
Column(){
Button(`STOP`)
.borderRadius(8)
.backgroundColor(0x317aff)
.width('30%')
.enabled(this.stopEnable)
.opacity(this.stopEnable? 1 : 0.4)
.onClick(async () => {
await AudioRenderer.stopRenderer()
await AudioRenderer.releaseRenderer()
this.playEnable = true
this.stopEnable = false
})
}
}
}
}
}.width('100%').height('80%').backgroundColor(Color.Black)
.justifyContent(FlexAlign.SpaceEvenly)
CustomContainer({
title: this.name,
Url:'pages/Audio/Audio_index',
StepTips:this.StepTips,
name:$name,
Vue: $Vue,
}).height('10%').width('100%')
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
validator/acts_validator/src/main/ets/pages/Audio/Audio_index.ets
浏览文件 @
8ea871d1
...
...
@@ -39,7 +39,11 @@ struct IndexPage {
@State result : string = '';
@State TEST : number = 0;
private TestCaseList = [
{title:'ScrollingList',uri:'pages/Audio/ScrollListTest'},
{title:'AudioInputRoutingTest(WiredHeadset)',uri:'pages/Audio/AudioInputRoutingWiredHeadset'},
{title:'AudioInputRoutingTest(TypeC)',uri:'pages/Audio/AudioInputRoutingTypeC'},
{title:'AudioOutputRoutingTest(WiredHeadset)',uri:'pages/Audio/AudioOutputRoutingWiredHeadset'},
{title:'AudioOutputRoutingTest(TypeC)',uri:'pages/Audio/AudioOutputRoutingTypeC'},
{title:'AudioOutputRoutingTest(BT)',uri:'pages/Audio/AudioOutputRoutingBT'},
]
@State ColorObject : string[] = VarColor;
async onPageShow(){
...
...
validator/acts_validator/src/main/ets/pages/Camera/CameraFlash.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// @ts-nocheck
// @ts-ignore
import camera from '@ohos.multimedia.camera'
import Logger from '../model/Logger'
import CameraService from '../model/CameraService'
import { CustomContainer } from '../common/CameraFlashContainer';
import FirstDialog from '../model/FirstDialog';
import router from '@ohos.router';
@Entry
@Component
struct cameraOrientation {
@State FillColor: string = '#FF000000';
@State name: string = 'CameraFlash';
@State StepTips: string = '测试目的:用于测试相机闪光灯能力\n-确定是否有闪光灯\n-根据设备选择选项\n-点击开启关闭对闪光灯进行操作' + '\n' + '预期结果:操作后闪关灯表现一致';
private tag: string = 'qlw CameraFlash'
@State Vue: boolean = false
@State isFlash: boolean = undefined
private mXComponentController: XComponentController = new XComponentController()
@State captureSession: camera.CaptureSession = undefined
@State flashChange: boolean = false
async aboutToAppear() {
await FirstDialog.ChooseDialog(this.StepTips, this.name)
this.cameraIsFlash()
}
cameraInit() {
// @ts-ignore
this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
CameraService.initCamera(this.surfaceId, 0).then(() => {
this.captureSession = CameraService.captureSession
this.isFlash = this.captureSession.hasFlash()
Logger.info(this.tag, `onLoad isFlash: ${this.isFlash}`)
})
}
openFlash() {
this.flashChange = !this.flashChange
if (this.isFlash) {
// 设置当前设备的闪光灯模式
this.captureSession.setFlashMode(this.flashChange ? camera.FlashMode.FLASH_MODE_ALWAYS_OPEN : camera.FlashMode.FLASH_MODE_CLOSE)
if (!this.flashChange){
this.Vue = true
}
Logger.info(this.tag, `setFlashMode success`)
// 获取当前设备的闪光灯模式
let flashMode = this.captureSession.getFlashMode()
Logger.info(this.tag, `getFlashMode success: ${flashMode}`)
}
}
onPageShow() {
this.cameraInit()
}
onPageHide() {
CameraService.releaseCamera()
Logger.info(this.tag, `onPageHide releaseCamera end`)
}
build() {
Column() {
Row() {
Button() {
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({ left: '20vp' })
}.backgroundColor(Color.Black)
.onClick(() => {
router.back({
url: 'pages/Camera/Camera_index',
params: { result: 'None', }
})
})
Text(this.name).fontColor(Color.White).fontSize('18fp').margin({ left: '-20vp' })
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
Stack() {
XComponent({
id: 'componentId',
type: 'surface',
controller: this.mXComponentController
})
.onLoad(async () => {
Logger.info(this.tag, 'onLoad is called')
this.cameraInit()
})
Row().backgroundColor(Color.Black).size({ width: '100%', height: '100%' })
}.size({ width: '10%', height: '30%' })
Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start, direction: FlexDirection.Column }) {
// Text(`提示:` + this.isFlash).fontSize('16fp').fontColor(Color.White)
Text(`提示:如果设备存在闪光灯,选择开启,否则选择无闪光灯`)
.fontSize('16fp').fontColor(Color.White).margin('20fp')
Row() {
Button(this.flashChange ? '关闭' : '开启').onClick(() => {
this.openFlash()
})
Button('无闪光灯').onClick(() => {
this.Vue = true
})
}.justifyContent(FlexAlign.SpaceEvenly).width('100%').margin('20fp')
}.width('80%').height('50%')
CustomContainer({
title: this.name,
Url: 'pages/Camera/Camera_index',
StepTips: this.StepTips,
FillColor: $FillColor,
name: $name,
Vue: $Vue,
isFlash:$isFlash
}).height('10%').width('100%')
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
\ No newline at end of file
validator/acts_validator/src/main/ets/pages/Camera/CameraFormat.ets
已删除
100644 → 0
浏览文件 @
1a33fb29
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import camera from '@ohos.multimedia.camera'
import Logger from '../model/Logger'
import CameraService from '../model/CameraService'
import {CustomContainer} from '../common/CameraOrientation';
import FirstDialog from '../model/FirstDialog';
const CameraMode = {
MODE_PHOTO: 0, // 拍照模式
MODE_VIDEO: 1 // 录像模式
}
@Entry
@Component
struct SetCircle {
@State FillColor: string = '#FF000000';
@State name: string = 'CameraFormat';
@State StepTips: string = '测试目的:用于测试相机预览和拍照旋转能力\n-左侧显示给定旋转角度后的预览窗口\n-右侧显示拍照后的图片\n-对于前置摄像头会有镜像效果'+'\n'+'预期结果:拍照图片与预览窗口的画面一致';
private tag: string = 'qlw'
private mXComponentController: XComponentController = new XComponentController()
@State surfaceId: number = 0;
private x: number = 0;
@State curModel: number = CameraMode.MODE_PHOTO
@State cameraDeviceIndex: number = 0
@State imageRotationValue: number = camera.ImageRotation.ROTATION_90
@State qualityLevelValue: number = camera.QualityLevel.QUALITY_LEVEL_LOW
@State photoUri: string = undefined
@State Vue: boolean = false
async aboutToAppear(){
await FirstDialog.ChooseDialog(this.StepTips,this.name);
}
handleTakePicture = (photoUri: string) => {
this.photoUri = photoUri
Logger.info(this.tag, `takePicture end, photoUri: ${this.photoUri}`)
}
@Builder specificNoParam() {
Column() {
}
}
build() {
Column() {
CustomContainer({
title: this.name,
Url:'pages/Camera/Camera_index',
StepTips:this.StepTips,
content: this.specificNoParam,
FillColor:$FillColor,
name: $name,
Vue: $Vue
}).height('30%').width('100%')
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) {
XComponent({
id: 'componentId',
type: 'surface',
controller: this.mXComponentController
})
.onLoad(async () => {
Logger.info(this.tag, 'onLoad is called')
// @ts-ignore
this.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: 10, surfaceHeight: 10 })
// @ts-ignore
this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
Logger.info(this.tag, `onLoad surfaceId: ${this.surfaceId}`)
this.curModel = CameraMode.MODE_PHOTO
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex)
})
.height('40%')
.width('40%')
Text('Camera Preview').fontSize('20fp')
Text('Camera').fontSize(20)
// Select(qualityLevel)
// .selected(2)
// .value('请选择')
// .font({ size: 20, weight: 20, family: 'serif', style: FontStyle.Normal })
// .selectedOptionFont({ size: 20, weight: 20, family: 'serif', style: FontStyle.Normal })
// .optionFont({ size: 20, weight: 40, family: 'serif', style: FontStyle.Normal })
// .onSelect((index: number, value: string) => {
// console.info("Select:" + index)
// console.info("Select qualityLevelValue:" + value)
// this.qualityLevelValue = Number(value)
// })
Button('NEXT', {
type: ButtonType.Normal,
stateEffect: true
}).borderRadius(8).backgroundColor(0x317aff).width('20%').onClick(() => {
CameraService.takePicture(this.imageRotationValue, this.qualityLevelValue)
CameraService.setTakePictureCallback(this.handleTakePicture.bind(this))
this.Vue = true
})
}.width('100%').height('70%').backgroundColor(Color.White)
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
//@CustomDialog
//struct CustomDialogExample {
// @Link textValue: string
// @Link inputValue: string
// @Link qualityLevelValue: number
// @Link imageRotationValue: number
// @Link imageResolutionValue: string
// controller: CustomDialogController
// cancel: () => void
// confirm: () => void
//}
\ No newline at end of file
validator/acts_validator/src/main/ets/pages/Camera/CameraOrientation.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// @ts-ignore
import camera from '@ohos.multimedia.camera'
import Logger from '../model/Logger'
import CameraService from '../model/CameraService'
import { CustomContainer } from '../common/CameraOrientationContainer';
import FirstDialog from '../model/FirstDialog';
import router from '@ohos.router';
@Entry
@Component
struct cameraOrientation {
@State FillColor: string = '#FF000000';
@State name: string = 'CameraOrientation';
@State StepTips: string = '测试目的:用于测试相机预览和拍照旋转能力\n-左侧显示给定旋转角度后的预览窗口\n-右侧显示拍照后的图片\n-对于前置摄像头会有镜像效果' + '\n' + '预期结果:拍照图片与预览窗口的画面一致';
private tag: string = 'qlw CameraOrientation'
private mXComponentController: XComponentController = new XComponentController()
@State surfaceId: number = 0;
@State cameraDeviceIndex: number = 0
@State assetUri: string = undefined
@State Vue: boolean = false
@State imageRotation: number = 0
@State cameraListLength: number = undefined
@State cameraList: SelectOption[] = []
@State takeFlag: boolean = true
@State testingFrequency: number = undefined
@State isEnabled: boolean = true
@State takeSelect: number = 0
@State clickFrequency: number = 0
async aboutToAppear() {
await FirstDialog.ChooseDialog(this.StepTips, this.name);
CameraService.setTakePictureCallback(this.handleTakePicture.bind(this))
}
onChangeTake() {
if (this.takeFlag) {
CameraService.takePicture(this.imageRotation)
this.Vue = true
this.takeFlag = false
this.isEnabled = false
} else {
this.takeFlag = true
// next 刷新数据
// 图像置为黑色
this.assetUri = ''
this.imageRotation = this.imageRotation + 90
if (this.imageRotation > 270 && this.clickFrequency > 3) {
this.imageRotation = 0
this.cameraDeviceIndex = 1
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex)
}
}
}
cameraListFn() {
this.cameraListLength = CameraService.cameras.length
for (let index = 0; index < this.cameraListLength; index++) {
this.cameraList.push({
value: `Camera ${index}`
})
}
this.testingFrequency = this.cameraListLength * 4
}
handleTakePicture = (assetUri: string) => {
this.assetUri = assetUri
Logger.info(this.tag, `takePicture end, assetUri: ${this.assetUri}`)
}
onPageShow() {
Logger.info(this.tag, `takePicture end, assetUri`)
// @ts-ignore
this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex).then(() => {
this.cameraListFn()
})
}
onPageHide() {
CameraService.releaseCamera()
Logger.info(this.tag, `onPageHide releaseCamera end`)
}
build() {
Column() {
Row() {
Button() {
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({ left: '20vp' })
}.backgroundColor(Color.Black)
.onClick(() => {
router.back({
url: 'pages/Camera/Camera_index',
params: { result: 'None', }
})
})
Text(this.name).fontColor(Color.White).fontSize('18fp').margin({ left: '-20vp' })
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceAround }) {
Column() {
XComponent({
id: 'componentId',
type: 'surface',
controller: this.mXComponentController
})
.onLoad(async () => {
Logger.info(this.tag, 'onLoad is called')
// @ts-ignore
this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
Logger.info(this.tag, `onLoad surfaceId: ${this.surfaceId}`)
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex).then(() => {
this.cameraListFn()
})
})
.size({ width: '100%', height: '100%' })
Text('Camera Preview').fontSize('20fp').fontColor(Color.White)
}.size({ width: '40%', height: '60%' })
Column() {
Image(this.assetUri || '').size({ width: '100%', height: '100%' }).border({ width: 1 })
Text('Oriented Photo').fontSize('20fp').fontColor(Color.White)
}.size({ width: '40%', height: '60%' })
}.width('100%').height('50%')
Flex({ direction: FlexDirection.Column }) {
Text(`Camera: ${this.cameraDeviceIndex}`).fontSize('16fp').fontColor(Color.White)
Text(`Orientation: ${this.imageRotation}°`).fontSize('16fp').fontColor(Color.White)
Text(`顺时针`).fontSize('16fp').fontColor(Color.White)
Text(`提示:`).fontSize('16fp').fontColor(Color.White)
Text(`如果左边窗口旋转后与右边窗口相同,选择pass,否则选择fail`)
.fontSize('16fp').fontColor(Color.White)
}.size({ width: '80%', height: '25%' })
Button(this.takeFlag ? '拍照' : '下一个')
.enabled(this.isEnabled)
.opacity(this.isEnabled ? 1 : 0.4)
.width('50%')
.height('5%')
.backgroundColor(0x317aff)
.onClick(async () => {
this.onChangeTake()
})
CustomContainer({
title: this.name,
Url: 'pages/Camera/Camera_index',
StepTips: this.StepTips,
FillColor: $FillColor,
name: $name,
Vue: $Vue,
testingFrequency: this.testingFrequency,
isEnabled: $isEnabled,
clickFrequency: $clickFrequency
}).height('10%').width('100%')
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
\ No newline at end of file
validator/acts_validator/src/main/ets/pages/Camera/CameraPhotoFormat.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// @ts-ignore
import camera from '@ohos.multimedia.camera'
import Logger from '../model/Logger'
import CameraService from '../model/CameraService'
import { CustomContainer } from '../common/CameraPhotoContainer';
import FirstDialog from '../model/FirstDialog';
import router from '@ohos.router';
@Entry
@Component
struct cameraOrientation {
@State FillColor: string = '#FF000000';
@State name: string = 'CameraPhotoFormat';
@State StepTips: string = '测试目的:用于测试相机拍照分辨率能力\n预期结果:所有分辨率均可以拍照,图片与预览一致';
private tag: string = 'qlw'
private mXComponentController: XComponentController = new XComponentController()
@State surfaceId: number = 0;
@State cameraDeviceIndex: number = 0
@State assetUri: string = undefined
@State Vue: boolean = false
@State imageRotation: number = 0
@State cameraListLength: number = undefined
@State cameraList: SelectOption[] = []
@State isEnabled: boolean = true
@State isNextEnabled: boolean = true
@State takeSelect: number = 0
@State clickFrequency: number = 0
@State resolutionSelectVal: string = '' // 下拉框默认value
@State clickSerialPhotoVal: number = 0
@State timer: number = -1
@State resolution: SelectOption[] = [] // 分辨率
@State testingFrequency: number = undefined // 测试总数
@State isCameraChange: boolean = false
async aboutToAppear() {
await FirstDialog.ChooseDialog(this.StepTips, this.name);
CameraService.setTakePictureCallback(this.handleTakePicture.bind(this))
}
cameraListFn() {
this.cameraList = []
this.cameraListLength = CameraService.cameras.length
for (let index = 0; index < this.cameraListLength; index++) {
this.cameraList.push({ value: `Camera ${index}` })
}
// 测试总次数 = 摄像头0的分辨率 + 摄像头1的分辨率 优先以RK为主
this.testingFrequency = this.resolution.length
Logger.info(this.tag, `testingFrequency ${this.testingFrequency}`)
}
handleTakePicture = (assetUri: string) => {
this.assetUri = assetUri
Logger.info(this.tag, `takePicture end, assetUri: ${this.assetUri}`)
}
onPageShow() {
Logger.info(this.tag, `takePicture end, assetUri`)
// @ts-ignore
this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex).then(() => {
this.cameraListFn()
})
}
async cameraInit(obj?) {
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex, obj, this.clickFrequency).then(() => {
this.resolution = CameraService.previewSizeResolution
this.resolutionSelectVal = String(this.resolution[this.clickFrequency].value)
this.cameraListFn()
})
}
onPageHide() {
CameraService.releaseCamera()
Logger.info(this.tag, `onPageHide releaseCamera end`)
}
// 对分辨率数据处理 获取到需要的格式
dealWithResolutionFn(arr) {
let newResolution = []
arr.forEach((item) => {
let indexOf = item.value.indexOf("x")
let objW = Number(item.value.slice(0, indexOf))
let objH = Number(item.value.slice(indexOf + 1))
let obj = {
format: 2000,
size: {
"width": objW,
"height": objH
}
}
newResolution.push(obj)
})
return newResolution
}
build() {
Column() {
Row() {
Button() {
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({ left: '20vp' })
}.backgroundColor(Color.Black)
.onClick(() => {
router.back({
url: 'pages/Camera/Camera_index',
params: { result: 'None', }
})
})
Text(this.name).fontColor(Color.White).fontSize('18fp').margin({ left: '-20vp' })
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceAround }) {
Column() {
XComponent({
id: 'componentId',
type: 'surface',
controller: this.mXComponentController
})
.onLoad(async () => {
Logger.info(this.tag, 'onLoad is called')
// @ts-ignore
this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
Logger.info(this.tag, `onLoad surfaceId: ${this.surfaceId}`)
this.cameraInit()
})
.size({ width: '100%', height: '100%' })
Text('Camera Preview').fontSize('20fp').fontColor(Color.White)
}.size({ width: '40%', height: '60%' })
Column() {
Image(this.assetUri || '').size({ width: '100%', height: '100%' }).border({ width: 1 })
Text('Oriented Photo').fontSize('20fp').fontColor(Color.White)
}.size({ width: '40%', height: '60%' })
}.width('100%').height('50%')
Flex({ direction: FlexDirection.Column }) {
Row() {
Select(this.resolution)
.selected(this.clickFrequency)
.value(this.resolutionSelectVal)
.font({ size: 16, weight: 500 })
.fontColor(Color.White)
.selectedOptionBgColor(Color.Black)
.optionBgColor(Color.Black)
.selectedOptionFont({ size: 16, weight: 400 })
.optionFont({ size: 16, weight: 400 })
.onSelect((index: number, value) => {
let indexOf = value.indexOf('x')
let objW = Number(value.slice(0, indexOf))
let objH = Number(value.slice(indexOf + 1))
let obj = {
format: 2000,
size: {
"width": objW,
"height": objH
}
}
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex, obj)
Logger.info(this.tag, `onSelect Rotation index: ${index}, value: ${value}, obj: ${obj}`)
})
Select(this.cameraList)
.selected(this.cameraDeviceIndex)
.value(this.cameraDeviceIndex ? 'Camera 1' : 'Camera 0')
.font({ size: 16, weight: 500 })
.fontColor(Color.White)
.selectedOptionBgColor(Color.Black)
.optionBgColor(Color.Black)
.selectedOptionFont({ size: 16, weight: 400 })
.optionFont({ size: 16, weight: 400 })
.onSelect((index: number) => {
this.cameraDeviceIndex = index
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex).then(() => {
this.cameraListFn()
})
})
}.justifyContent(FlexAlign.SpaceEvenly)
Text(`提示:对不同分辨率的图片进行拍摄,根据拍摄结果选择pass或选择fail`)
.fontSize('16fp').fontColor(Color.White).margin({ top: 20 })
}.size({ width: '80%', height: '20%' })
Row() {
Button('拍照')
.enabled(this.isEnabled)
.opacity(this.isEnabled ? 1 : 0.4)
.width('40%')
.backgroundColor(0x317aff)
.onClick(async () => {
this.isEnabled = false
this.isNextEnabled = false
CameraService.takePicture()
})
Button('NEXT')
.enabled(!this.isNextEnabled)
.opacity(!this.isNextEnabled ? 1 : 0.4)
.width('40%')
.backgroundColor(0x317aff)
.onClick(async () => {
this.clickFrequency++
Logger.info(this.tag, `nextClickFn new clickFrequency: ${this.clickFrequency}`)
if (this.resolution.length == this.clickFrequency || this.resolution.length < this.clickFrequency){
if (this.isCameraChange){
this.Vue = true
this.isEnabled = false
this.isNextEnabled = true
return
}
this.cameraDeviceIndex = Number(!this.cameraDeviceIndex)
this.clickFrequency = 0
await this.cameraInit().then(() => {
this.isCameraChange = true
})
}
this.isEnabled = true
this.isNextEnabled = true
if (this.clickFrequency){
let newResolution = this.dealWithResolutionFn(this.resolution)
Logger.info(this.tag, `nextClickFn new Resolution: ${newResolution}`)
this.cameraInit(newResolution[this.clickFrequency])
this.resolutionSelectVal = String(this.resolution[this.clickFrequency].value)
}
})
}.width('100%').justifyContent(FlexAlign.SpaceEvenly)
.height('10%')
CustomContainer({
title: this.name,
Url: 'pages/Camera/Camera_index',
StepTips: this.StepTips,
FillColor: $FillColor,
name: $name,
Vue: $Vue
}).height('10%').width('100%')
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
\ No newline at end of file
validator/acts_validator/src/main/ets/pages/Camera/CameraPreviewFormat.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// @ts-ignore
import camera from '@ohos.multimedia.camera'
import Logger from '../model/Logger'
import CameraService from '../model/CameraService'
import { CustomContainer } from '../common/CameraPreviewFormatContainer';
import FirstDialog from '../model/FirstDialog';
import router from '@ohos.router';
@Entry
@Component
struct cameraFormat {
@State FillColor: string = '#FF000000';
@State name: string = 'CameraPreviewFormat';
@State StepTips: string = '测试目的:用于测试相机预览分辨率能力\n预期结果:所有分辨率均可以预览成功,预览画面正常';
private tag: string = 'qlw CameraFormat'
private mXComponentController: XComponentController = new XComponentController()
@State surfaceId: number = 0;
@State cameraDeviceIndex: number = 0
@State Vue: boolean = false
@State resolution: SelectOption[] = []
@State testingFrequency: number = undefined
@State clickFrequency: number = 0
@State cameraListLength: number = undefined
@State cameraList: SelectOption[] = []
@State resolutionSelectVal: string = ''
@State nextEnabled: boolean = true
@State formatVal: SelectOption[] = []
async aboutToAppear() {
await FirstDialog.ChooseDialog(this.StepTips, this.name);
Logger.info(this.tag, `the resolution: ${this.resolution}`)
}
onPageHide() {
CameraService.releaseCamera()
Logger.info(this.tag, `onPageHide releaseCamera end`)
}
cameraListFn() {
this.cameraList = []
this.cameraListLength = CameraService.cameras.length
for (let index = 0; index < this.cameraListLength; index++) {
this.cameraList.push({ value: `Camera ${index}` })
}
// 测试总次数 = 摄像头0的分辨率 + 摄像头1的分辨率 优先以RK为主
this.testingFrequency = this.resolution.length
Logger.info(this.tag, `testingFrequency ${this.testingFrequency}`)
}
async cameraInit(obj?) {
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex, obj).then(() => {
this.resolution = CameraService.resolution
this.resolutionSelectVal = String(this.resolution[this.clickFrequency].value)
this.cameraListFn()
})
}
onPageShow() {
Logger.info(this.tag, `takePicture end, assetUri`)
// @ts-ignore
this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex).then(() => {
this.cameraListFn()
})
}
nextClickFn() {
// 切换next 次数增加 分辨率遍历 分辨率遍历完 切换摄像头 再次遍历分辨率 调取初始化相机进行改变
this.clickFrequency++
if (this.clickFrequency === this.testingFrequency) {
this.Vue = true
this.nextEnabled = false
return
}
let newResolution = this.dealWithResolutionFn(this.resolution)
Logger.info(this.tag, `nextClickFn new Resolution: ${newResolution}`)
this.cameraInit(newResolution[this.clickFrequency])
this.resolutionSelectVal = String(this.resolution[this.clickFrequency].value)
}
// 对分辨率数据处理 获取到需要的格式
dealWithResolutionFn(arr) {
let newResolution = []
arr.forEach((item) => {
let indexOf = item.value.indexOf("x")
let objW = Number(item.value.slice(0, indexOf))
let objH = Number(item.value.slice(indexOf + 1))
let obj = {
format: 1003,
size: {
"width": objW,
"height": objH
}
}
newResolution.push(obj)
})
return newResolution
}
build() {
Column() {
Row() {
Button() {
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({ left: '20vp' })
}.backgroundColor(Color.Black)
.onClick(() => {
router.back({
url: 'pages/Camera/Camera_index',
params: { result: 'None', }
})
})
Text(this.name).fontColor(Color.White).fontSize('18fp').margin({ left: '-20vp' })
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceAround, direction: FlexDirection.Column }) {
Column() {
XComponent({
id: 'componentId',
type: 'surface',
controller: this.mXComponentController
})
.onLoad(async () => {
Logger.info(this.tag, 'onLoad is called')
// @ts-ignore
this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
Logger.info(this.tag, `onLoad surfaceId: ${this.surfaceId}`)
this.cameraInit()
})
.size({ width: '100%', height: '100%' })
Text('Camera Preview').fontSize('20fp').fontColor(Color.White)
}.size({ width: '80%', height: '70%' })
Column() {
Row() {
Select(this.resolution)
.selected(this.clickFrequency)
.value(this.resolutionSelectVal)
.font({ size: 16, weight: 500 })
.fontColor(Color.White)
.selectedOptionBgColor(Color.Black)
.optionBgColor(Color.Black)
.selectedOptionFont({ size: 16, weight: 400 })
.optionFont({ size: 16, weight: 400 })
.onSelect((index: number, value) => {
let indexOf = value.indexOf('x')
let objW = Number(value.slice(0, indexOf))
let objH = Number(value.slice(indexOf + 1))
let obj = {
format: 1003,
size: {
"width": objW,
"height": objH
}
}
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex, obj)
Logger.info(this.tag, `onSelect Rotation index: ${index}, value: ${value}, obj: ${obj}`)
})
Select(this.cameraList)
.selected(this.cameraDeviceIndex)
.value(this.cameraDeviceIndex ? 'Camera 1' : 'Camera 0')
.font({ size: 16, weight: 500 })
.fontColor(Color.White)
.selectedOptionBgColor(Color.Black)
.optionBgColor(Color.Black)
.selectedOptionFont({ size: 16, weight: 400 })
.optionFont({ size: 16, weight: 400 })
.onSelect((index: number) => {
this.cameraDeviceIndex = index
this.cameraInit()
})
}.size({ width: '100%', height: '50%' }).justifyContent(FlexAlign.SpaceEvenly)
Row() {
Select([{ value: 'YUV' }])
.selected(0)
.value('YUV')
.font({ size: 16, weight: 500 })
.fontColor(Color.White)
.selectedOptionBgColor(Color.Black)
.optionBgColor(Color.Black)
.selectedOptionFont({ size: 16, weight: 400 })
.optionFont({ size: 16, weight: 400 })
.onSelect((index: number, value) => {
Logger.info(this.tag, `onSelect format index: ${index}, value: ${value}`)
})
Button('NEXT')
.borderRadius(8)
.backgroundColor(0x317aff)
.enabled(this.nextEnabled)
.opacity(this.nextEnabled ? 1 : 0.4)
.width('20%')
.onClick(async () => {
this.nextClickFn()
})
}.size({ width: '100%', height: '50%' }).justifyContent(FlexAlign.SpaceEvenly)
}.size({ width: '100%', height: '20%' })
}.height('80%').width('100%')
CustomContainer({
title: this.name,
Url: 'pages/Camera/Camera_index',
StepTips: this.StepTips,
FillColor: $FillColor,
name: $name,
Vue: $Vue,
}).height('10%').width('100%')
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
\ No newline at end of file
validator/acts_validator/src/main/ets/pages/Camera/CameraSerialPhoto.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// @ts-ignore
import camera from '@ohos.multimedia.camera'
import Logger from '../model/Logger'
import CameraService from '../model/CameraService'
import { CustomContainer } from '../common/CameraPhotoContainer';
import FirstDialog from '../model/FirstDialog';
import router from '@ohos.router';
@Entry
@Component
struct cameraOrientation {
@State FillColor: string = '#FF000000';
@State name: string = 'CameraSerialPhoto';
@State StepTips: string = '测试目的:用于测试相机连拍\n-左侧显示相机预览窗口\n-右侧显示拍照后的每个图片\n-对于前置摄像头会有镜像效果\n测试步骤:\n1.点击拍照按钮\n预期结果:点击拍照按钮后每个摄像头连拍生成10张图片';
private tag: string = 'qlw CameraSerialPhoto'
private mXComponentController: XComponentController = new XComponentController()
@State surfaceId: number = 0;
@State cameraDeviceIndex: number = 0
@State assetUri: string = undefined
@State Vue: boolean = false
@State imageRotation: number = 0
@State cameraListLength: number = undefined
@State cameraList: SelectOption[] = []
@State isEnabled: boolean = true
@State takeSelect: number = 0
@State clickFrequency: number = 0
@State resolutionSelectVal: string = '' // 下拉框默认value
@State @Watch('onChangeClickSerialPhotoVal') clickSerialPhotoVal: number = 0
@State timer: number = -1
async aboutToAppear() {
await FirstDialog.ChooseDialog(this.StepTips, this.name);
CameraService.setTakePictureCallback(this.handleTakePicture.bind(this))
}
onChangeClickSerialPhotoVal() {
if (this.clickSerialPhotoVal < 10 * this.cameraListLength || this.clickSerialPhotoVal == 10 * this.cameraListLength) {
CameraService.takePicture()
this.assetUri = ''
if (this.clickSerialPhotoVal == 10) {
this.onChangeCamera()
}
if (this.clickSerialPhotoVal == 10 * this.cameraListLength){
clearInterval(this.timer)
this.Vue = true
}
return
}
}
onChangeCamera(){
if (this.cameraListLength > 1){
this.cameraDeviceIndex = Number(!this.cameraDeviceIndex)
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex).then(() => {
this.cameraListFn()
})
}
}
cameraListFn() {
this.cameraList = []
this.cameraListLength = CameraService.cameras.length
for (let index = 0; index < this.cameraListLength; index++) {
this.cameraList.push({ value: `Camera ${index}` })
}
}
handleTakePicture = (assetUri: string) => {
this.assetUri = assetUri
Logger.info(this.tag, `takePicture end, assetUri: ${this.assetUri}`)
}
onPageShow() {
Logger.info(this.tag, `takePicture end, assetUri`)
// @ts-ignore
this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex).then(() => {
this.cameraListFn()
})
}
onPageHide() {
CameraService.releaseCamera()
Logger.info(this.tag, `onPageHide releaseCamera end`)
}
build() {
Column() {
Row() {
Button() {
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({ left: '20vp' })
}.backgroundColor(Color.Black)
.onClick(() => {
router.back({
url: 'pages/Camera/Camera_index',
params: { result: 'None', }
})
})
Text(this.name).fontColor(Color.White).fontSize('18fp').margin({ left: '-20vp' })
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceAround }) {
Column() {
XComponent({
id: 'componentId',
type: 'surface',
controller: this.mXComponentController
})
.onLoad(async () => {
Logger.info(this.tag, 'onLoad is called')
// @ts-ignore
this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
Logger.info(this.tag, `onLoad surfaceId: ${this.surfaceId}`)
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex).then(() => {
this.cameraListFn()
})
})
.size({ width: '100%', height: '100%' })
Text('Camera Preview').fontSize('20fp').fontColor(Color.White)
}.size({ width: '40%', height: '60%' })
Column() {
Image(this.assetUri || '').size({ width: '100%', height: '100%' }).border({ width: 1 })
Text('Oriented Photo').fontSize('20fp').fontColor(Color.White)
}.size({ width: '40%', height: '60%' })
}.width('100%').height('50%')
Flex({ direction: FlexDirection.Column }) {
Select(this.cameraList)
.selected(this.cameraDeviceIndex)
.value(this.cameraDeviceIndex ? 'Camera 1' : 'Camera 0')
.font({ size: 16, weight: 500 })
.fontColor(Color.White)
.selectedOptionBgColor(Color.Black)
.optionBgColor(Color.Black)
.selectedOptionFont({ size: 16, weight: 400 })
.optionFont({ size: 16, weight: 400 })
.onSelect((index: number) => {
this.cameraDeviceIndex = index
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex).then(() => {
this.cameraListFn()
})
})
Text(`提示:`).fontSize('16fp').fontColor(Color.White)
Text(`期望拍摄${this.cameraListLength*10}张照片,实际拍摄${this.clickSerialPhotoVal}张,如果一致请选择pass,否则选择fail`)
.fontSize('16fp').fontColor(Color.White)
}.size({ width: '80%', height: '25%' })
Button('拍照')
.enabled(this.isEnabled)
.opacity(this.isEnabled ? 1 : 0.4)
.width('50%')
.height('5%')
.backgroundColor(0x317aff)
.onClick(async () => {
this.isEnabled = false
this.timer = setInterval(() => {
this.clickSerialPhotoVal++
}, 1000)
})
CustomContainer({
title: this.name,
Url: 'pages/Camera/Camera_index',
StepTips: this.StepTips,
FillColor: $FillColor,
name: $name,
Vue: $Vue
}).height('10%').width('100%')
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
\ No newline at end of file
validator/acts_validator/src/main/ets/pages/Camera/CameraVideo.ets
浏览文件 @
8ea871d1
/*
* Copyright (c) 202
2-202
3 Huawei Device Co., Ltd.
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
...
...
@@ -12,86 +12,261 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// @ts-ignore
import camera from '@ohos.multimedia.camera'
import Logger from '../model/Logger'
import CameraService from '../model/CameraService'
import {CustomContainer} from '../common/CameraOrientation';
import FirstDialog from '../model/FirstDialog';
const CameraMode = {
MODE_PHOTO: 0, // 拍照模式
MODE_VIDEO: 1 // 录像模式
}
import { CustomContainer } from '../common/CameraVideoContainer'
import FirstDialog from '../model/FirstDialog'
import router from '@ohos.router'
import mediaPlay from '../model/mediaPlay'
import prompt from '@ohos.prompt'
@Entry
@Component
struct
SetCircle
{
struct
cameraOrientation
{
@State FillColor: string = '#FF000000';
@State name: string = 'CameraVideo';
@State StepTips: string = '测试目的:用于测试相机
不同分辨率下的录像能力\n-上边显示录像的预览窗口\n-按下测试按钮后触发3s录像,回放的录像文件将在录像结束后显示在下边窗口\n-使用下拉框可以选择相机设备和分辨率'+'\n'+'预期结果:回放的录像视频与预览窗口的画面
一致';
private tag: string = 'qlw'
@State StepTips: string = '测试目的:用于测试相机
录像分辨率能力\n预期结果:所有分辨率均可以录像,录像与预览
一致';
private tag: string = 'qlw
CameraVideo
'
private mXComponentController: XComponentController = new XComponentController()
private mXComponentController1: XComponentController = new XComponentController()
@State surfaceId: number = 0;
private x: number = 0;
@State curModel: number = CameraMode.MODE_PHOTO
@State cameraDeviceIndex: number = 0
@State imageRotationValue: number = camera.ImageRotation.ROTATION_90
@State qualityLevelValue: number = camera.QualityLevel.QUALITY_LEVEL_LOW
@State assetUri: string = undefined
@State Vue: boolean = false
async aboutToAppear(){
await FirstDialog.ChooseDialog(this.StepTips,this.name);
@State takeFlag: boolean = true
@State isEnabled: boolean = true
@State resolution: SelectOption[] = [] // 分辨率
@State clickFrequency: number = 0 // 点击次数
@State resolutionSelectVal: string = '' // 下拉框默认value
@State cameraListLength: number = undefined // 相机数量
@State cameraList: SelectOption[] = [] // 相机列表
@State testingFrequency: number = undefined // 测试总数
@State testEnabled: boolean = true
@State nextEnabled: boolean = false
async aboutToAppear() {
await FirstDialog.ChooseDialog(this.StepTips, this.name);
}
handleTakePicture = (assetUri: string) => {
this.assetUri = assetUri
Logger.info(this.tag, `Video recorder end, assetUri: ${this.assetUri}`)
cameraListFn() {
this.cameraList = []
this.cameraListLength = CameraService.cameras.length
for (let index = 0; index < this.cameraListLength; index++) {
this.cameraList.push({ value: `Camera ${index}` })
}
// 测试总次数 = 摄像头0的分辨率 + 摄像头1的分辨率 优先以RK为主
this.testingFrequency = this.resolution.length
Logger.info(this.tag, `testingFrequency ${this.testingFrequency}`)
}
@Builder specificNoParam() {
Column() {
nextClickFn() {
// 切换next 次数增加 分辨率遍历 分辨率遍历完 切换摄像头 再次遍历分辨率 调取初始化相机进行改变
this.clickFrequency++
Logger.info(this.tag, `nextClickFn new clickFrequency: ${this.clickFrequency}`)
if (this.clickFrequency === this.testingFrequency) {
this.Vue = true
this.testEnabled = false
this.nextEnabled = false
return
}
let newResolution = this.dealWithResolutionFn(this.resolution)
Logger.info(this.tag, `nextClickFn new Resolution: ${newResolution}`)
this.cameraInit(newResolution[this.clickFrequency])
this.resolutionSelectVal = String(this.resolution[this.clickFrequency].value)
}
// 对分辨率数据处理 获取到需要的格式
dealWithResolutionFn(arr) {
let newResolution = []
arr.forEach((item) => {
let indexOf = item.value.indexOf("x")
let objW = Number(item.value.slice(0, indexOf))
let objH = Number(item.value.slice(indexOf + 1))
let obj = {
format: 1003,
size: {
"width": objW,
"height": objH
}
}
newResolution.push(obj)
})
return newResolution
}
async cameraInit(obj?) {
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex, obj).then(() => {
this.resolution = CameraService.resolution
this.resolutionSelectVal = String(this.resolution[this.clickFrequency].value)
this.cameraListFn()
})
}
onPageShow() {
Logger.info(this.tag, `takePicture end, assetUri`)
// @ts-ignore
this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex)
}
onPageHide() {
CameraService.releaseCamera()
Logger.info(this.tag, `onPageHide releaseCamera end`)
}
build() {
Column() {
Row() {
Button() {
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({ left: '20vp' })
}.backgroundColor(Color.Black)
.onClick(() => {
router.back({
url: 'pages/Camera/Camera_index',
params: { result: 'None', }
})
})
Text(this.name).fontColor(Color.White).fontSize('18fp').margin({ left: '-20vp' })
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
Flex({ justifyContent: FlexAlign.SpaceEvenly }) {
Column() {
XComponent({
id: 'componentId',
type: 'surface',
controller: this.mXComponentController
})
.onLoad(async () => {
Logger.info(this.tag, 'onLoad is called')
// @ts-ignore
this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
Logger.info(this.tag, `onLoad surfaceId: ${this.surfaceId}`)
this.cameraInit()
})
.size({ width: '100%', height: '100%' })
Text('Video capture').fontSize('20fp').fontColor(Color.White)
}.size({ width: '45%', height: '100%' })
Column() {
XComponent({
id: '',
type: 'surface',
controller: this.mXComponentController1
})
.onLoad(() => {
})
.size({ width: '100%', height: '100%' })
Text('Video callback').fontSize('20fp').fontColor(Color.White)
}.size({ width: '45%', height: '100%' })
}.size({ width: '100%', height: '50%' })
Column() {
Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceEvenly }) {
Select(this.resolution)
.selected(this.clickFrequency)
.value(this.resolutionSelectVal)
.font({ size: 16, weight: 500 })
.fontColor(Color.White)
.margin({ top: 50 })
.selectedOptionBgColor(Color.Black)
.optionBgColor(Color.Black)
.selectedOptionFont({ size: 16, weight: 400 })
.optionFont({ size: 16, weight: 400 })
.onSelect((index: number, value) => {
let indexOf = value.indexOf('x')
let objW = Number(value.slice(0, indexOf))
let objH = Number(value.slice(indexOf + 1))
let obj = {
format: 1003,
size: {
"width": objW,
"height": objH
}
}
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex, obj)
Logger.info(this.tag, `onSelect Rotation index: ${index}, value: ${value}, obj: ${obj}`)
})
Select(this.cameraList)
.selected(this.cameraDeviceIndex)
.value(this.cameraDeviceIndex ? 'Camera 1' : 'Camera 0')
.font({ size: 16, weight: 500 })
.fontColor(Color.White)
.margin({ top: 50 })
.selectedOptionBgColor(Color.Black)
.optionBgColor(Color.Black)
.selectedOptionFont({ size: 16, weight: 400 })
.optionFont({ size: 16, weight: 400 })
.onSelect((index: number) => {
this.cameraDeviceIndex = index
this.cameraInit()
})
Select([{ value: 'YUV' }])
.selected(0)
.value('YUV')
.font({ size: 16, weight: 500 })
.fontColor(Color.White)
.margin({ top: 50 })
.selectedOptionBgColor(Color.Black)
.optionBgColor(Color.Black)
.selectedOptionFont({ size: 16, weight: 400 })
.optionFont({ size: 16, weight: 400 })
.onSelect((index: number, value) => {
Logger.info(this.tag, `onSelect format index: ${index}, value: ${value}`)
})
}.size({ width: '100%', height: '50%' })
Row() {
Button('TEST')
.borderRadius(8)
.backgroundColor(0x317aff)
.margin(15)
.enabled(this.testEnabled)
.opacity(this.testEnabled ? 1 : 0.4)
.size({ width: '30%', height: '40%' })
.onClick(async () => {
this.testEnabled = false
this.nextEnabled = true
prompt.showToast({
message: '录制中,请等待三秒', duration: 1000
});
CameraService.startVideo().then(() => {
setTimeout(() => {
// @ts-ignore
let sufferID = this.mXComponentController1.getXComponentSurfaceId()
Logger.info(this.tag, `onSelect format sufferID: ${sufferID}`)
mediaPlay.init(sufferID)
}, 4000)
})
})
Button('NEXT')
.borderRadius(8)
.backgroundColor(0x317aff)
.margin(15)
.enabled(this.nextEnabled)
.opacity(this.nextEnabled ? 1 : 0.4)
.size({ width: '30%', height: '40%' })
.onClick(async () => {
this.testEnabled = true
this.nextClickFn()
})
}.size({ width: '100%', height: '50%' }).justifyContent(FlexAlign.SpaceEvenly)
}.size({ width: '100%', height: '30%' })
CustomContainer({
title: this.name,
Url:'pages/Camera/Camera_index',
StepTips:this.StepTips,
content: this.specificNoParam,
FillColor:$FillColor,
Url: 'pages/Camera/Camera_index',
StepTips: this.StepTips,
FillColor: $FillColor,
name: $name,
Vue: $Vue
}).height('30%').width('100%')
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) {
XComponent({
id: 'componentId',
type: 'surface',
controller: this.mXComponentController
})
.onLoad(async () => {
Logger.info(this.tag, 'onLoad is called')
// @ts-ignore
this.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: 10, surfaceHeight: 10 })
// @ts-ignore
this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
Logger.info(this.tag, `onLoad surfaceId: ${this.surfaceId}`)
this.curModel = CameraMode.MODE_PHOTO
CameraService.initCamera(this.surfaceId, this.cameraDeviceIndex)
})
.height('40%')
.width('40%')
Text('Camera Preview').fontSize('20fp')
// Video()
Text('Video playback').fontSize('20fp')
Button('Test', {
type: ButtonType.Normal,
stateEffect: true
}).borderRadius(8).backgroundColor(0x317aff).width('20%').onClick(() => {
CameraService.startVideo()
CameraService.setTakePictureCallback(this.handleTakePicture.bind(this))
this.Vue = true
})
}.width('100%').height('70%').backgroundColor(Color.White)
Vue: $Vue,
}).height('10%').width('100%')
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
\ No newline at end of file
validator/acts_validator/src/main/ets/pages/Camera/Camera_index.ets
浏览文件 @
8ea871d1
...
...
@@ -39,9 +39,12 @@ struct IndexPage {
@State result : string = '';
@State TEST : number = 0;
private TestCaseList = [
{title:'Camera Orientation',uri:'pages/Camera/CameraOrientation'},
{title:'Camera Format',uri:'pages/Camera/CameraFormat'},
{title:'Camera Video',uri:'pages/Camera/CameraVideo'},
{ title: 'CameraPreviewFormat', uri: 'pages/Camera/CameraPreviewFormat' },
{ title: 'CameraPhotoFormat', uri: 'pages/Camera/CameraPhotoFormat' },
{ title: 'CameraOrientation', uri: 'pages/Camera/CameraOrientation' },
{ title: 'CameraSerialPhoto', uri: 'pages/Camera/CameraSerialPhoto' },
{ title: 'CameraVideo', uri: 'pages/Camera/CameraVideo' },
{ title: 'CameraFlash', uri: 'pages/Camera/CameraFlash' },
]
@State ColorObject : string[] = VarColor;
async onPageShow(){
...
...
validator/acts_validator/src/main/ets/pages/
Audio/ScrollListTest
.ets
→
validator/acts_validator/src/main/ets/pages/
Player/PlayAudio
.ets
浏览文件 @
8ea871d1
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CustomContainer} from '../common/CustomContainer';
import FirstDialog from '../model/FirstDialog';
@Entry
@Component
struct CustomContainerUser {
private listArr: number[] = Array.from(new Array(50).keys());
@State name: string = 'ScrollingList';
@State StepTips: string = '操作步骤:滑动列表观察是否能正常滑动'+'\n'+'预期结果:列表滑动正常';
@State Vue: boolean = false;
async aboutToAppear(){
await FirstDialog.ChooseDialog(this.StepTips,this.name);
this.Vue = true;
}
@Builder specificNoParam() {
Column() {
List() {
ForEach(this.listArr,(item:any,index:number) => {
ListItem() {
Text('Item #' + (index + 1)).width('100%').height(50).fontSize(16).fontColor(Color.White).margin({left:'10vp'})
}
},index => index)
}.height('100%').width('100%').divider({strokeWidth:1,color:Color.Grey})
}.height('83%').width('100%')
}
build() {
Column() {
CustomContainer({
title: this.name,
Url: 'pages/Audio/Audio_index',
StepTips: this.StepTips,
content: this.specificNoParam.bind(this),
name: $name,
Vue: $Vue,
})
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CustomContainer } from '../common/AudioContainer';
import FirstDialog from '../model/FirstDialog';
import router from '@ohos.router';
@Entry
@Component
struct playAudio {
@State FillColor: string = '#FF000000';
@State name: string = 'PlayAudio';
@State StepTips: string = '测试目的:用于测试音频播放暂停seek\n预期结果:音频播放暂停seek功能正常';
private tag: string = 'qlw'
@State Vue: boolean = false
@State videoSrc: Resource = $rawfile('StarWars10s-1C-44100-2SW.wav')
@State isAutoPlay: boolean = true
@State showControls: boolean = true
controller: VideoController = new VideoController()
async aboutToAppear() {
await FirstDialog.ChooseDialog(this.StepTips, this.name);
}
build() {
Column() {
Row() {
Button() {
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({ left: '20vp' })
}.backgroundColor(Color.Black)
.onClick(() => {
router.back({
url: 'pages/Player/Player_index',
params: { result: 'None', }
})
})
Text(this.name).fontColor(Color.White).fontSize('18fp').margin({ left: '-20vp' })
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Video({
src: this.videoSrc,
controller: this.controller
})
.width('100%')
.height('60%')
.autoPlay(this.isAutoPlay)
.controls(this.showControls)
.onFinish(() => {
this.Vue = true
})
}.width('100%').height('80%').onClick(() => {
this.showControls = !this.showControls
})
CustomContainer({
title: this.name,
Url: 'pages/Player/Player_index',
StepTips: this.StepTips,
name: $name,
Vue: $Vue
}).height('10%').width('100%')
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
\ No newline at end of file
validator/acts_validator/src/main/ets/pages/Player/
ScrollListTest
.ets
→
validator/acts_validator/src/main/ets/pages/Player/
PlayVideo
.ets
浏览文件 @
8ea871d1
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {CustomContainer} from '../common/CustomContainer';
import FirstDialog from '../model/FirstDialog';
@Entry
@Component
struct CustomContainerUser {
private listArr: number[] = Array.from(new Array(50).keys());
@State name: string = 'ScrollingList';
@State StepTips: string = '操作步骤:滑动列表观察是否能正常滑动'+'\n'+'预期结果:列表滑动正常';
@State Vue: boolean = false;
async aboutToAppear(){
await FirstDialog.ChooseDialog(this.StepTips,this.name);
this.Vue = true;
}
@Builder specificNoParam() {
Column() {
List() {
ForEach(this.listArr,(item:any,index:number) => {
ListItem() {
Text('Item #' + (index + 1)).width('100%').height(50).fontSize(16).fontColor(Color.White).margin({left:'10vp'})
}
},index => index)
}.height('100%').width('100%').divider({strokeWidth:1,color:Color.Grey})
}.height('83%').width('100%')
}
build() {
Column() {
CustomContainer({
title: this.name,
Url: 'pages/Player/Player_index',
StepTips: this.StepTips,
content: this.specificNoParam.bind(this),
name: $name,
Vue: $Vue,
})
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CustomContainer } from '../common/AudioContainer';
import FirstDialog from '../model/FirstDialog';
import router from '@ohos.router';
@Entry
@Component
struct playVideo {
@State FillColor: string = '#FF000000';
@State name: string = 'PlayVideo';
@State StepTips: string = '测试目的:用于测试视频播放暂停seek\n预期结果:视频播放暂停seek功能正常';
private tag: string = 'qlw'
@State Vue: boolean = false
@State videoSrc: Resource = $rawfile('H264_AAC.mkv')
@State isAutoPlay: boolean = true
@State showControls: boolean = true
controller: VideoController = new VideoController()
async aboutToAppear() {
await FirstDialog.ChooseDialog(this.StepTips, this.name);
}
build() {
Column() {
Row() {
Button() {
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({ left: '20vp' })
}.backgroundColor(Color.Black)
.onClick(() => {
router.back({
url: 'pages/Player/Player_index',
params: { result: 'None', }
})
})
Text(this.name).fontColor(Color.White).fontSize('18fp').margin({ left: '-20vp' })
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Video({
src: this.videoSrc,
controller: this.controller
})
.width('100%')
.height('60%')
.autoPlay(this.isAutoPlay)
.controls(this.showControls)
.onFinish(() => {
this.Vue = true
})
}.width('100%').height('80%').onClick(() => {
this.showControls = !this.showControls
})
CustomContainer({
title: this.name,
Url: 'pages/Player/Player_index',
StepTips: this.StepTips,
name: $name,
Vue: $Vue
}).height('10%').width('100%')
}.width('100%').height('100%').backgroundColor(Color.Black)
}
}
\ No newline at end of file
validator/acts_validator/src/main/ets/pages/Player/Player_index.ets
浏览文件 @
8ea871d1
...
...
@@ -39,7 +39,8 @@ struct IndexPage {
@State result : string = '';
@State TEST : number = 0;
private TestCaseList = [
{title:'ScrollingList',uri:'pages/Player/ScrollListTest'},
{title:'PlayAudio',uri:'pages/Player/PlayAudio'},
{title:'PlayVideo',uri:'pages/Player/PlayVideo'},
]
@State ColorObject : string[] = VarColor;
async onPageShow(){
...
...
validator/acts_validator/src/main/ets/pages/common/AudioContainer.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import prompt from '@ohos.prompt';
import fileio from '@ohos.fileio';
import router from '@ohos.router';
// @ts-ignore
import screenshot from '@ohos.screenshot';
import image from '@ohos.multimedia.image';
import Logger from '../model/Logger';
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
let path = globalThis.dir;
const TAG = '[Screenshot]';
@Component
export struct CustomContainer {
@Link name : string;
title : string = '';
StepTips: string = '';
Url : string = '';
@Link Vue : boolean;
@Builder
PassBtn(text: Resource, isFullScreen: boolean) {
if(this.Vue == false){
Button({stateEffect:this.Vue}) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey).opacity(0.4)
.onClick(()=>{
})
}
else{
Button({stateEffect:this.Vue}) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(()=>{
router.back({
url:this.Url,
params: {result : 'Pass', title : this.name,
}
})
this.getScreen(isFullScreen);
prompt.showToast({
message: '通过', duration: 1000
});
})
}
}
@Builder
FailBtn(text: Resource, isFullScreen: boolean) {
Button(){
Image($r('app.media.ic_public_fail')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(()=>{
router.back({
url:this.Url,
params: {result : 'Fail',title : this.name,
}
})
this.getScreen(isFullScreen);
prompt.showToast({
message: '失败', duration: 1000
});
})
}
build() {
Column() {
Row() {
this.PassBtn($r('app.string.btn_fullscreen'), true);
Button(){
Image($r('app.media.ic_public_help')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(() =>{
AlertDialog.show({
title:'操作提示',
message: this.StepTips,
confirm:{
value:'OK',
action:()=>{
}
}
})
})
this.FailBtn($r('app.string.btn_fullscreen'), true);
}.width('100%').justifyContent(FlexAlign.SpaceEvenly).backgroundColor(Color.Black)
}.height('98%').width('100%')
}
async savePicture(data: image.PixelMap, context: any) {
Logger.info(TAG, `savePicture`);
let packOpts: image.PackingOption = {
format: "image/jpeg", quality: 100
};
let info = {
prefix: 'IMG_', suffix: '.jpg', directory: mediaLibrary.DirectoryType.DIR_IMAGE
};
let name = this.name;
let displayName = `${info.prefix}${name}${info.suffix}`;
let dirPath = path + '/' + displayName;
let imagePackerApi = image.createImagePacker();
let arrayBuffer = await imagePackerApi.packing(data, packOpts);
let fd = fileio.openSync(dirPath,0o102,0o666);
imagePackerApi.release();
try {
await fileio.write(fd, arrayBuffer);
} catch (err) {
Logger.error(`write failed, code is ${err.code}, message is ${err.message}`);
}
await fileio.close(fd);
Logger.info(TAG, `write done`);
}
getScreen = (isFullScreen: boolean) => {
let screenshotOptions: screenshot.ScreenshotOptions = {
screenRect: { left: 0, top: 0, width: 400, height: 400 },
imageSize: { width: 400, height: 400 },
rotation: 0,
displayId: 0
};
if (isFullScreen) {
screenshotOptions = {
rotation: 0
}
}
try {
screenshot.save(screenshotOptions, (err, data: image.PixelMap) => {
if (err) {
Logger.info(TAG, `Failed to save the screenshot. Error:${JSON.stringify(err)}`);
}
Logger.info(TAG, 'save callback');
this.savePicture(data, getContext(this) as any);
})
} catch (err) {
Logger.error(`save failed, code is ${err.code}, message is ${err.message}`);
}
}
}
validator/acts_validator/src/main/ets/pages/common/CameraFlashContainer.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fileio from '@ohos.fileio';
import prompt from '@ohos.prompt';
import router from '@ohos.router';
// @ts-ignore
import screenshot from '@ohos.screenshot';
import image from '@ohos.multimedia.image';
import Logger from '../model/Logger';
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
let path = globalThis.dir;
const TAG = '[Screenshot]';
@Component
export struct CustomContainer {
@Link FillColor: string;
@Link name: string;
@Link Vue: boolean;
@Link isFlash: boolean;
Url: string = '';
title: string = '';
StepTips: string = '';
@Builder
PassBtn(text: Resource, isFullScreen: boolean) {
if (this.Vue == false) {
Button({ stateEffect: this.Vue }) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}
.width('30%')
.height('30vp')
.backgroundColor(Color.Grey)
.opacity(0.4)
.onClick(() => {
})
}
else {
Button({ stateEffect: this.Vue }) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(() => {
router.back({
url: this.Url,
params: { result: 'Pass', title: this.name,
}
})
this.getScreen(isFullScreen);
prompt.showToast({
message: '通过', duration: 1000
});
})
}
}
@Builder
FailBtn(text: Resource, isFullScreen: boolean) {
Button() {
Image($r('app.media.ic_public_fail')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(() => {
router.back({
url: this.Url,
params: { result: 'Fail', title: this.name,
}
})
this.getScreen(isFullScreen);
prompt.showToast({
message: '失败', duration: 1000
});
})
}
build() {
Column() {
Flex({
justifyContent: FlexAlign.SpaceEvenly, alignItems: ItemAlign.Center
}) {
this.PassBtn($r('app.string.btn_fullscreen'), true);
Button() {
Image($r('app.media.ic_public_help')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(() => {
AlertDialog.show(
{
title: '操作提示',
message: this.StepTips,
confirm: {
value: 'OK',
action: () => {
}
}
}
)
})
this.FailBtn($r('app.string.btn_fullscreen'), true);
}.height('98%').width('100%').backgroundColor(Color.Black)
}.height('98%').width('100%')
}
async savePicture(data: image.PixelMap, context: any) {
Logger.info(TAG, `savePicture`);
let packOpts: image.PackingOption = {
format: "image/jpeg", quality: 100
};
let info = {
prefix: 'IMG_', suffix: '.jpg', directory: mediaLibrary.DirectoryType.DIR_IMAGE
};
let name = this.name;
let displayName = `${info.prefix}${name}${info.suffix}`;
let dirPath = path + '/' + displayName;
let imagePackerApi = image.createImagePacker();
let arrayBuffer = await imagePackerApi.packing(data, packOpts);
let fd = fileio.openSync(dirPath, 0o102, 0o666);
imagePackerApi.release();
try {
await fileio.write(fd, arrayBuffer);
} catch (err) {
Logger.error(`write failed, code is ${err.code}, message is ${err.message}`);
}
await fileio.close(fd);
Logger.info(TAG, `write done`);
}
getScreen = (isFullScreen: boolean) => {
let screenshotOptions: screenshot.ScreenshotOptions = {
screenRect: { left: 0, top: 0, width: 400, height: 400 },
imageSize: { width: 400, height: 400 },
rotation: 0,
displayId: 0
};
if (isFullScreen) {
screenshotOptions = {
rotation: 0
}
}
try {
screenshot.save(screenshotOptions, (err, data: image.PixelMap) => {
if (err) {
Logger.info(TAG, `Failed to save the screenshot. Error:${JSON.stringify(err)}`);
}
Logger.info(TAG, 'save callback');
this.savePicture(data, getContext(this) as any);
})
} catch (err) {
Logger.error(`save failed, code is ${err.code}, message is ${err.message}`);
}
}
}
validator/acts_validator/src/main/ets/pages/common/CameraOrientationContainer.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fileio from '@ohos.fileio';
import prompt from '@ohos.prompt';
import router from '@ohos.router';
// @ts-ignore
import screenshot from '@ohos.screenshot';
import image from '@ohos.multimedia.image';
import Logger from '../model/Logger';
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
let path = globalThis.dir;
const TAG = '[Screenshot]';
@Component
export struct CustomContainer {
@Link FillColor: string;
@Link name: string;
@Link Vue : boolean;
@Link isEnabled: boolean;
Url : string = '';
title : string = '';
StepTips: string = '';
testingFrequency: number
@Link clickFrequency: number
@Builder
PassBtn(text: Resource, isFullScreen: boolean) {
if(this.Vue == false){
Button({stateEffect:this.Vue}) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey).opacity(0.4)
.onClick(()=>{
})
}
else{
Button({stateEffect:this.Vue}) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(()=>{
this.isEnabled = true
this.Vue = false
this.clickFrequency++
if (this.clickFrequency === this.testingFrequency){
router.back({
url:this.Url,
params: {result : 'Pass', title : this.name,
}
})
}
this.getScreen(isFullScreen);
prompt.showToast({
message: '通过', duration: 1000
});
})
}
}
@Builder
FailBtn(text: Resource, isFullScreen: boolean) {
Button(){
Image($r('app.media.ic_public_fail')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(()=>{
router.back({
url:this.Url,
params: {result : 'Fail',title : this.name,
}
})
this.getScreen(isFullScreen);
prompt.showToast({
message: '失败', duration: 1000
});
})
}
build() {
Column() {
Flex({
justifyContent: FlexAlign.SpaceEvenly, alignItems: ItemAlign.Center
}){
this.PassBtn($r('app.string.btn_fullscreen'), true);
Button(){
Image($r('app.media.ic_public_help')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(() =>{
AlertDialog.show(
{
title:'操作提示',
message: this.StepTips,
confirm:{
value:'OK',
action:()=>{
}
}
}
)
})
this.FailBtn($r('app.string.btn_fullscreen'), true);
}.height('98%').width('100%').backgroundColor(Color.Black)
}.height('98%').width('100%')
}
async savePicture(data: image.PixelMap, context: any) {
Logger.info(TAG, `savePicture`);
let packOpts: image.PackingOption = {
format: "image/jpeg", quality: 100
};
let info = {
prefix: 'IMG_', suffix: '.jpg', directory: mediaLibrary.DirectoryType.DIR_IMAGE
};
let name = this.name;
let displayName = `${info.prefix}${name}${info.suffix}`;
let dirPath = path + '/' + displayName;
let imagePackerApi = image.createImagePacker();
let arrayBuffer = await imagePackerApi.packing(data, packOpts);
let fd = fileio.openSync(dirPath,0o102,0o666);
imagePackerApi.release();
try {
await fileio.write(fd, arrayBuffer);
} catch (err) {
Logger.error(`write failed, code is ${err.code}, message is ${err.message}`);
}
await fileio.close(fd);
Logger.info(TAG, `write done`);
}
getScreen = (isFullScreen: boolean) => {
let screenshotOptions: screenshot.ScreenshotOptions = {
screenRect: { left: 0, top: 0, width: 400, height: 400 },
imageSize: { width: 400, height: 400 },
rotation: 0,
displayId: 0
};
if (isFullScreen) {
screenshotOptions = {
rotation: 0
}
}
try {
screenshot.save(screenshotOptions, (err, data: image.PixelMap) => {
if (err) {
Logger.info(TAG, `Failed to save the screenshot. Error:${JSON.stringify(err)}`);
}
Logger.info(TAG, 'save callback');
this.savePicture(data, getContext(this) as any);
})
} catch (err) {
Logger.error(`save failed, code is ${err.code}, message is ${err.message}`);
}
}
}
validator/acts_validator/src/main/ets/pages/common/Camera
Orientation
.ets
→
validator/acts_validator/src/main/ets/pages/common/Camera
PhotoContainer
.ets
浏览文件 @
8ea871d1
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fileio from '@ohos.fileio';
import prompt from '@ohos.prompt';
import router from '@ohos.router';
import screenshot from '@ohos.screenshot';
import image from '@ohos.multimedia.image';
import Logger from '../model/Logger';
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
let path = globalThis.dir;
const TAG = '[Screenshot]';
@Component
export struct CustomContainer {
@Link FillColor: string;
@Link name: string;
@Link Vue : boolean;
Url : string = '';
title : string = '';
StepTips: string = '';
@BuilderParam content: () => void;
@Builder
PassBtn(text: Resource, isFullScreen: boolean) {
if(this.Vue == false){
Button({stateEffect:this.Vue}) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey).opacity(0.4)
.onClick(()=>{
})
}
else{
Button({stateEffect:this.Vue}) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(()=>{
router.back({
url:this.Url,
params: {result : 'Pass', title : this.name,
}
})
this.getScreen(isFullScreen);
prompt.showToast({
message: '通过', duration: 1000
});
})
}
}
@Builder
FailBtn(text: Resource, isFullScreen: boolean) {
Button(){
Image($r('app.media.ic_public_fail')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(()=>{
router.back({
url:this.Url,
params: {result : 'Fail',title : this.name,
}
})
this.getScreen(isFullScreen);
prompt.showToast({
message: '失败', duration: 1000
});
})
}
build() {
Column() {
Row() {
Button(){
Image($r('app.media.ic_public_back')).width('20vp').height('18vp').margin({left:'20vp'})
}.backgroundColor(Color.Black)
.onClick(()=>{
router.back({
url:this.Url,
params: {result : 'None',}
})
})
Text(this.title).fontColor(Color.White).fontSize('18fp').margin({left:'-20vp'})
Text('hello').fontColor(Color.White).visibility(Visibility.Hidden)
}.backgroundColor(Color.Black).height('10%').width('100%').justifyContent(FlexAlign.SpaceBetween)
this.content();
Blank()
Row() {
this.PassBtn($r('app.string.btn_fullscreen'), true);
Button(){
Image($r('app.media.ic_public_help')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(() =>{
AlertDialog.show(
{
title:'操作提示',
message: this.StepTips,
confirm:{
value:'OK',
action:()=>{
}
}
}
)
})
this.FailBtn($r('app.string.btn_fullscreen'), true);
}.width('100%').justifyContent(FlexAlign.SpaceEvenly).backgroundColor(Color.Black)
}.height('98%').width('100%')
}
async savePicture(data: image.PixelMap, context: any) {
Logger.info(TAG, `savePicture`);
let packOpts: image.PackingOption = {
format: "image/jpeg", quality: 100
};
let info = {
prefix: 'IMG_', suffix: '.jpg', directory: mediaLibrary.DirectoryType.DIR_IMAGE
};
let name = this.name;
let displayName = `${info.prefix}${name}${info.suffix}`;
let dirPath = path + '/screenshot' + '/' + displayName;
let imagePackerApi = image.createImagePacker();
let arrayBuffer = await imagePackerApi.packing(data, packOpts);
let fd = fileio.openSync(dirPath,0o102,0o666);
imagePackerApi.release();
try {
await fileio.write(fd, arrayBuffer);
} catch (err) {
Logger.error(`write failed, code is ${err.code}, message is ${err.message}`);
}
await fileio.close(fd);
Logger.info(TAG, `write done`);
}
getScreen = (isFullScreen: boolean) => {
let screenshotOptions: screenshot.ScreenshotOptions = {
screenRect: { left: 0, top: 0, width: 400, height: 400 },
imageSize: { width: 400, height: 400 },
rotation: 0,
displayId: 0
};
if (isFullScreen) {
screenshotOptions = {
rotation: 0
}
}
try {
screenshot.save(screenshotOptions, (err, data: image.PixelMap) => {
if (err) {
Logger.info(TAG, `Failed to save the screenshot. Error:${JSON.stringify(err)}`);
}
Logger.info(TAG, 'save callback');
this.savePicture(data, getContext(this) as any);
})
} catch (err) {
Logger.error(`save failed, code is ${err.code}, message is ${err.message}`);
}
}
}
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fileio from '@ohos.fileio';
import prompt from '@ohos.prompt';
import router from '@ohos.router';
// @ts-ignore
import screenshot from '@ohos.screenshot';
import image from '@ohos.multimedia.image';
import Logger from '../model/Logger';
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
let path = globalThis.dir;
const TAG = '[Screenshot]';
@Component
export struct CustomContainer {
@Link FillColor: string;
@Link name: string;
@Link Vue : boolean;
Url : string = '';
title : string = '';
StepTips: string = '';
@Builder
PassBtn(text: Resource, isFullScreen: boolean) {
if(this.Vue == false){
Button({stateEffect:this.Vue}) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey).opacity(0.4)
.onClick(()=>{
})
}
else{
Button({stateEffect:this.Vue}) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(()=>{
router.back({
url:this.Url,
params: {result : 'Pass', title : this.name,
}
})
this.getScreen(isFullScreen);
prompt.showToast({
message: '通过', duration: 1000
});
})
}
}
@Builder
FailBtn(text: Resource, isFullScreen: boolean) {
Button(){
Image($r('app.media.ic_public_fail')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(()=>{
router.back({
url:this.Url,
params: {result : 'Fail',title : this.name,
}
})
this.getScreen(isFullScreen);
prompt.showToast({
message: '失败', duration: 1000
});
})
}
build() {
Column() {
Flex({
justifyContent: FlexAlign.SpaceEvenly, alignItems: ItemAlign.Center
}){
this.PassBtn($r('app.string.btn_fullscreen'), true);
Button(){
Image($r('app.media.ic_public_help')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(() =>{
AlertDialog.show(
{
title:'操作提示',
message: this.StepTips,
confirm:{
value:'OK',
action:()=>{
}
}
}
)
})
this.FailBtn($r('app.string.btn_fullscreen'), true);
}.height('98%').width('100%').backgroundColor(Color.Black)
}.height('98%').width('100%')
}
async savePicture(data: image.PixelMap, context: any) {
Logger.info(TAG, `savePicture`);
let packOpts: image.PackingOption = {
format: "image/jpeg", quality: 100
};
let info = {
prefix: 'IMG_', suffix: '.jpg', directory: mediaLibrary.DirectoryType.DIR_IMAGE
};
let name = this.name;
let displayName = `${info.prefix}${name}${info.suffix}`;
let dirPath = path + '/' + displayName;
let imagePackerApi = image.createImagePacker();
let arrayBuffer = await imagePackerApi.packing(data, packOpts);
let fd = fileio.openSync(dirPath,0o102,0o666);
imagePackerApi.release();
try {
await fileio.write(fd, arrayBuffer);
} catch (err) {
Logger.error(`write failed, code is ${err.code}, message is ${err.message}`);
}
await fileio.close(fd);
Logger.info(TAG, `write done`);
}
getScreen = (isFullScreen: boolean) => {
let screenshotOptions: screenshot.ScreenshotOptions = {
screenRect: { left: 0, top: 0, width: 400, height: 400 },
imageSize: { width: 400, height: 400 },
rotation: 0,
displayId: 0
};
if (isFullScreen) {
screenshotOptions = {
rotation: 0
}
}
try {
screenshot.save(screenshotOptions, (err, data: image.PixelMap) => {
if (err) {
Logger.info(TAG, `Failed to save the screenshot. Error:${JSON.stringify(err)}`);
}
Logger.info(TAG, 'save callback');
this.savePicture(data, getContext(this) as any);
})
} catch (err) {
Logger.error(`save failed, code is ${err.code}, message is ${err.message}`);
}
}
}
validator/acts_validator/src/main/ets/pages/common/CameraPreviewFormatContainer.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fileio from '@ohos.fileio';
import prompt from '@ohos.prompt';
import router from '@ohos.router';
// @ts-ignore
import screenshot from '@ohos.screenshot';
import image from '@ohos.multimedia.image';
import Logger from '../model/Logger';
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
let path = globalThis.dir;
const TAG = '[Screenshot]';
@Component
export struct CustomContainer {
@Link FillColor: string;
@Link name: string;
@Link Vue : boolean;
Url : string = '';
title : string = '';
StepTips: string = '';
@Builder
PassBtn(text: Resource, isFullScreen: boolean) {
if(this.Vue == false){
Button({stateEffect:this.Vue}) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey).opacity(0.4)
.onClick(()=>{
})
}
else{
Button({stateEffect:this.Vue}) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(()=>{
router.back({
url:this.Url,
params: {result : 'Pass', title : this.name,
}
})
this.getScreen(isFullScreen);
prompt.showToast({
message: '通过', duration: 1000
});
})
}
}
@Builder
FailBtn(text: Resource, isFullScreen: boolean) {
Button(){
Image($r('app.media.ic_public_fail')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(()=>{
router.back({
url:this.Url,
params: {result : 'Fail',title : this.name,
}
})
this.getScreen(isFullScreen);
prompt.showToast({
message: '失败', duration: 1000
});
})
}
build() {
Column() {
Flex({
justifyContent: FlexAlign.SpaceEvenly, alignItems: ItemAlign.Center
}){
this.PassBtn($r('app.string.btn_fullscreen'), true);
Button(){
Image($r('app.media.ic_public_help')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(() =>{
AlertDialog.show(
{
title:'操作提示',
message: this.StepTips,
confirm:{
value:'OK',
action:()=>{
}
}
}
)
})
this.FailBtn($r('app.string.btn_fullscreen'), true);
}.height('98%').width('100%').backgroundColor(Color.Black)
}.height('98%').width('100%')
}
async savePicture(data: image.PixelMap, context: any) {
Logger.info(TAG, `savePicture`);
let packOpts: image.PackingOption = {
format: "image/jpeg", quality: 100
};
let info = {
prefix: 'IMG_', suffix: '.jpg', directory: mediaLibrary.DirectoryType.DIR_IMAGE
};
let name = this.name;
let displayName = `${info.prefix}${name}${info.suffix}`;
let dirPath = path + '/' + displayName;
let imagePackerApi = image.createImagePacker();
let arrayBuffer = await imagePackerApi.packing(data, packOpts);
let fd = fileio.openSync(dirPath,0o102,0o666);
imagePackerApi.release();
try {
await fileio.write(fd, arrayBuffer);
} catch (err) {
Logger.error(`write failed, code is ${err.code}, message is ${err.message}`);
}
await fileio.close(fd);
Logger.info(TAG, `write done`);
}
getScreen = (isFullScreen: boolean) => {
let screenshotOptions: screenshot.ScreenshotOptions = {
screenRect: { left: 0, top: 0, width: 400, height: 400 },
imageSize: { width: 400, height: 400 },
rotation: 0,
displayId: 0
};
if (isFullScreen) {
screenshotOptions = {
rotation: 0
}
}
try {
screenshot.save(screenshotOptions, (err, data: image.PixelMap) => {
if (err) {
Logger.info(TAG, `Failed to save the screenshot. Error:${JSON.stringify(err)}`);
}
Logger.info(TAG, 'save callback');
this.savePicture(data, getContext(this) as any);
})
} catch (err) {
Logger.error(`save failed, code is ${err.code}, message is ${err.message}`);
}
}
}
validator/acts_validator/src/main/ets/pages/common/CameraVideoContainer.ets
0 → 100644
浏览文件 @
8ea871d1
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fileio from '@ohos.fileio';
import prompt from '@ohos.prompt';
import router from '@ohos.router';
// @ts-ignore
import screenshot from '@ohos.screenshot';
import image from '@ohos.multimedia.image';
import Logger from '../model/Logger';
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
let path = globalThis.dir;
const TAG = '[Screenshot]';
@Component
export struct CustomContainer {
@Link FillColor: string;
@Link name: string;
@Link Vue : boolean;
Url : string = '';
title : string = '';
StepTips: string = '';
@Builder
PassBtn(text: Resource, isFullScreen: boolean) {
if(this.Vue == false){
Button({stateEffect:this.Vue}) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey).opacity(0.4)
.onClick(()=>{
})
}
else{
Button({stateEffect:this.Vue}) {
Image($r('app.media.ic_public_pass')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(()=>{
router.back({
url:this.Url,
params: {result : 'Pass', title : this.name,
}
})
this.getScreen(isFullScreen);
prompt.showToast({
message: '通过', duration: 1000
});
})
}
}
@Builder
FailBtn(text: Resource, isFullScreen: boolean) {
Button(){
Image($r('app.media.ic_public_fail')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(()=>{
router.back({
url:this.Url,
params: {result : 'Fail',title : this.name,
}
})
this.getScreen(isFullScreen);
prompt.showToast({
message: '失败', duration: 1000
});
})
}
build() {
Column() {
Flex({
justifyContent: FlexAlign.SpaceEvenly, alignItems: ItemAlign.Center
}){
this.PassBtn($r('app.string.btn_fullscreen'), true);
Button(){
Image($r('app.media.ic_public_help')).width('20vp').height('20vp')
}.width('30%').height('30vp').backgroundColor(Color.Grey)
.onClick(() =>{
AlertDialog.show(
{
title:'操作提示',
message: this.StepTips,
confirm:{
value:'OK',
action:()=>{
}
}
}
)
})
this.FailBtn($r('app.string.btn_fullscreen'), true);
}.height('98%').width('100%').backgroundColor(Color.Black)
}.height('98%').width('100%')
}
async savePicture(data: image.PixelMap, context: any) {
Logger.info(TAG, `savePicture`);
let packOpts: image.PackingOption = {
format: "image/jpeg", quality: 100
};
let info = {
prefix: 'IMG_', suffix: '.jpg', directory: mediaLibrary.DirectoryType.DIR_IMAGE
};
let name = this.name;
let displayName = `${info.prefix}${name}${info.suffix}`;
let dirPath = path + '/' + displayName;
let imagePackerApi = image.createImagePacker();
let arrayBuffer = await imagePackerApi.packing(data, packOpts);
let fd = fileio.openSync(dirPath,0o102,0o666);
imagePackerApi.release();
try {
await fileio.write(fd, arrayBuffer);
} catch (err) {
Logger.error(`write failed, code is ${err.code}, message is ${err.message}`);
}
await fileio.close(fd);
Logger.info(TAG, `write done`);
}
getScreen = (isFullScreen: boolean) => {
let screenshotOptions: screenshot.ScreenshotOptions = {
screenRect: { left: 0, top: 0, width: 400, height: 400 },
imageSize: { width: 400, height: 400 },
rotation: 0,
displayId: 0
};
if (isFullScreen) {
screenshotOptions = {
rotation: 0
}
}
try {
screenshot.save(screenshotOptions, (err, data: image.PixelMap) => {
if (err) {
Logger.info(TAG, `Failed to save the screenshot. Error:${JSON.stringify(err)}`);
}
Logger.info(TAG, 'save callback');
this.savePicture(data, getContext(this) as any);
})
} catch (err) {
Logger.error(`save failed, code is ${err.code}, message is ${err.message}`);
}
}
}
validator/acts_validator/src/main/ets/pages/model/AudioCapturer.ts
0 → 100644
浏览文件 @
8ea871d1
import
audio
from
'
@ohos.multimedia.audio
'
import
deviceInfo
from
'
@ohos.deviceInfo
'
import
fileio
from
'
@ohos.fileio
'
import
image
from
'
@ohos.multimedia.image
'
import
media
from
'
@ohos.multimedia.media
'
import
mediaLibrary
from
'
@ohos.multimedia.mediaLibrary
'
import
Logger
from
'
../model/Logger
'
import
MediaUtils
from
'
../model/MediaUtils
'
// @ts-ignore
import
fs
from
'
@ohos.file.fs
'
import
mediaPlay
from
'
../model/mediaPlay
'
class
AudioCapturer
{
private
tag
:
string
=
'
qlw AudioCapture
'
private
static
instance
:
AudioCapturer
=
new
AudioCapturer
()
private
audioCapturer
:
audio
.
AudioCapturer
=
undefined
private
fd
:
number
=
undefined
private
isRecorder
:
boolean
=
false
private
file
:
fs
.
File
=
undefined
async
createAudioCapturer
()
{
let
AudioStreamInfo
=
{
samplingRate
:
audio
.
AudioSamplingRate
.
SAMPLE_RATE_44100
,
channels
:
audio
.
AudioChannel
.
CHANNEL_2
,
sampleFormat
:
audio
.
AudioSampleFormat
.
SAMPLE_FORMAT_S16LE
,
encodingType
:
audio
.
AudioEncodingType
.
ENCODING_TYPE_RAW
}
let
AudioCapturerInfo
=
{
source
:
audio
.
SourceType
.
SOURCE_TYPE_MIC
,
capturerFlags
:
0
}
let
AudioCapturerOptions
=
{
streamInfo
:
AudioStreamInfo
,
capturerInfo
:
AudioCapturerInfo
// @ts-ignore
}
this
.
audioCapturer
=
await
audio
.
createAudioCapturer
(
AudioCapturerOptions
)
}
async
getFileFd
()
{
let
filesDir
=
globalThis
.
abilityContext
.
filesDir
let
path
=
filesDir
+
'
/test.wav
'
Logger
.
info
(
this
.
tag
,
`getFileFd path :
${
path
}
`
)
this
.
file
=
fs
.
openSync
(
path
,
fs
.
OpenMode
.
READ_WRITE
|
fs
.
OpenMode
.
CREATE
|
fs
.
OpenMode
.
TRUNC
)
return
this
.
file
.
fd
}
async
startCapturer
()
{
try
{
this
.
fd
=
await
this
.
getFileFd
()
Logger
.
info
(
this
.
tag
,
`fd :
${
this
.
fd
}
`
)
if
(
this
.
fd
!==
null
)
{
Logger
.
info
(
this
.
tag
,
`create audio fileAssets success fd :
${
this
.
fd
}
`
)
}
else
{
Logger
.
info
(
this
.
tag
,
`create audio fileAssets error`
)
}
let
header
=
mediaPlay
.
encodeWAV
(
audio
.
AudioSamplingRate
.
SAMPLE_RATE_44100
,
audio
.
AudioSampleFormat
.
SAMPLE_FORMAT_S16LE
,
audio
.
AudioChannel
.
CHANNEL_2
)
Logger
.
info
(
this
.
tag
,
`wav header length:
${
header
.
buffer
.
byteLength
}
`
)
fs
.
writeSync
(
this
.
fd
,
header
.
buffer
)
this
.
audioCapturer
.
start
(
async
(
err
)
=>
{
if
(
err
)
{
Logger
.
info
(
this
.
tag
,
`Capture start failed`
)
}
else
{
Logger
.
info
(
this
.
tag
,
`Capture start success`
)
let
bufferSize
=
await
this
.
audioCapturer
.
getBufferSize
()
Logger
.
info
(
this
.
tag
,
`audioCapture bufferSize:
${
bufferSize
}
`
)
this
.
isRecorder
=
true
while
(
this
.
isRecorder
)
{
Logger
.
info
(
this
.
tag
,
'
audioCapture: ---------READ BUFFER---------
'
)
let
buffer
=
await
this
.
audioCapturer
.
read
(
bufferSize
,
true
)
Logger
.
info
(
this
.
tag
,
'
audioCapture: ---------WRITE BUFFER---------
'
)
fs
.
writeSync
(
this
.
fd
,
buffer
)
}
}
})
}
catch
(
err
)
{
Logger
.
info
(
this
.
tag
,
`startCapturer fail err:
${
err
}
, message:
${
err
.
message
}
, code:
${
err
.
code
}
`
)
}
}
async
stopCapturer
()
{
try
{
await
this
.
audioCapturer
.
stop
()
this
.
isRecorder
=
false
Logger
.
info
(
this
.
tag
,
`stopCapturer success`
)
}
catch
(
err
)
{
Logger
.
info
(
this
.
tag
,
`stopCapturer fail err:
${
err
}
, message:
${
err
.
message
}
, code:
${
err
.
code
}
`
)
}
}
async
releaseCapturer
()
{
try
{
if
(
this
.
audioCapturer
)
{
await
this
.
audioCapturer
.
release
()
Logger
.
info
(
this
.
tag
,
`releaseCapturer success`
)
}
if
(
this
.
file
)
{
fs
.
closeSync
(
this
.
file
);
Logger
.
info
(
this
.
tag
,
`release file success`
)
}
}
catch
(
err
)
{
Logger
.
info
(
this
.
tag
,
`stopCapturer fail err:
${
err
}
, message:
${
err
.
message
}
, code:
${
err
.
code
}
`
)
}
}
}
export
default
new
AudioCapturer
()
\ No newline at end of file
validator/acts_validator/src/main/ets/pages/model/AudioRenderer.ts
0 → 100644
浏览文件 @
8ea871d1
import
audio
from
'
@ohos.multimedia.audio
'
import
fileio
from
'
@ohos.fileio
'
import
Logger
from
'
../model/Logger
'
// @ts-ignore
import
fs
from
'
@ohos.file.fs
'
;
class
AudioRenderer
{
private
tag
:
string
=
'
qlw AudioRenderer
'
private
static
instance
:
AudioRenderer
=
new
AudioRenderer
()
private
audioRenderer
:
audio
.
AudioRenderer
=
undefined
private
fd
:
number
=
undefined
private
offset
:
number
=
undefined
async
createAudioRenderer
(){
let
audioStreamInfo
=
{
samplingRate
:
audio
.
AudioSamplingRate
.
SAMPLE_RATE_44100
,
channels
:
audio
.
AudioChannel
.
CHANNEL_2
,
// channels: audio.AudioChannel.CHANNEL_1,
sampleFormat
:
audio
.
AudioSampleFormat
.
SAMPLE_FORMAT_S16LE
,
encodingType
:
audio
.
AudioEncodingType
.
ENCODING_TYPE_RAW
}
let
audioRendererInfo
=
{
content
:
audio
.
ContentType
.
CONTENT_TYPE_MUSIC
,
usage
:
audio
.
StreamUsage
.
STREAM_USAGE_MEDIA
,
rendererFlags
:
0
}
let
audioRendererOptions
=
{
streamInfo
:
audioStreamInfo
,
rendererInfo
:
audioRendererInfo
}
this
.
audioRenderer
=
await
audio
.
createAudioRenderer
(
audioRendererOptions
);
}
async
startRenderer
(){
try
{
await
this
.
audioRenderer
.
start
()
// await globalThis.abilityContext.resourceManager.getRawFileDescriptor('test_44100_2.wav').then(value => {
// this.fd = value.fd
// Logger.info(this.tag, `fd : ${this.fd}`)
// let fileDescriptor = {fd: value.fd, offset: value.offset, length: value.length};
// Logger.info(this.tag, `getRawFileDescriptor success fileDescriptor:` + JSON.stringify(fileDescriptor) )
// }).catch(error => {
// console.log('case getRawFileDescriptor err: ' + error);
// });
globalThis
.
abilityContext
.
resourceManager
.
getRawFd
(
"
test_44100_2.wav
"
).
then
(
value
=>
{
this
.
fd
=
value
.
fd
this
.
offset
=
value
.
offset
Logger
.
info
(
this
.
tag
,
`getRawFd fd :
${
this
.
fd
}
, offset:
${
value
.
offset
}
, length:
${
value
.
length
}
`
)
}).
catch
(
err
=>
{
console
.
log
(
`getRawFd fail err:
${
err
}
, message:
${
err
.
message
}
, code:
${
err
.
code
}
`
);
})
let
bufferSize
=
await
this
.
audioRenderer
.
getBufferSize
()
Logger
.
info
(
this
.
tag
,
`audioRenderer bufferSize:`
+
JSON
.
stringify
(
bufferSize
))
let
stat
=
await
fs
.
stat
(
this
.
fd
);
let
len
=
stat
.
size
%
bufferSize
==
0
?
Math
.
floor
(
stat
.
size
/
bufferSize
)
:
Math
.
floor
(
stat
.
size
/
bufferSize
+
1
);
let
buf
=
new
ArrayBuffer
(
bufferSize
);
while
(
true
)
{
for
(
let
i
=
0
;
i
<
len
;
i
++
)
{
let
options
=
{
offset
:
i
*
bufferSize
+
this
.
offset
,
length
:
bufferSize
}
await
fs
.
read
(
this
.
fd
,
buf
,
options
)
try
{
await
this
.
audioRenderer
.
write
(
buf
)
}
catch
(
err
)
{
console
.
error
(
`audioRenderer.write err:
${
err
}
`
)
}
}
}
}
catch
(
err
){
Logger
.
info
(
this
.
tag
,
`startRenderer fail err:
${
err
}
, message:
${
err
.
message
}
, code:
${
err
.
code
}
`
)
}
}
async
stopRenderer
(){
try
{
await
this
.
audioRenderer
.
stop
()
}
catch
(
err
){
Logger
.
info
(
this
.
tag
,
`stopCapturer fail err:
${
err
}
, message:
${
err
.
message
}
, code:
${
err
.
code
}
`
)
}
}
async
releaseRenderer
(){
try
{
if
(
this
.
audioRenderer
){
await
this
.
audioRenderer
.
release
()
// await globalThis.abilityContext.resourceManager.closeRawFileDescriptor('test_44100_2.wav').then(()=> {
// Logger.info(this.tag, `closeRawFileDescriptor success`)
// }).catch(err => {
// Logger.info(this.tag, `closeRawFileDescriptor fail err: ${err}, message: ${err.message}, code: ${err.code}`)
// });
await
globalThis
.
abilityContext
.
resourceManager
.
closeRawFd
(
'
test_44100_2.wav
'
).
then
(()
=>
{
Logger
.
info
(
this
.
tag
,
`closeRawFileDescriptor success`
)
}).
catch
(
err
=>
{
Logger
.
info
(
this
.
tag
,
`closeRawFileDescriptor fail err:
${
err
}
, message:
${
err
.
message
}
, code:
${
err
.
code
}
`
)
});
}
}
catch
(
err
){
Logger
.
info
(
this
.
tag
,
`stopCapturer fail err:
${
err
}
, message:
${
err
.
message
}
, code:
${
err
.
code
}
`
)
}
}
}
export
default
new
AudioRenderer
()
\ No newline at end of file
validator/acts_validator/src/main/ets/pages/model/CameraService.ts
浏览文件 @
8ea871d1
此差异已折叠。
点击以展开。
validator/acts_validator/src/main/ets/pages/model/MediaUtils.ts
浏览文件 @
8ea871d1
...
...
@@ -37,7 +37,12 @@ export default class MediaUtils {
Logger
.
info
(
this
.
tag
,
`displayName =
${
displayName
}
,mediaType =
${
mediaType
}
`
)
let
publicPath
=
await
this
.
mediaTest
.
getPublicDirectory
(
info
.
directory
)
Logger
.
info
(
this
.
tag
,
`publicPath =
${
publicPath
}
`
)
return
await
this
.
mediaTest
.
createAsset
(
mediaType
,
displayName
,
publicPath
)
try
{
return
await
this
.
mediaTest
.
createAsset
(
mediaType
,
displayName
,
publicPath
)
}
catch
(
err
){
Logger
.
info
(
this
.
tag
,
`createAsset err `
+
JSON
.
stringify
(
err
))
}
}
async
queryFile
(
dataUri
:
any
)
{
...
...
validator/acts_validator/src/main/ets/pages/model/mediaPlay.ts
0 → 100644
浏览文件 @
8ea871d1
// @ts-nocheck
import
media
from
'
@ohos.multimedia.media
'
import
fs
from
'
@ohos.file.fs
'
import
Logger
from
'
./Logger
'
const
TAG
=
'
qlw play
'
export
class
mediaPlay
{
private
avPlay
:
media
.
AVPlayer
=
undefined
private
surfaceId
:
number
=
-
1
public
totalDuration
:
number
async
getFileFd
(
name
)
{
let
filesDir
=
globalThis
.
abilityContext
.
filesDir
let
path
=
filesDir
+
'
/
'
+
name
let
file
=
fs
.
openSync
(
path
)
return
file
.
fd
}
async
getRawfileFd
(
name
)
{
let
file
=
await
globalThis
.
abilityContext
.
resourceManager
.
getRawFd
(
name
)
return
file
.
fd
}
getCurrentTime
()
{
return
0
}
seek
()
{
}
async
init
(
surfaceId
?)
{
let
fd
if
(
surfaceId
)
{
this
.
surfaceId
=
surfaceId
fd
=
await
this
.
getFileFd
(
'
test.mp4
'
)
}
else
{
fd
=
await
this
.
getFileFd
(
'
test.wav
'
)
}
Logger
.
info
(
TAG
,
` fd success :
${
fd
}
`
)
this
.
avPlay
=
await
media
.
createAVPlayer
()
this
.
setCallBack
(
this
.
avPlay
)
this
.
avPlay
.
url
=
'
fd://
'
+
fd
}
async
initVideo
(
surfaceId
)
{
this
.
surfaceId
=
surfaceId
let
fd
=
await
this
.
getRawfileFd
(
'
video.mp4
'
)
Logger
.
info
(
TAG
,
` fd success :
${
fd
}
`
)
this
.
avPlay
=
await
media
.
createAVPlayer
()
this
.
setCallBack
(
this
.
avPlay
)
this
.
avPlay
.
url
=
'
fd://
'
+
fd
}
async
Play
()
{
await
this
.
avPlay
.
play
()
}
setCallBack
(
AVPlayer
)
{
AVPlayer
.
on
(
'
stateChange
'
,
async
(
state
,
reason
)
=>
{
switch
(
state
)
{
case
'
idle
'
:
Logger
.
info
(
TAG
,
'
state idle start
'
)
break
;
case
'
initialized
'
:
Logger
.
info
(
TAG
+
'
state initialized start
'
)
if
(
this
.
surfaceId
)
{
AVPlayer
.
surfaceId
=
this
.
surfaceId
}
await
AVPlayer
.
prepare
()
Logger
.
info
(
TAG
,
'
state initialized end
'
)
break
;
case
'
prepared
'
:
Logger
.
info
(
TAG
,
'
state prepared start
'
)
await
AVPlayer
.
play
()
Logger
.
info
(
TAG
,
'
state prepared end
'
)
break
;
case
'
playing
'
:
Logger
.
info
(
TAG
,
'
state playing callback
'
)
break
;
case
'
paused
'
:
Logger
.
info
(
TAG
,
'
state paused callback
'
)
break
;
case
'
completed
'
:
await
AVPlayer
.
stop
()
await
AVPlayer
.
release
()
case
'
error
'
:
Logger
.
info
(
TAG
,
'
state error callback
'
)
break
;
}
})
AVPlayer
.
on
(
'
error
'
,
(
err
)
=>
{
Logger
.
info
(
TAG
,
`state error callback err:
${
err
}
,code:
${
err
.
code
}
,message:
${
err
.
message
}
}`
)
})
}
async
release
(){
if
(
this
.
avPlay
){
await
this
.
avPlay
.
release
()
Logger
.
info
(
TAG
,
'
avplay release success
'
)
}
}
encodeWAV
(
sampleRateValue
,
sampleBitsValue
,
channelCountValue
)
{
let
sampleRate
=
sampleRateValue
;
let
dataLen
=
sampleRate
*
1000
;
let
sampleBits
=
sampleBitsValue
*
8
+
8
// 采样格式
let
channelCount
=
channelCountValue
;
// 单声道
let
offset
=
0
;
let
buffer
=
new
ArrayBuffer
(
44
);
let
data
=
new
DataView
(
buffer
);
// 资源交换文件标识符
this
.
writeString
(
data
,
offset
,
'
RIFF
'
);
offset
+=
4
;
// 下个地址开始到文件尾总字节数,即文件大小-8
data
.
setUint32
(
offset
,
36
+
dataLen
,
true
);
offset
+=
4
;
// WAV文件标志
this
.
writeString
(
data
,
offset
,
'
WAVE
'
);
offset
+=
4
;
// 波形格式标志
this
.
writeString
(
data
,
offset
,
'
fmt
'
);
offset
+=
4
;
// 过滤字节,一般为 0x10 = 16
data
.
setUint32
(
offset
,
16
,
true
);
offset
+=
4
;
// 格式类别 (PCM形式采样数据)
data
.
setUint16
(
offset
,
1
,
true
);
offset
+=
2
;
// 通道数
data
.
setUint16
(
offset
,
channelCount
,
true
);
offset
+=
2
;
// 采样率,每秒样本数,表示每个通道的播放速度
data
.
setUint32
(
offset
,
sampleRate
,
true
);
offset
+=
4
;
// 波形数据传输率 (每秒平均字节数) 单声道×每秒数据位数×每样本数据位/8
data
.
setUint32
(
offset
,
channelCount
*
sampleRate
*
(
sampleBits
/
8
),
true
);
offset
+=
4
;
// 快数据调整数 采样一次占用字节数 单声道×每样本的数据位数/8
data
.
setUint16
(
offset
,
channelCount
*
(
sampleBits
/
8
),
true
);
offset
+=
2
;
// 每样本数据位数
data
.
setUint16
(
offset
,
sampleBits
,
true
);
offset
+=
2
;
// 数据标识符
this
.
writeString
(
data
,
offset
,
'
data
'
);
offset
+=
4
;
// 采样数据总数,即数据总大小-44
data
.
setUint32
(
offset
,
dataLen
,
true
);
offset
+=
4
;
return
data
;
}
writeString
(
data
,
offset
,
str
)
{
for
(
let
i
=
0
;
i
<
str
.
length
;
i
++
)
{
data
.
setUint8
(
offset
+
i
,
str
.
charCodeAt
(
i
));
}
}
}
export
default
new
mediaPlay
()
validator/acts_validator/src/main/ets/pages/model/timeTools.ts
0 → 100644
浏览文件 @
8ea871d1
export
function
fillNum
(
num
)
{
if
(
num
<
10
)
{
return
'
0
'
+
num
}
return
num
.
toString
()
}
export
function
getTimeString
(
time
)
{
if
(
time
==
-
1
||
time
==
undefined
)
{
time
=
0
}
let
hour
=
Math
.
floor
(
time
%
(
1000
*
60
*
60
*
24
)
/
(
1000
*
60
*
60
))
let
minute
=
Math
.
floor
(
time
%
(
1000
*
60
*
60
)
/
(
1000
*
60
))
let
second
=
Math
.
floor
(
time
%
(
1000
*
60
)
/
1000
)
if
(
hour
>
0
)
{
return
`
${
fillNum
(
hour
)}
:
${
fillNum
(
minute
)}
:
${
fillNum
(
second
)}
`
}
return
`
${
fillNum
(
minute
)}
:
${
fillNum
(
second
)}
`
}
\ No newline at end of file
validator/acts_validator/src/main/resources/base/media/icon_pause.svg
0 → 100644
浏览文件 @
8ea871d1
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"24px"
height=
"24px"
viewBox=
"0 0 24 24"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
icon_pause
</title>
<defs>
<path
d=
"M19.7541071,9.806969 L8.736431,3.33971866 C7.54502607,2.64037754 6.02158251,3.05539763 5.33372456,4.26669198 C5.11509768,4.65168644 5,5.08840778 5,5.53296109 L5,18.4674618 C5,19.866144 6.11523809,21 7.490954,21 C7.92820775,21 8.35775814,20.8829809 8.736431,20.6607042 L19.7541071,14.1934539 C20.945512,13.4941127 21.3537175,11.9452367 20.6658595,10.7339423 C20.4472326,10.3489479 20.1327799,10.0292457 19.7541071,9.806969 Z"
id=
"path-1"
></path>
</defs>
<g
id=
"icon_pause"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<mask
id=
"mask-2"
fill=
"white"
>
<use
xlink:href=
"#path-1"
></use>
</mask>
<use
id=
"形状结合"
fill=
"#FFFFFF"
xlink:href=
"#path-1"
></use>
</g>
</svg>
\ No newline at end of file
validator/acts_validator/src/main/resources/base/media/icon_play.svg
0 → 100644
浏览文件 @
8ea871d1
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"24px"
height=
"24px"
viewBox=
"0 0 24 24"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
icon_play
</title>
<defs>
<path
d=
"M7.5,3.5 C8.32842712,3.5 9,4.17157288 9,5 L9,19 C9,19.8284271 8.32842712,20.5 7.5,20.5 C6.67157288,20.5 6,19.8284271 6,19 L6,5 C6,4.17157288 6.67157288,3.5 7.5,3.5 Z M16.5,3.5 C17.3284271,3.5 18,4.17157288 18,5 L18,19 C18,19.8284271 17.3284271,20.5 16.5,20.5 C15.6715729,20.5 15,19.8284271 15,19 L15,5 C15,4.17157288 15.6715729,3.5 16.5,3.5 Z"
id=
"path-1"
></path>
</defs>
<g
id=
"icon_play"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<mask
id=
"mask-2"
fill=
"white"
>
<use
xlink:href=
"#path-1"
></use>
</mask>
<use
id=
"Combined-Shape"
fill=
"#FFFFFF"
xlink:href=
"#path-1"
></use>
</g>
</svg>
\ No newline at end of file
validator/acts_validator/src/main/resources/base/profile/main_pages.json
浏览文件 @
8ea871d1
...
...
@@ -26,12 +26,21 @@
"pages/ArkUI/CanvasLineDashOffset"
,
"pages/ArkUI/CanvasShadowOffsetY"
,
"pages/Camera/Camera_index"
,
"pages/Camera/CameraFormat"
,
"pages/Camera/CameraPreviewFormat"
,
"pages/Camera/CameraPhotoFormat"
,
"pages/Camera/CameraOrientation"
,
"pages/Camera/CameraSerialPhoto"
,
"pages/Camera/CameraVideo"
,
"pages/Camera/CameraFlash"
,
"pages/Audio/Audio_index"
,
"pages/Audio/ScrollListTest"
,
"pages/Audio/AudioInputRoutingWiredHeadset"
,
"pages/Audio/AudioInputRoutingTypeC"
,
"pages/Audio/AudioOutputRoutingWiredHeadset"
,
"pages/Audio/AudioOutputRoutingTypeC"
,
"pages/Audio/AudioOutputRoutingBT"
,
"pages/Player/Player_index"
,
"pages/Player/ScrollListTest"
,
"pages/Player/PlayAudio"
,
"pages/Player/PlayVideo"
,
"pages/Experience/Experience_index"
,
"pages/Experience/PhotoFps"
,
"pages/Experience/DeskFps"
,
...
...
validator/acts_validator/src/main/resources/rawfile/H264_AAC.mkv
0 → 100644
浏览文件 @
8ea871d1
文件已添加
validator/acts_validator/src/main/resources/rawfile/StarWars10s-1C-44100-2SW.wav
0 → 100644
浏览文件 @
8ea871d1
文件已添加
validator/acts_validator/src/main/resources/rawfile/test_44100_2.wav
0 → 100644
浏览文件 @
8ea871d1
文件已添加
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录