回复
Harmony Next 和 OpenHarmony 获取相机预览的刷新率、fps 原创
msdone
发布于 2024-11-18 18:33
浏览
0收藏
@toc
概述
已在 Harmony Next 和 OpenHarmony 5.0+ 上测试通过
其中 399 行可以测试计算真实性(需要 API12)
源码采用 openharmony 社区相机代码,https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Media/Camera,由于在 Harmony Next 上测试,社区源码语法适配修改较多,所以删减了一些功能,专注于计算相机的分辨率,且这里只贴出修改最大(最核心)的两个文件:
- entry/src/main/ets/pages/Camera.ets
- entry/src/main/ets/model/CameraModel.ts
效果
光线正常
光线较暗
支持的fps范围
代码
CameraModel.ts
import camera from '@ohos.multimedia.camera';
import deviceInfo from '@ohos.deviceInfo';
import fileIo from '@ohos.file.fs';
import image from '@ohos.multimedia.image';
import media from '@ohos.multimedia.media';
import photoAccessHelper from '@ohos.file.photoAccessHelper';
import Logger from '../utlis/Logger';
import MediaModel from './MediaModel';
import prompt from '@ohos.prompt';
import { BusinessError } from '@ohos.base';
const FOUR = 4; // format
const EIGHT = 8; // capacity
const FOUR_THOUSAND_AND_SIXTY_NINE = 4096; // buffer大小
const cameraMode = {
modePhoto: 0, // 拍照模式
modeVideo: 1, // 录像模式
};
const cameraWH = {
width: 2560,
height: 1440,
};
/**
* 分辨率
*/
export enum VideoFrame {
VIDEOFRAME_1920_1080,
VIDEOFRAME_1280_720,
VIDEOFRAME_800_600,
};
type VideoFrameWH = {
width: number;
height: number;
};
const TAG = '[CameraModel]';
export default class CameraService {
private mediaModel: MediaModel = undefined;
private fileAsset: photoAccessHelper.PhotoAsset | undefined = undefined;
private cameraMgr: camera.CameraManager = undefined;
private camerasArray: Array<camera.CameraDevice> = undefined;
private cameraInput: camera.CameraInput = undefined;
private previewOutput: camera.PreviewOutput = undefined;
private capSession: camera.Session = undefined;
// private capSession: camera.PhotoSession = undefined;
private videoOutput: camera.VideoOutput = undefined;
private capability: camera.CameraOutputCapability = undefined;
private avRecorder: media.AVRecorder = undefined;
private receiver: image.ImageReceiver = undefined;
private photoPath: string = '';
private fd: number = -1;
private takePictureHandle: (photoUri: string) => void = undefined;
private currentMode:number = cameraMode.modePhoto;
private frame_times: number[] = [];
private last_time: number = 0;
private sum: number = 0;
private isListen: boolean = false;
private round(value: number, decimals: number): number {
const factor = Math.pow(10, decimals);
return Math.round(value * factor) / factor;
}
private fps: number = 0;
private videoFrameWH: VideoFrameWH = {
// width: 480,
// height: 360,
width: 2560,
height: 1440,
}; // 视频分辨率
private imageRotation: camera.ImageRotation = camera.ImageRotation.ROTATION_0; // 图片旋转角度
private videoProfile: media.AVRecorderProfile = {
audioChannels: 2,
audioCodec: media.CodecMimeType.AUDIO_AAC,
audioBitrate: 48000,
audioSampleRate: 48000,
fileFormat: media.ContainerFormatType.CFT_MPEG_4,
videoBitrate: 48000,
videoCodec: media.CodecMimeType.VIDEO_AVC,
videoFrameWidth: 2560,
videoFrameHeight: 1440,
videoFrameRate: 30,
};
private videoSourceType: number = 0;
callback: (fps: number) => void;
setCallback(callback: (fps: number) => void) {
this.callback = callback;
}
listenFPS() {
if (this.isListen) {
return;
}
this.isListen = true;
this.receiver.on('imageArrival', () => {
Logger.info(TAG, 'imageArrival');
this.receiver?.readNextImage((err: BusinessError, nextImage: image.Image) => {
if (err || nextImage === undefined || this.isListen === false) {
return;
}
nextImage.getComponent(image.ComponentType.JPEG, async (err: BusinessError, imgComponent: image.Component) => {
if (err || imgComponent === undefined) {
return;
}
console.log(TAG + `20241115 FPS LOG ==> buffer success`);
try {
if (this.last_time === 0) {
this.last_time = Date.now(); // ms
return;
}
let current_time = Date.now();
console.log('20241115 FPS LOG ====> current_time:', current_time);
let frame_time = current_time - this.last_time;
console.log('20241115 FPS LOG ====> frame_time:', frame_time);
this.last_time = current_time;
console.log('20241115 FPS LOG ====> last_time:', this.last_time);
if (frame_time > 0 && frame_time < 1000) { // 添加合理性检查,帧时间应该在 0-1000ms 之间
this.frame_times.push(frame_time);
console.log('20241115 FPS LOG ====> frame_times:', this.frame_times);
if (this.frame_times.length > 60) {
this.sum -= this.frame_times.shift()!;
this.sum += frame_time;
} else {
this.sum += frame_time;
}
console.log('20241115 FPS LOG ====> sum:', this.sum);
let avg_frame_time = this.sum / this.frame_times.length;
console.log('20241115 FPS LOG ====> avg_frame_time:', avg_frame_time);
let fps = 1000.0 / avg_frame_time; // 秒转换为毫秒并计算 FPS
console.log('20241115 FPS LOG ====> fps:', fps);
this.fps = this.round(fps, 1);
console.log('20241115 FPS LOG ====> fps:', this.fps);
this.callback(this.fps);
}
nextImage.release();
console.log(TAG + `20241115 FPS LOG ==> release successfully`);
} catch (e) {
console.log(TAG + `20241115 FPS LOG ==> release error: ${JSON.stringify(e)}`);
}
})
})
});
Logger.info(TAG, 'imageArrival END');
}
unlistenFPS() {
this.isListen = false;
this.frame_times = [];
this.fps = 0;
this.last_time = 0;
this.sum = 0;
}
constructor() {
this.mediaModel = MediaModel.getMediaInstance();
this.receiver = image.createImageReceiver(
cameraWH.width,
cameraWH.height,
FOUR,
EIGHT
//
// image.ImageFormat.JPEG,
// 1
);
Logger.info(TAG, 'imageArrival: receiver:' + JSON.stringify(this.receiver));
if (!this.receiver) {
Logger.error(TAG, 'imageArrival: failed to create receiver');
}
this.listenFPS();
// this.receiver.on('imageArrival', () => {
// Logger.info(TAG, 'imageArrival');
// this.receiver?.readNextImage((err: BusinessError, nextImage: image.Image) => {
// if (err || nextImage === undefined || this.isListen === false) {
// return;
// }
//
// nextImage.getComponent(image.ComponentType.JPEG, async (err: BusinessError, imgComponent: image.Component) => {
// if (err || imgComponent === undefined) {
// return;
// }
// console.log(TAG + `20241115 FPS LOG ==> buffer success`);
// try {
// if (this.last_time === 0) {
// this.last_time = Date.now(); // ms
// return;
// }
// let current_time = Date.now();
// console.log('20241115 FPS LOG ====> current_time:', current_time);
// let frame_time = current_time - this.last_time;
// console.log('20241115 FPS LOG ====> frame_time:', frame_time);
// this.last_time = current_time;
// console.log('20241115 FPS LOG ====> last_time:', this.last_time);
//
// if (frame_time > 0 && frame_time < 1000) { // 添加合理性检查,帧时间应该在 0-1000ms 之间
// this.frame_times.push(frame_time);
// console.log('20241115 FPS LOG ====> frame_times:', this.frame_times);
// if (this.frame_times.length > 60) {
// this.sum -= this.frame_times.shift()!;
// this.sum += frame_time;
// } else {
// this.sum += frame_time;
// }
// console.log('20241115 FPS LOG ====> sum:', this.sum);
// let avg_frame_time = this.sum / this.frame_times.length;
// console.log('20241115 FPS LOG ====> avg_frame_time:', avg_frame_time);
// let fps = 1000.0 / avg_frame_time; // 秒转换为毫秒并计算 FPS
// console.log('20241115 FPS LOG ====> fps:', fps);
// this.fps = this.round(fps, 1);
// console.log('20241115 FPS LOG ====> fps:', this.fps);
// this.callback(this.fps);
// }
// nextImage.release();
// console.log(TAG + `20241115 FPS LOG ==> release successfully`);
// } catch (e) {
// console.log(TAG + `20241115 FPS LOG ==> release error: ${JSON.stringify(e)}`);
// }
// })
// })
// });
// Logger.info(TAG, 'imageArrival END');
}
/**
* 设置分辨率
* @param videoFrame
*/
setVideoFrameWH(videoFrame: VideoFrame): void {
switch (videoFrame) {
case VideoFrame.VIDEOFRAME_800_600:
this.videoFrameWH = {
// width: 800,
// height: 600,
width: 2560,
height: 1440,
};
Logger.info(
TAG,
`setVideoFrameWH videoFrameWH:${JSON.stringify(this.videoFrameWH)}`
);
break;
case VideoFrame.VIDEOFRAME_1280_720:
this.videoFrameWH = {
// width: 1280,
// height: 720,
width: 2560,
height: 1440,
};
Logger.info(
TAG,
`setVideoFrameWH videoFrameWH:${JSON.stringify(this.videoFrameWH)}`
);
break;
case VideoFrame.VIDEOFRAME_1920_1080:
this.videoFrameWH = {
// width: 1920,
// height: 1080,
width: 2560,
height: 1440,
};
Logger.info(
TAG,
`setVideoFrameWH videoFrameWH:${JSON.stringify(this.videoFrameWH)}`
);
break;
}
}
/**
* 设置图片旋转角度
* @param imageRotation
*/
setImageRotation(imageRotation: camera.ImageRotation): void {
this.imageRotation = imageRotation;
}
/**
* 保存图片
* @param buffer
* @param img
*/
async saveImage(buffer: ArrayBuffer, img: image.Image): Promise<void> {
// Logger.info(TAG, 'savePicture');
// this.fileAsset = await this.mediaModel.createAndGetUri(photoAccessHelper.PhotoType.IMAGE);
// this.photoPath = this.fileAsset.uri;
// Logger.info(TAG, `this.photoUri = ${this.photoPath}`);
// this.fd = await this.mediaModel.getFdPath(this.fileAsset);
// Logger.info(TAG, `this.fd = ${this.fd}`);
// await fileIo.write(this.fd, buffer);
// await this.fileAsset.close(this.fd);
// await img.release();
// Logger.info(TAG, 'save image done');
// if (this.takePictureHandle) {
// this.takePictureHandle(this.photoPath);
// }
}
/**
* 初始化相机
* @param surfaceId
*/
async initCamera(surfaceId: string): Promise<void> {
Logger.info(TAG, `initCamera surfaceId:${surfaceId}`);
await this.cameraRelease();
Logger.info(TAG, `deviceInfo.deviceType = ${deviceInfo.deviceType}`);
if (deviceInfo.deviceType === 'default') {
Logger.info(TAG, `deviceInfo.deviceType default 1 = ${deviceInfo.deviceType}`);
this.videoSourceType = 1;
Logger.info(TAG, `deviceInfo.deviceType default 2 = ${deviceInfo.deviceType}`);
} else {
Logger.info(TAG, `deviceInfo.deviceType other 1 = ${deviceInfo.deviceType}`);
this.videoSourceType = 0;
Logger.info(TAG, `deviceInfo.deviceType other 2 = ${deviceInfo.deviceType}`);
}
Logger.info(TAG, 'getCameraManager begin');
try {
Logger.info(TAG, 'getCameraManager try begin');
this.cameraMgr = camera.getCameraManager(globalThis.cameraContext);
Logger.info(TAG, 'getCameraManager try end');
} catch (e) {
Logger.info(TAG, `getCameraManager catch e:${JSON.stringify(e)}`);
Logger.info(TAG, `getCameraManager catch code:${JSON.stringify(e.code)}`);
Logger.info(TAG, `getCameraManager catch message:${JSON.stringify(e.message)}`);
}
Logger.info(TAG, 'getCameraManager end');
Logger.info(TAG, `getCameraManager ${JSON.stringify(this.cameraMgr)}`);
this.camerasArray = this.cameraMgr.getSupportedCameras();
Logger.info(TAG, `get cameras: ${JSON.stringify(this.camerasArray)}`);
if (this.camerasArray.length === 0) {
Logger.info(TAG, 'cannot get cameras');
return;
}
let mCamera = this.camerasArray.find((cameraDevice) => cameraDevice.cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK);
// let sceneModes = this.cameraMgr.getSupportedSceneModes(mCamera);
// Logger.info(TAG, 'SupportedSceneModes: ' + JSON.stringify(sceneModes));
// Logger.info(TAG, 'isTorchSupported: ' + this.cameraMgr.isTorchSupported());
// Logger.info(TAG, 'isTorchModeSupported(camera.TorchMode.ON): ' + this.cameraMgr.isTorchModeSupported(camera.TorchMode.ON));
// Logger.info(TAG, 'isTorchModeSupported(camera.TorchMode.OFF): ' + this.cameraMgr.isTorchModeSupported(camera.TorchMode.OFF));
// Logger.info(TAG, 'isTorchModeSupported(camera.TorchMode.AUTO): ' + this.cameraMgr.isTorchModeSupported(camera.TorchMode.AUTO));
// try {
// this.cameraMgr.setTorchMode(camera.TorchMode.ON);
// } catch(e) {
// Logger.error(TAG, 'setTorchMode error: ' + JSON.stringify(e));
// }
this.cameraInput = this.cameraMgr.createCameraInput(mCamera);
this.cameraInput.open();
Logger.info(TAG, 'createCameraInput');
this.capability = this.cameraMgr.getSupportedOutputCapability(mCamera, camera.SceneMode.NORMAL_PHOTO);
Logger.info(TAG, 'SupportedOutputCapability: ' + JSON.stringify(this.capability.previewProfiles));
let previewProfile = this.capability.previewProfiles[19];
let previewProfile2 = this.capability?.previewProfiles[19];
this.previewOutput = this.cameraMgr.createPreviewOutput(
previewProfile,
surfaceId
);
let imageReceiveSurfaceId: string = await this.receiver?.getReceivingSurfaceId() ?? "";
Logger.info("imageArrival: imageReceiveSurfaceId: " + imageReceiveSurfaceId);
let previewOutput2 = this.cameraMgr?.createPreviewOutput(previewProfile2, imageReceiveSurfaceId);
Logger.info(TAG, 'createPreviewOutput, previewProfile: ' + JSON.stringify(previewProfile) + 'previewOutput: ' + JSON.stringify(this.previewOutput));
this.capSession = this.cameraMgr.createSession(camera.SceneMode.NORMAL_PHOTO);
Logger.info(TAG, 'createCaptureSession');
this.capSession.beginConfig();
Logger.info(TAG, 'beginConfig');
this.capSession.addInput(this.cameraInput);
this.capSession.addOutput(this.previewOutput);
this.capSession.addOutput(previewOutput2);
await this.capSession.commitConfig();
await this.capSession.start();
let cameraSupportedFrameRatesArray = this.previewOutput.getSupportedFrameRates();
let imageReceiverSupportedFrameRatesArray = previewOutput2.getSupportedFrameRates();
Logger.info(TAG, 'cameraSupportedFrameRatesArray: ' + JSON.stringify(cameraSupportedFrameRatesArray) + ', imageReceiverSupportedFrameRatesArray: ' + JSON.stringify(imageReceiverSupportedFrameRatesArray));
try {
this.previewOutput.setFrameRate(13, 30);
Logger.info(TAG, "setPreviewFrameRate success");
} catch (e) {
Logger.error(TAG, "setPreviewFrameRate failed: " + JSON.stringify(e));
}
Logger.info(TAG, 'captureSession start');
}
setTakePictureHandleCallback(callback): void {
this.takePictureHandle = callback;
}
/**
* 拍照
*/
async takePicture(): Promise<void> {
Logger.info(TAG, 'takePicture');
if (this.currentMode === cameraMode.modeVideo) {
this.currentMode = cameraMode.modePhoto;
}
Logger.info(TAG, `takePicture imageRotation:${this.imageRotation}`);
let photoSettings = {
rotation: this.imageRotation,
quality: camera.QualityLevel.QUALITY_LEVEL_MEDIUM,
location: {
// 位置信息,经纬度
latitude: 12.9698,
longitude: 77.75,
altitude: 1000,
},
mirror: false,
};
Logger.info(TAG, 'takePicture done');
}
/**
* 开始录像
*/
async startVideo(): Promise<void> {
// Logger.info(TAG, 'startVideo begin');
// Logger.info(TAG, 'startVideo 1');
// await this.capSession.stop();
// Logger.info(TAG, 'startVideo 2');
// this.capSession.beginConfig();
// Logger.info(TAG, 'startVideo 3');
// if (this.currentMode === cameraMode.modePhoto) {
// this.currentMode = cameraMode.modeVideo;
// if (this.photoOutPut) {
// this.capSession.removeOutput(this.photoOutPut);
// this.photoOutPut.release();
// }
// } else {
// if (this.videoOutput) {
// try {
// Logger.info(TAG, 'startVideo 4');
// this.capSession.removeOutput(this.videoOutput);
// Logger.info(TAG, 'startVideo 5');
// } catch (e) {
// Logger.info(TAG, `startVideo catch e:${JSON.stringify(e)}`);
// Logger.info(TAG, `startVideo catch code:${JSON.stringify(e.code)}`);
// Logger.info(TAG, `startVideo catch message:${JSON.stringify(e.message)}`);
// }
// }
// }
// if (this.videoOutput) {
// try {
// Logger.info(TAG, 'startVideo 6');
// this.capSession.removeOutput(this.videoOutput);
// Logger.info(TAG, 'startVideo 7');
// } catch (e) {
// Logger.info(TAG, `startVideo catch e:${JSON.stringify(e)}`);
// Logger.info(TAG, `startVideo catch code:${JSON.stringify(e.code)}`);
// Logger.info(TAG, `startVideo catch message:${JSON.stringify(e.message)}`);
// }
// try {
// Logger.info(TAG, 'startVideo release 1');
// await this.videoOutput.release();
// Logger.info(TAG, 'startVideo release 2');
// } catch (e) {
// Logger.info(TAG, `startVideo catch e:${JSON.stringify(e)}`);
// Logger.info(TAG, `startVideo catch code:${JSON.stringify(e.code)}`);
// Logger.info(TAG, `startVideo catch message:${JSON.stringify(e.message)}`);
// }
// }
// Logger.info(TAG, 'startVideo 8');
// this.fileAsset = await this.mediaModel.createAndGetUri(photoAccessHelper.PhotoType.VIDEO);
// Logger.info(TAG, `startVideo fileAsset:${this.fileAsset}`);
// this.fd = await this.mediaModel.getFdPath(this.fileAsset);
// Logger.info(TAG, `startVideo fd:${this.fd}`);
// media.createAVRecorder(async (error, recorder) => {
// Logger.info(TAG, `startVideo into createAVRecorder:${recorder}`);
// if (recorder != null) {
// Logger.info(TAG, `startVideo into recorder:${recorder}`);
// this.avRecorder = recorder;
// Logger.info(TAG, `startVideo createAVRecorder success:${this.avRecorder}`);
// // 当前录像配置
// let currConfig = {
// audioSourceType: 1,
// videoSourceType: this.videoSourceType,
// profile: this.videoProfile,
// url: `fd://${this.fd}`,
// rotation: 0
// };
// Logger.info(TAG, `startVideo into recorder:${recorder}`);
// await this.avRecorder.prepare(currConfig);
// Logger.info(TAG, `startVideo videoConfig:${JSON.stringify(currConfig)}`);
// let videoId = await this.avRecorder.getInputSurface();
// let videoProfile = this.capability.videoProfiles[0];
// Logger.info(TAG, `startVideo capability.videoProfiles[]=: ${JSON.stringify(this.capability.videoProfiles)}`);
// Logger.info(TAG, `startVideo videoProfile:${JSON.stringify(videoProfile)}`);
// this.videoOutput = this.cameraMgr.createVideoOutput(videoProfile, videoId);
// Logger.info(TAG, `startVideo videoOutput:${this.videoOutput}`);
// this.capSession.addOutput(this.videoOutput);
// Logger.info(TAG, 'startVideo addOutput');
// await this.capSession.commitConfig();
// Logger.info(TAG, 'startVideo commitConfig');
// await this.capSession.start();
// Logger.info(TAG, 'startVideo commitConfig capSession');
// await this.videoOutput.start();
// Logger.info(TAG, 'startVideo commitConfig videoOutput');
// try {
// Logger.info(TAG, 'startVideo avRecorder.start 1');
// await this.avRecorder.start();
// Logger.info(TAG, 'startVideo avRecorder.start 2');
// } catch (e) {
// Logger.info(TAG, `startVideo catch e:${JSON.stringify(e)}`);
// }
//
// Logger.info(TAG, 'startVideo end');
//
// } else {
// Logger.info(TAG, `startVideo createAVRecorder fail, error:${error}`);
// }
// });
}
/**
* 停止录像
*/
async stopVideo(): Promise<void> {
Logger.info(TAG, 'stopVideo called');
await this.avRecorder.stop();
await this.avRecorder.release();
await this.videoOutput.stop();
await this.fileAsset.close(this.fd);
}
/**
* 资源释放
*/
async cameraRelease(): Promise<void> {
Logger.info(TAG, 'releaseCamera');
if (this.cameraInput) {
await this.cameraInput.close();
}
if (this.previewOutput) {
await this.previewOutput.release();
}
if (this.videoOutput) {
await this.videoOutput.release();
}
if (this.capSession) {
await this.capSession.release();
}
}
}
Camera.ets
import prompt from '@ohos.promptAction';
import camera from '@ohos.multimedia.camera';
import CameraModel from '../model/CameraModel';
import { VideoFrame } from '../model/CameraModel';
import Title from '../component/TitleComponent';
import grantPermission from '../utlis/PermissionUtils';
import Logger from '../utlis/Logger';
import { GlobalContext } from '../utlis/GlobalContext'
import { BusinessError } from '@ohos.base';
import common from '@ohos.app.ability.common';
enum CameraMode {
modePhoto = 0, // 拍照模式
modeVideo = 1 // 录像模式
};
const TAG: string = '[CameraPage]';
@Entry
@Component
struct CameraPage {
private mXComponentController: XComponentController = new XComponentController();
private surfaceId: string = '-1';
@State cameraModel: CameraModel = new CameraModel();
@State imageThumbnail: string = '';
@State videoThumbnail: Resource | undefined = undefined;
@State currentModel: number = CameraMode.modePhoto;
@State isRecording: boolean = false;
@State textMove: number = 45;
@State isPointShow: boolean = true;
@State isTitleShow: boolean = true;
@StorageLink('selectType_0') @Watch('rotationChange') rotation: number = 0;
@StorageLink('selectType_1') @Watch('resolutionChange') resolution: number = 0;
@State timeShow: boolean = false;
private textTimerController: TextTimerController = new TextTimerController();
@State format: string = 'mm:ss';
@State fps: number = 0;
/**
* 旋转角度改变监听方法
*/
rotationChange() {
Logger.info(TAG, `rotationChange begin ${this.rotation}`);
// 0°
if (this.rotation == 0) {
Logger.info(TAG, `rotationChange ${this.rotation}`);
this.cameraModel.setImageRotation(camera.ImageRotation.ROTATION_0);
// 90°
} else if (this.rotation == 1) {
Logger.info(TAG, `rotationChange ${this.rotation}`);
this.cameraModel.setImageRotation(camera.ImageRotation.ROTATION_90);
// 180°
} else if (this.rotation == 2) {
Logger.info(TAG, `rotationChange ${this.rotation}`);
this.cameraModel.setImageRotation(camera.ImageRotation.ROTATION_180);
// 270°
} else if (this.rotation == 3) {
Logger.info(TAG, `rotationChange ${this.rotation}`);
this.cameraModel.setImageRotation(camera.ImageRotation.ROTATION_270);
}
Logger.info(TAG, 'rotationChange end');
}
/**
* 分辨率改变监听方法
*/
resolutionChange() {
Logger.info(TAG, `resolutionChange begin ${this.resolution}`);
// 不支持 则为默认800*600
if (this.resolution == 0) {
Logger.info(TAG, `resolutionChange ${this.resolution}`);
this.cameraModel.setVideoFrameWH(VideoFrame.VIDEOFRAME_1920_1080);
} else if (this.resolution == 1) {
Logger.info(TAG, `resolutionChange ${this.resolution}`);
this.cameraModel.setVideoFrameWH(VideoFrame.VIDEOFRAME_1920_1080);
// 1280*720
} else if (this.resolution == 2) {
Logger.info(TAG, `resolutionChange ${this.resolution}`);
this.cameraModel.setVideoFrameWH(VideoFrame.VIDEOFRAME_1280_720);
// 800*600
} else if (this.resolution == 3) {
Logger.info(TAG, `resolutionChange ${this.resolution}`);
this.cameraModel.setVideoFrameWH(VideoFrame.VIDEOFRAME_800_600);
}
Logger.info(TAG, 'resolutionChange end');
}
async aboutToAppear() {
this.cameraModel.setCallback((fps: number) => {
this.fps = fps;
})
await grantPermission().then(res => {
Logger.info(TAG, `权限申请成功 ${JSON.stringify(res)}`);
if (this.surfaceId) {
this.cameraModel.initCamera(this.surfaceId);
}
}).catch((rej: BusinessError) => {
Logger.info(TAG, `权限申请失败 ${JSON.stringify(rej)}`);
})
this.surfaceId = this.mXComponentController.getXComponentSurfaceId();
Logger.info(TAG, `aboutToAppear,surfaceId=${this.surfaceId}`);
this.cameraModel.setTakePictureHandleCallback((photoUri: string): void => this.takePictureHandle(photoUri));
}
onPageHide() {
Logger.info(TAG, 'onPageHide begin');
if (this.isRecording) {
Logger.info(TAG, 'stopVideo begin');
this.timeShow = false;
this.textTimerController.pause();
this.cameraModel.stopVideo();
this.isRecording = false;
this.cameraModel.cameraRelease();
this.videoThumbnail = $r('app.media.video_poster');
}
Logger.info(TAG, 'onPageHide end');
}
onPageShow() {
this.cameraModel.initCamera(this.surfaceId);
}
getCameraIcon() {
if (this.currentModel === CameraMode.modePhoto) {
return $r('app.media.take_photo_normal');
} else {
if (this.isRecording) {
return $r('app.media.take_video_stop');
} else {
return $r('app.media.take_video_normal');
}
}
}
refreshVideoState() {
if (this.isRecording) {
Logger.info(TAG, 'stopVideo begin');
this.timeShow = false;
this.textTimerController.pause();
this.cameraModel.stopVideo();
this.isRecording = false;
this.videoThumbnail = $r('app.media.video_poster');
} else {
Logger.info(TAG, 'startVideo begin');
this.timeShow = true;
this.textTimerController.reset();
this.textTimerController.start();
this.cameraModel.startVideo();
this.isRecording = true;
}
}
startAbilityToPhoto() {
(GlobalContext.getContext().getCameraAbilityContext() as common.UIAbilityContext).startAbility({
bundleName: 'com.ohos.photos',
abilityName: 'com.ohos.photos.MainAbility'
}, (error: BusinessError) => {
Logger.info(TAG, `error.code = ${error.code}`)
});
}
takePictureHandle = (thumbnail: string) => {
this.imageThumbnail = thumbnail;
Logger.info(TAG, `takePicture end , thumbnail: ${this.imageThumbnail}`);
};
animateParam: AnimateParam = {
duration: 500,
onFinish: () => {
this.isPointShow = true;
}
};
/**
* 拍照事件
*/
photoEvent() {
if (this.currentModel === CameraMode.modeVideo) {
animateTo(this.animateParam, () => {
this.isPointShow = false;
this.textMove = this.textMove + 56;
});
if (this.isRecording) {
this.timeShow = false;
this.isRecording = false;
this.cameraModel.stopVideo();
}
this.currentModel = CameraMode.modePhoto;
this.videoThumbnail = undefined;
this.cameraModel.initCamera(this.surfaceId);
}
}
/**
* 录像事件
*/
videoEvent() {
if (this.currentModel === CameraMode.modePhoto) {
animateTo(this.animateParam, () => {
this.isPointShow = false;
this.textMove = this.textMove - 56;
});
this.currentModel = CameraMode.modeVideo;
this.imageThumbnail = '';
}
}
build() {
Stack() {
XComponent({
id: 'componentId',
type: 'surface',
controller: this.mXComponentController
})
.onLoad(() => {
Logger.info(TAG, 'onLoad is called');
this.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: 2560, surfaceHeight: 1440 });
this.surfaceId = this.mXComponentController.getXComponentSurfaceId();
Logger.info(TAG, `onLoad surfaceId: ${this.surfaceId}`);
this.currentModel = CameraMode.modePhoto;
this.cameraModel.initCamera(this.surfaceId);
})
// .width('1216px')
// .height('1216px')
// .width('480px')
// .height('480px')
.width('100%')
.height('100%')
.gesture(
SwipeGesture({ direction: SwipeDirection.Horizontal, speed: 40 })
.onAction((event: GestureEvent) => {
Logger.info(TAG, `SwipeGesture event: ${JSON.stringify(event)}`);
// 右滑
if (event.angle > 0) {
this.photoEvent();
} else {
this.videoEvent();
}
})
)
Column() {
Text(this.fps.toString())
.fontSize(30)
.backgroundColor(Color.Red)
Row() {
Button("start")
.onClick(() => {
this.cameraModel.listenFPS();
})
Button("stop")
.onClick(() => {
this.cameraModel.unlistenFPS();
})
}
}
}
.width('100%')
.height('100%')
.alignSelf(ItemAlign.End)
.alignContent(Alignment.Bottom)
.align(Alignment.Bottom)
}
async aboutToDisappear() {
if (this.isRecording) {
await this.cameraModel.stopVideo();
}
await this.cameraModel.cameraRelease();
}
}
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
标签
已于2024-11-20 17:51:53修改
赞
收藏
回复
相关推荐