未验证 提交 8ea871d1 编写于 作者: O openharmony_ci 提交者: Gitee

!8074 新增camera&audio&player validator用例

Merge pull request !8074 from 秦莉文/master
......@@ -10,7 +10,7 @@
"keepAlive": true,
"singleUser": true,
"minAPIVersion": 9,
"targetAPIVersion": 9,
"targetAPIVersion": 10,
"car": {
"apiCompatibleVersion": 9,
"singleUser": false
......
/*
* 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)
}
}
/*
* 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)
}
}
/*
* 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)
}
}
/*
* 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)
}
}
/*
* 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)
}
}
......@@ -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(){
......
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* Copyright (c) 2022-2023 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
......@@ -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(){
......
/*
* 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
/*
* 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
......@@ -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(){
......
/*
* 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}`);
}
}
}
/*
* 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}`);
}
}
}
/*
* 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}`);
}
}
}
/*
* 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}`);
}
}
}
/*
* 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}`);
}
}
}
/*
* 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}`);
}
}
}
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
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
......@@ -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) {
......
// @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()
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
<?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
<?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
......@@ -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",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册