提交 eaf9538d 编写于 作者: Q qinliwen

<新增camera&audio&player Validator用例>

Signed-off-by: Nqinliwen <qinliwen3@huawei.com>
上级 2c753396
......@@ -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}`);
}
}
}
/*
* 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 camera from '@ohos.multimedia.camera'
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'
const CameraMode = {
MODE_PHOTO: 0, // 拍照模式
MODE_VIDEO: 1 // 录像模式
}
//const CameraSize = {
// WIDTH: 1280,
// HEIGHT: 960
//}
const CameraSize = {
WIDTH: 4096,
HEIGHT: 3072
}
class CameraService {
private tag: string = 'qlw CameraService'
private static instance: CameraService = new CameraService()
private mediaUtil = MediaUtils.getInstance()
private cameraManager: camera.CameraManager = undefined
private cameras: Array<camera.CameraDevice> = undefined
private cameraOutputCapability: camera.CameraOutputCapability = undefined
private cameraId: string = ''
private cameraInput: camera.CameraInput = undefined
private previewOutput: camera.PreviewOutput = undefined
private photoOutPut: camera.PhotoOutput = undefined
private captureSession: camera.CaptureSession = undefined
private mReceiver: image.ImageReceiver = undefined
private photoUri: string = ''
private fileAsset: mediaLibrary.FileAsset = undefined
private fd: number = -1
private curMode = CameraMode.MODE_PHOTO
private videoRecorder: media.VideoRecorder = undefined
private videoOutput: camera.VideoOutput = undefined
private handleTakePicture: (photoUri: string) => void = undefined
private mirrorValue: boolean = false
private videoConfig: any = {
audioSourceType: 1,
videoSourceType: 0,
profile: {
audioBitrate: 48000,
audioChannels: 2,
audioCodec: 'audio/mp4v-es',
audioSampleRate: 48000,
durationTime: 1000,
fileFormat: 'mp4',
videoBitrate: 48000,
videoCodec: 'video/mp4v-es',
// videoFrameWidth: globalThis.videoSize.width,
// videoFrameHeight: globalThis.videoSize.height,
videoFrameWidth: 176,
videoFrameHeight: 144,
videoFrameRate: 30
},
url: '',
orientationHint: 0,
location: { latitude: 30, longitude: 130 },
maxSize: 10000,
maxDuration: 10000
}
constructor() {
this.mReceiver = image.createImageReceiver(CameraSize.WIDTH, CameraSize.HEIGHT, image.ImageFormat.JPEG, 8)
Logger.info(this.tag, 'createImageReceiver')
this.mReceiver.on('imageArrival', () => {
Logger.info(this.tag, 'imageArrival')
this.mReceiver.readNextImage((err, image) => {
Logger.info(this.tag, 'readNextImage')
if (err || image === undefined) {
Logger.error(this.tag, 'failed to get valid image')
return
}
image.getComponent(4, (errMsg, img) => {
Logger.info(this.tag, 'getComponent')
if (errMsg || img === undefined) {
Logger.info(this.tag, 'failed to get valid buffer')
return
}
let buffer
if (img.byteBuffer) {
buffer = img.byteBuffer
} else {
Logger.error(this.tag, 'img.byteBuffer is undefined')
}
this.savePicture(buffer, image)
})
})
})
}
async savePicture(buffer: ArrayBuffer, img: image.Image) {
Logger.info(this.tag, 'savePicture')
this.fileAsset = await this.mediaUtil.createAndGetUri(mediaLibrary.MediaType.IMAGE)
this.photoUri = this.fileAsset.uri
Logger.info(this.tag, `this.photoUri = ${this.photoUri}`)
this.fd = await this.mediaUtil.getFdPath(this.fileAsset)
Logger.info(this.tag, `this.fd = ${this.fd}`)
await fileio.write(this.fd, buffer)
await this.fileAsset.close(this.fd)
await img.release()
Logger.info(this.tag, 'save image done')
if (this.handleTakePicture) {
this.handleTakePicture(this.photoUri)
}
}
async initCamera(surfaceId: number, cameraDeviceIndex: number) {
try{
Logger.info(this.tag, 'initCamera')
if (this.curMode === CameraMode.MODE_VIDEO) {
await this.releaseCamera()
}
if (this.curMode === CameraMode.MODE_PHOTO) {
await this.releasePhotoCamera()
}
Logger.info(this.tag, `deviceInfo.deviceType = ${deviceInfo.deviceType}`)
if (deviceInfo.deviceType === 'default') {
this.videoConfig.videoSourceType = 1
} else {
this.videoConfig.videoSourceType = 0
}
this.cameraManager = await camera.getCameraManager(globalThis.abilityContext)
Logger.info(this.tag, 'getCameraManager')
this.cameras = await this.cameraManager.getSupportedCameras()
Logger.info(this.tag, `get cameras ${this.cameras.length}`)
if (this.cameras.length === 0) {
Logger.info(this.tag, 'cannot get cameras')
return
}
this.cameraInput = await this.cameraManager.createCameraInput(this.cameras[cameraDeviceIndex])
await this.cameraInput.open((err) => {
if(err){
Logger.info(this.tag, `cameraInput open Failed : ${err}`)
return
}
Logger.info(this.tag, `cameraInput open success`)
})
Logger.info(this.tag, 'createCameraInput')
this.cameraOutputCapability = await this.cameraManager.getSupportedOutputCapability(this.cameras[cameraDeviceIndex])
Logger.info(this.tag, 'cameraOutputCapability: ' + JSON.stringify(this.cameraOutputCapability))
Logger.info(this.tag, 'cameraOutputCapability previewProfiles: ' + JSON.stringify(this.cameraOutputCapability.previewProfiles))
Logger.info(this.tag, 'cameraOutputCapability photoProfiles: ' + JSON.stringify(this.cameraOutputCapability.photoProfiles))
Logger.info(this.tag, 'cameraOutputCapability videoProfiles: ' + JSON.stringify(this.cameraOutputCapability.videoProfiles))
this.previewOutput = await this.cameraManager.createPreviewOutput(this.cameraOutputCapability.previewProfiles[0], surfaceId.toString())
Logger.info(this.tag, 'createPreviewOutput')
let mSurfaceId = await this.mReceiver.getReceivingSurfaceId()
this.photoOutPut = await this.cameraManager.createPhotoOutput(this.cameraOutputCapability.photoProfiles[0], (mSurfaceId))
Logger.info(this.tag, 'createPhotoOutput')
this.captureSession = await this.cameraManager.createCaptureSession()
Logger.info(this.tag, 'createCaptureSession')
await this.captureSession.beginConfig()
Logger.info(this.tag, 'beginConfig')
await this.captureSession.addInput(this.cameraInput)
await this.captureSession.addOutput(this.previewOutput)
await this.captureSession.addOutput(this.photoOutPut)
await this.captureSession.commitConfig()
await this.captureSession.start()
Logger.info(this.tag, 'captureSession start')
}catch(err){
Logger.info(this.tag, 'initCamera err: ' + err)
}
}
setTakePictureCallback(callback) {
this.handleTakePicture = callback
}
async takePicture(rotationValue, qualityLevel) {
Logger.info(this.tag, 'takePicture')
if (this.curMode === CameraMode.MODE_VIDEO) {
this.curMode = CameraMode.MODE_PHOTO
}
// if(this.photoOutPut.isMirrorSupported()){
// this.mirrorValue = true
// }
let photoSettings = {
rotation: rotationValue,
quality: qualityLevel,
location: { // 位置信息,经纬度
latitude: 0,
longitude: 0,
altitude: 1000
},
mirror: this.mirrorValue
}
Logger.info(this.tag, JSON.stringify(photoSettings))
try{
await this.photoOutPut.capture(photoSettings)
}catch(err){
Logger.info(this.tag, `takePicture err ${err.message}`)
}
Logger.info(this.tag, 'takePicture done')
}
async startVideo() {
try{
Logger.info(this.tag, 'startVideo begin')
await this.captureSession.stop()
await this.captureSession.beginConfig()
Logger.info(this.tag, 'beginConfig')
if (this.curMode === CameraMode.MODE_PHOTO) {
this.curMode = CameraMode.MODE_VIDEO
if (this.photoOutPut) {
await this.captureSession.removeOutput(this.photoOutPut)
}
} else {
if (this.videoOutput) {
await this.captureSession.removeOutput(this.videoOutput)
}
}
}catch(err){
Logger.info(this.tag, 'startVideo err1: ' + err)
}
this.fileAsset = await this.mediaUtil.createAndGetUri(mediaLibrary.MediaType.VIDEO)
this.fd = await this.mediaUtil.getFdPath(this.fileAsset)
this.videoRecorder = await media.createVideoRecorder()
this.videoConfig.url = `fd://${this.fd}`
await this.videoRecorder.prepare(this.videoConfig)
let videoId = await this.videoRecorder.getInputSurface()
Logger.info(this.tag, `cameraOutputCapability.videoProfiles ${this.cameraOutputCapability.videoProfiles.length}`)
// let index = 0
// this.videoOutput = await this.cameraManager.createVideoOutput(this.cameraOutputCapability.videoProfiles[index], videoId)
// @ts-ignore
let videoProfilesObj: camera.VideoProfile = {
"format": 1003,
"size":{
"width": 176,
"height": 144
},
"frameRateRange":{
"min": -1,
"max": 0
}
}
try{
this.videoOutput = await this.cameraManager.createVideoOutput(videoProfilesObj, videoId)
await this.captureSession.addOutput(this.videoOutput)
await this.captureSession.commitConfig()
Logger.info(this.tag, 'captureSession commitConfig')
await this.captureSession.start()
Logger.info(this.tag, 'captureSession start')
await this.videoOutput.start()
Logger.info(this.tag, 'videoOutput start')
await this.videoRecorder.start()
Logger.info(this.tag, 'videoRecorder start')
}catch(err){
Logger.info(this.tag, 'startVideo err2: ' + err)
}
}
async stopVideo() {
Logger.info(this.tag, 'stopVideo called')
await this.videoRecorder.stop()
await this.videoRecorder.release()
await this.videoOutput.stop()
await this.fileAsset.close(this.fd)
}
async releaseCamera() {
Logger.info(this.tag, 'releaseCamera')
if (this.cameraInput) {
// @ts-ignore
await this.cameraInput.release()
}
if (this.previewOutput) {
await this.previewOutput.release()
}
if (this.photoOutPut) {
await this.photoOutPut.release()
}
if (this.videoOutput) {
await this.videoOutput.release()
}
if (this.captureSession) {
await this.captureSession.release()
}
}
async releasePhotoCamera() {
Logger.info(this.tag, 'releaseCamera')
if (this.cameraInput) {
// @ts-ignore
await this.cameraInput.release()
}
if (this.previewOutput) {
await this.previewOutput.release()
}
if (this.photoOutPut) {
await this.photoOutPut.release()
}
if (this.captureSession) {
await this.captureSession.release()
}
}
}
export default new CameraService()
\ 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.
*/
/**
* @file 日期工具
*/
export default class DateTimeUtil {
/**
* 时分秒
*/
getTime() {
const DATETIME = new Date()
return this.concatTime(DATETIME.getHours(), DATETIME.getMinutes(), DATETIME.getSeconds())
}
getHour() {
const DATETIME = new Date()
return DATETIME.getHours()
}
getMinute() {
const DATETIME = new Date()
return DATETIME.getMinutes()
}
getSecond() {
const DATETIME = new Date()
return DATETIME.getSeconds()
}
/**
* 年月日
*/
getDate() {
const DATETIME = new Date()
return this.concatDate(DATETIME.getFullYear(), DATETIME.getMonth() + 1, DATETIME.getDate())
}
getFullYear() {
const DATETIME = new Date()
return DATETIME.getFullYear()
}
getMonth() {
const DATETIME = new Date()
return DATETIME.getMonth() + 1
}
getDay() {
const DATETIME = new Date()
return DATETIME.getDate()
}
/**
* 日期不足两位补充0
* @param value-数据值
*/
fill(value: number) {
return (value > 9 ? '' : '0') + value
}
/**
* 年月日格式修饰
* @param year
* @param month
* @param date
*/
concatDate(year: number, month: number, date: number) {
return `${year}${this.fill(month)}${this.fill(date)}`
}
/**
* 时分秒格式修饰
* @param hours
* @param minutes
* @param seconds
*/
concatTime(hours: number, minutes: number, seconds: number) {
return `${this.fill(hours)}${this.fill(minutes)}${this.fill(seconds)}`
}
}
\ 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 hilog from '@ohos.hilog';
class Logger {
private domain: number;
private prefix: string;
private format: string = "%{public}s, %{public}s";
constructor(prefix: string) {
this.prefix = prefix;
this.domain = 0xFF00;
}
debug(...args: any[]) {
hilog.debug(this.domain, this.prefix, this.format, args);
}
info(...args: any[]) {
hilog.info(this.domain, this.prefix, this.format, args);
}
warn(...args: any[]) {
hilog.warn(this.domain, this.prefix, this.format, args);
}
error(...args: any[]) {
hilog.error(this.domain, this.prefix, this.format, args);
}
}
export default new Logger('[Screenshot]');
\ 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 mediaLibrary from '@ohos.multimedia.mediaLibrary'
import DateTimeUtil from '../model/DateTimeUtil'
import Logger from './Logger'
export default class MediaUtils {
private tag: string = 'qlw MediaUtils'
private mediaTest: mediaLibrary.MediaLibrary = mediaLibrary.getMediaLibrary(globalThis.abilityContext)
private static instance: MediaUtils = new MediaUtils()
public static getInstance() {
if (this.instance === undefined) {
this.instance = new MediaUtils()
}
return this.instance
}
async createAndGetUri(mediaType: number) {
let info = this.getInfoFromType(mediaType)
let dateTimeUtil = new DateTimeUtil()
let name = `${dateTimeUtil.getDate()}_${dateTimeUtil.getTime()}`
let displayName = `${info.prefix}${name}${info.suffix}`
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)
}
async queryFile(dataUri: any) {
let fileKeyObj = mediaLibrary.FileKey
if (dataUri !== undefined) {
let args = dataUri.id.toString()
let fetchOp = {
selections: `${fileKeyObj.ID}=?`,
selectionArgs: [args],
}
const fetchFileResult = await this.mediaTest.getFileAssets(fetchOp)
Logger.info(this.tag, `fetchFileResult.getCount() = ${fetchFileResult.getCount()}`)
const fileAsset = await fetchFileResult.getAllObject()
return fileAsset[0]
}
}
async getFdPath(fileAsset: any) {
let fd = await fileAsset.open('Rw')
Logger.info(this.tag, `fd = ${fd}`)
return fd
}
async createFile(mediaType: number) {
let dataUri = await this.createAndGetUri(mediaType)
if (dataUri) {
let fileAsset = await this.queryFile(dataUri)
if (fileAsset) {
let fd = await this.getFdPath(fileAsset)
return fd
}
}
}
async getFileAssetsFromType(mediaType: number) {
Logger.info(this.tag, `getFileAssetsFromType,mediaType = ${mediaType}`)
let fileKeyObj = mediaLibrary.FileKey
let fetchOp = {
selections: `${fileKeyObj.MEDIA_TYPE}=?`,
selectionArgs: [`${mediaType}`],
}
const fetchFileResult = await this.mediaTest.getFileAssets(fetchOp)
Logger.info(this.tag, `getFileAssetsFromType,fetchFileResult.count = ${fetchFileResult.getCount()}`)
let fileAssets = []
if (fetchFileResult.getCount() > 0) {
fileAssets = await fetchFileResult.getAllObject()
}
return fileAssets
}
async getAlbums() {
Logger.info(this.tag, 'getAlbums begin')
let albums = []
const [ files, images, videos, audios ] = await Promise.all([
this.getFileAssetsFromType(mediaLibrary.MediaType.FILE),
this.getFileAssetsFromType(mediaLibrary.MediaType.IMAGE),
this.getFileAssetsFromType(mediaLibrary.MediaType.VIDEO),
this.getFileAssetsFromType(mediaLibrary.MediaType.AUDIO)
])
albums.push({
albumName: 'Documents', count: files.length, mediaType: mediaLibrary.MediaType.FILE
})
albums.push({
albumName: 'Pictures', count: images.length, mediaType: mediaLibrary.MediaType.IMAGE
})
albums.push({
albumName: 'Videos', count: videos.length, mediaType: mediaLibrary.MediaType.VIDEO
})
albums.push({
albumName: 'Audios', count: audios.length, mediaType: mediaLibrary.MediaType.AUDIO
})
return albums
}
deleteFile(media: any) {
let uri = media.uri
Logger.info(this.tag, `deleteFile,uri = ${uri}`)
return this.mediaTest.deleteAsset(uri)
}
onDateChange(callback: () => void) {
this.mediaTest.on('albumChange', () => {
Logger.info(this.tag, 'albumChange called')
callback()
})
this.mediaTest.on('imageChange', () => {
Logger.info(this.tag, 'imageChange called')
callback()
})
this.mediaTest.on('audioChange', () => {
Logger.info(this.tag, 'audioChange called')
callback()
})
this.mediaTest.on('videoChange', () => {
Logger.info(this.tag, 'videoChange called')
callback()
})
this.mediaTest.on('fileChange', () => {
Logger.info(this.tag, 'fileChange called')
callback()
})
}
offDateChange() {
this.mediaTest.off('albumChange')
this.mediaTest.off('imageChange')
this.mediaTest.off('audioChange')
this.mediaTest.off('videoChange')
this.mediaTest.off('fileChange')
}
getInfoFromType(mediaType: number) {
let result = {
prefix: '', suffix: '', directory: 0
}
switch (mediaType) {
case mediaLibrary.MediaType.FILE:
result.prefix = 'FILE_'
result.suffix = '.txt'
result.directory = mediaLibrary.DirectoryType.DIR_DOCUMENTS
break
case mediaLibrary.MediaType.IMAGE:
result.prefix = 'IMG_'
result.suffix = '.jpg'
result.directory = mediaLibrary.DirectoryType.DIR_IMAGE
break
case mediaLibrary.MediaType.VIDEO:
result.prefix = 'VID_'
result.suffix = '.mp4'
result.directory = mediaLibrary.DirectoryType.DIR_VIDEO
break
case mediaLibrary.MediaType.AUDIO:
result.prefix = 'AUD_'
result.suffix = '.wav'
result.directory = mediaLibrary.DirectoryType.DIR_AUDIO
break
}
return result
}
}
\ 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 media from '@ohos.multimedia.media'
import Logger from '../model/Logger'
let audioConfig = {
audioSourceType: 1,
audioEncoder: 3,
audioEncodeBitRate: 22050,
audioSampleRate: 22050,
numberOfChannels: 2,
format: 6,
uri: ''
}
export default class RecordModel {
private tag: string = 'qlw RecordModel'
private audioRecorder: media.AudioRecorder = undefined
initAudioRecorder(handleStateChange: () => void) {
this.release();
this.audioRecorder = media.createAudioRecorder()
Logger.info(this.tag, 'create audioRecorder success')
this.audioRecorder.on('prepare', () => {
Logger.info(this.tag, 'setCallback prepare case callback is called')
this.audioRecorder.start()
})
this.audioRecorder.on('start', () => {
Logger.info(this.tag, 'setCallback start case callback is called')
handleStateChange()
})
this.audioRecorder.on('stop', () => {
Logger.info(this.tag, 'audioRecorder stop called')
this.audioRecorder.release()
})
this.audioRecorder.on('pause', () => {
Logger.info(this.tag, 'audioRecorder pause finish')
handleStateChange()
})
this.audioRecorder.on('resume', () => {
Logger.info(this.tag, 'audioRecorder resume finish')
handleStateChange()
})
}
release() {
if (typeof (this.audioRecorder) !== `undefined`) {
Logger.info(this.tag, 'audioRecorder release')
this.audioRecorder.release()
this.audioRecorder = undefined
}
}
startRecorder(pathName: string) {
Logger.info(this.tag, `startRecorder, pathName = ${pathName}`)
if (typeof (this.audioRecorder) !== 'undefined') {
Logger.info(this.tag, 'start prepare')
audioConfig.uri = pathName
this.audioRecorder.prepare(audioConfig)
} else {
Logger.error(this.tag, 'case failed, audioRecorder is null')
}
}
pause() {
Logger.info(this.tag, 'audioRecorder pause called')
if (typeof (this.audioRecorder) !== `undefined`) {
this.audioRecorder.pause()
}
}
resume() {
Logger.info(this.tag, 'audioRecorder resume called')
if (typeof (this.audioRecorder) !== `undefined`) {
this.audioRecorder.resume()
}
}
finish() {
if (typeof (this.audioRecorder) !== `undefined`) {
this.audioRecorder.stop()
}
}
}
\ 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.
先完成此消息的编辑!
想要评论请 注册