删除无用文件
This commit is contained in:
parent
acc9f03109
commit
cb276de665
@ -1,424 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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.file.fs';
|
|
||||||
import image from '@ohos.multimedia.image';
|
|
||||||
import media from '@ohos.multimedia.media';
|
|
||||||
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
|
|
||||||
import Logger from '../utils/Logger';
|
|
||||||
import MediaModel from './MediaModel';
|
|
||||||
|
|
||||||
|
|
||||||
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: 480,
|
|
||||||
height: 360,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分辨率
|
|
||||||
*/
|
|
||||||
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: mediaLibrary.FileAsset = undefined;
|
|
||||||
private cameraMgr: camera.CameraManager = undefined;
|
|
||||||
private camerasArray: Array<camera.CameraDevice> = undefined;
|
|
||||||
private cameraInput: camera.CameraInput = undefined;
|
|
||||||
private previewOutput: camera.PreviewOutput = undefined;
|
|
||||||
private photoOutPut: camera.PhotoOutput = undefined;
|
|
||||||
private capSession: camera.CaptureSession = 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 videoFrameWH: VideoFrameWH = {
|
|
||||||
width: 480,
|
|
||||||
height: 360,
|
|
||||||
}; // 视频分辨率
|
|
||||||
private imageRotation: camera.ImageRotation = camera.ImageRotation.ROTATION_0; // 图片旋转角度
|
|
||||||
|
|
||||||
private videoProfile: media.VideoRecorderProfile = {
|
|
||||||
audioChannels: 2,
|
|
||||||
audioCodec: media.CodecMimeType.AUDIO_AAC,
|
|
||||||
audioBitrate: 48000,
|
|
||||||
audioSampleRate: 48000,
|
|
||||||
fileFormat: media.ContainerFormatType.CFT_MPEG_4,
|
|
||||||
videoBitrate: 48000,
|
|
||||||
videoCodec: media.CodecMimeType.VIDEO_MPEG4,
|
|
||||||
videoFrameWidth: 480,
|
|
||||||
videoFrameHeight: 360,
|
|
||||||
videoFrameRate: 30,
|
|
||||||
};
|
|
||||||
private videoSourceType: number = 0;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.mediaModel = MediaModel.getMediaInstance();
|
|
||||||
this.receiver = image.createImageReceiver(
|
|
||||||
cameraWH.width,
|
|
||||||
cameraWH.height,
|
|
||||||
FOUR,
|
|
||||||
EIGHT
|
|
||||||
);
|
|
||||||
Logger.info(TAG, 'createImageReceiver');
|
|
||||||
this.receiver.on('imageArrival', () => {
|
|
||||||
Logger.info(TAG, 'imageArrival');
|
|
||||||
this.receiver.readNextImage((err, image) => {
|
|
||||||
Logger.info(TAG, 'readNextImage');
|
|
||||||
if (err || image === undefined) {
|
|
||||||
Logger.error(TAG, 'failed to get valid image');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
image.getComponent(FOUR, (errMsg, img) => {
|
|
||||||
Logger.info(TAG, 'getComponent');
|
|
||||||
if (errMsg || img === undefined) {
|
|
||||||
Logger.info(TAG, 'failed to get valid buffer');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let buffer = new ArrayBuffer(FOUR_THOUSAND_AND_SIXTY_NINE);
|
|
||||||
if (img.byteBuffer) {
|
|
||||||
buffer = img.byteBuffer;
|
|
||||||
} else {
|
|
||||||
Logger.error(TAG, 'img.byteBuffer is undefined');
|
|
||||||
}
|
|
||||||
this.saveImage(buffer, image);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置分辨率
|
|
||||||
* @param videoFrame
|
|
||||||
*/
|
|
||||||
setVideoFrameWH(videoFrame: VideoFrame): void {
|
|
||||||
switch (videoFrame) {
|
|
||||||
case VideoFrame.VIDEOFRAME_800_600:
|
|
||||||
this.videoFrameWH = {
|
|
||||||
width: 800,
|
|
||||||
height: 600,
|
|
||||||
};
|
|
||||||
Logger.info(
|
|
||||||
TAG,
|
|
||||||
`setVideoFrameWH videoFrameWH:${JSON.stringify(this.videoFrameWH)}`
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case VideoFrame.VIDEOFRAME_1280_720:
|
|
||||||
this.videoFrameWH = {
|
|
||||||
width: 1280,
|
|
||||||
height: 720,
|
|
||||||
};
|
|
||||||
Logger.info(
|
|
||||||
TAG,
|
|
||||||
`setVideoFrameWH videoFrameWH:${JSON.stringify(this.videoFrameWH)}`
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case VideoFrame.VIDEOFRAME_1920_1080:
|
|
||||||
this.videoFrameWH = {
|
|
||||||
width: 1920,
|
|
||||||
height: 1080,
|
|
||||||
};
|
|
||||||
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(mediaLibrary.MediaType.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 ${this.camerasArray.length}`);
|
|
||||||
if (this.camerasArray.length === 0) {
|
|
||||||
Logger.info(TAG, 'cannot get cameras');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mCamera = this.camerasArray[0];
|
|
||||||
this.cameraInput = this.cameraMgr.createCameraInput(mCamera);
|
|
||||||
this.cameraInput.open();
|
|
||||||
Logger.info(TAG, 'createCameraInput');
|
|
||||||
this.capability = this.cameraMgr.getSupportedOutputCapability(mCamera);
|
|
||||||
let previewProfile = this.capability.previewProfiles[0];
|
|
||||||
this.previewOutput = this.cameraMgr.createPreviewOutput(
|
|
||||||
previewProfile,
|
|
||||||
surfaceId
|
|
||||||
);
|
|
||||||
Logger.info(TAG, 'createPreviewOutput');
|
|
||||||
let rSurfaceId = await this.receiver.getReceivingSurfaceId();
|
|
||||||
let photoProfile = this.capability.photoProfiles[0];
|
|
||||||
this.photoOutPut = this.cameraMgr.createPhotoOutput(
|
|
||||||
photoProfile,
|
|
||||||
rSurfaceId
|
|
||||||
);
|
|
||||||
this.capSession = this.cameraMgr.createCaptureSession();
|
|
||||||
Logger.info(TAG, 'createCaptureSession');
|
|
||||||
this.capSession.beginConfig();
|
|
||||||
Logger.info(TAG, 'beginConfig');
|
|
||||||
this.capSession.addInput(this.cameraInput);
|
|
||||||
this.capSession.addOutput(this.previewOutput);
|
|
||||||
this.capSession.addOutput(this.photoOutPut);
|
|
||||||
await this.capSession.commitConfig();
|
|
||||||
await this.capSession.start();
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
await this.photoOutPut.capture(photoSettings);
|
|
||||||
Logger.info(TAG, 'takePicture done');
|
|
||||||
AppStorage.Set('isRefresh', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始录像
|
|
||||||
*/
|
|
||||||
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(mediaLibrary.MediaType.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.photoOutPut) {
|
|
||||||
await this.photoOutPut.release();
|
|
||||||
}
|
|
||||||
if (this.videoOutput) {
|
|
||||||
await this.videoOutput.release();
|
|
||||||
}
|
|
||||||
if (this.capSession) {
|
|
||||||
await this.capSession.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,424 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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.file.fs';
|
|
||||||
import image from '@ohos.multimedia.image';
|
|
||||||
import media from '@ohos.multimedia.media';
|
|
||||||
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
|
|
||||||
import Logger from '../utils/Logger';
|
|
||||||
import MediaModel from './MediaModel';
|
|
||||||
|
|
||||||
|
|
||||||
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: 480,
|
|
||||||
height: 360,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分辨率
|
|
||||||
*/
|
|
||||||
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: mediaLibrary.FileAsset = undefined;
|
|
||||||
private cameraMgr: camera.CameraManager
|
|
||||||
private camerasArray: Array<camera.CameraDevice> = undefined;
|
|
||||||
private cameraInput: camera.CameraInput = undefined;
|
|
||||||
private previewOutput: camera.PreviewOutput = undefined;
|
|
||||||
private photoOutPut: camera.PhotoOutput = undefined;
|
|
||||||
private capSession: camera.CaptureSession = 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 videoFrameWH: VideoFrameWH = {
|
|
||||||
width: 480,
|
|
||||||
height: 360,
|
|
||||||
}; // 视频分辨率
|
|
||||||
private imageRotation: camera.ImageRotation = camera.ImageRotation.ROTATION_0; // 图片旋转角度
|
|
||||||
|
|
||||||
private videoProfile: media.VideoRecorderProfile = {
|
|
||||||
audioChannels: 2,
|
|
||||||
audioCodec: media.CodecMimeType.AUDIO_AAC,
|
|
||||||
audioBitrate: 48000,
|
|
||||||
audioSampleRate: 48000,
|
|
||||||
fileFormat: media.ContainerFormatType.CFT_MPEG_4,
|
|
||||||
videoBitrate: 48000,
|
|
||||||
videoCodec: media.CodecMimeType.VIDEO_MPEG4,
|
|
||||||
videoFrameWidth: 480,
|
|
||||||
videoFrameHeight: 360,
|
|
||||||
videoFrameRate: 30,
|
|
||||||
};
|
|
||||||
private videoSourceType: number = 0;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.mediaModel = MediaModel.getMediaInstance();
|
|
||||||
this.receiver = image.createImageReceiver(
|
|
||||||
cameraWH.width,
|
|
||||||
cameraWH.height,
|
|
||||||
FOUR,
|
|
||||||
EIGHT
|
|
||||||
);
|
|
||||||
Logger.info(TAG, 'createImageReceiver');
|
|
||||||
this.receiver.on('imageArrival', () => {
|
|
||||||
Logger.info(TAG, 'imageArrival');
|
|
||||||
this.receiver.readNextImage((err, image) => {
|
|
||||||
Logger.info(TAG, 'readNextImage');
|
|
||||||
if (err || image === undefined) {
|
|
||||||
Logger.error(TAG, 'failed to get valid image');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
image.getComponent(FOUR, (errMsg, img) => {
|
|
||||||
Logger.info(TAG, 'getComponent');
|
|
||||||
if (errMsg || img === undefined) {
|
|
||||||
Logger.info(TAG, 'failed to get valid buffer');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let buffer = new ArrayBuffer(FOUR_THOUSAND_AND_SIXTY_NINE);
|
|
||||||
if (img.byteBuffer) {
|
|
||||||
buffer = img.byteBuffer;
|
|
||||||
} else {
|
|
||||||
Logger.error(TAG, 'img.byteBuffer is undefined');
|
|
||||||
}
|
|
||||||
this.saveImage(buffer, image);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置分辨率
|
|
||||||
* @param videoFrame
|
|
||||||
*/
|
|
||||||
setVideoFrameWH(videoFrame: VideoFrame): void {
|
|
||||||
switch (videoFrame) {
|
|
||||||
case VideoFrame.VIDEOFRAME_800_600:
|
|
||||||
this.videoFrameWH = {
|
|
||||||
width: 800,
|
|
||||||
height: 600,
|
|
||||||
};
|
|
||||||
Logger.info(
|
|
||||||
TAG,
|
|
||||||
`setVideoFrameWH videoFrameWH:${JSON.stringify(this.videoFrameWH)}`
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case VideoFrame.VIDEOFRAME_1280_720:
|
|
||||||
this.videoFrameWH = {
|
|
||||||
width: 1280,
|
|
||||||
height: 720,
|
|
||||||
};
|
|
||||||
Logger.info(
|
|
||||||
TAG,
|
|
||||||
`setVideoFrameWH videoFrameWH:${JSON.stringify(this.videoFrameWH)}`
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case VideoFrame.VIDEOFRAME_1920_1080:
|
|
||||||
this.videoFrameWH = {
|
|
||||||
width: 1920,
|
|
||||||
height: 1080,
|
|
||||||
};
|
|
||||||
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(mediaLibrary.MediaType.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 ${this.camerasArray.length}`);
|
|
||||||
if (this.camerasArray.length === 0) {
|
|
||||||
Logger.info(TAG, 'cannot get cameras');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mCamera = this.camerasArray[0];
|
|
||||||
this.cameraInput = this.cameraMgr.createCameraInput(mCamera);
|
|
||||||
this.cameraInput.open();
|
|
||||||
Logger.info(TAG, 'createCameraInput');
|
|
||||||
this.capability = this.cameraMgr.getSupportedOutputCapability(mCamera);
|
|
||||||
let previewProfile = this.capability.previewProfiles[0];
|
|
||||||
this.previewOutput = this.cameraMgr.createPreviewOutput(
|
|
||||||
previewProfile,
|
|
||||||
surfaceId
|
|
||||||
);
|
|
||||||
Logger.info(TAG, 'createPreviewOutput');
|
|
||||||
let rSurfaceId = await this.receiver.getReceivingSurfaceId();
|
|
||||||
let photoProfile = this.capability.photoProfiles[0];
|
|
||||||
this.photoOutPut = this.cameraMgr.createPhotoOutput(
|
|
||||||
photoProfile,
|
|
||||||
rSurfaceId
|
|
||||||
);
|
|
||||||
this.capSession = this.cameraMgr.createCaptureSession();
|
|
||||||
Logger.info(TAG, 'createCaptureSession');
|
|
||||||
this.capSession.beginConfig();
|
|
||||||
Logger.info(TAG, 'beginConfig');
|
|
||||||
this.capSession.addInput(this.cameraInput);
|
|
||||||
this.capSession.addOutput(this.previewOutput);
|
|
||||||
this.capSession.addOutput(this.photoOutPut);
|
|
||||||
await this.capSession.commitConfig();
|
|
||||||
await this.capSession.start();
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
await this.photoOutPut.capture(photoSettings);
|
|
||||||
Logger.info(TAG, 'takePicture done');
|
|
||||||
AppStorage.Set('isRefresh', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始录像
|
|
||||||
*/
|
|
||||||
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(mediaLibrary.MediaType.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.photoOutPut) {
|
|
||||||
await this.photoOutPut.release();
|
|
||||||
}
|
|
||||||
if (this.videoOutput) {
|
|
||||||
await this.videoOutput.release();
|
|
||||||
}
|
|
||||||
if (this.capSession) {
|
|
||||||
await this.capSession.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,173 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023 Hunan OpenValley Digital Industry Development 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 '../utils/DateTimeUtil';
|
|
||||||
import Logger from '../utils/Logger';
|
|
||||||
|
|
||||||
const TAG = '[MediaModel]';
|
|
||||||
|
|
||||||
type FileInfo = {
|
|
||||||
prefix: string;
|
|
||||||
suffix: string;
|
|
||||||
directory: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class MediaModel {
|
|
||||||
private mediaLibraryTest: mediaLibrary.MediaLibrary = undefined;
|
|
||||||
private static mediaInstance: MediaModel = undefined;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.mediaLibraryTest = mediaLibrary.getMediaLibrary(globalThis.cameraContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static getMediaInstance(): MediaModel {
|
|
||||||
if (this.mediaInstance === undefined) {
|
|
||||||
this.mediaInstance = new MediaModel();
|
|
||||||
}
|
|
||||||
return this.mediaInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
async createAndGetUri(mediaType: mediaLibrary.MediaType): Promise<mediaLibrary.FileAsset> {
|
|
||||||
let dateTimeUtil: DateTimeUtil = new DateTimeUtil();
|
|
||||||
let info: FileInfo = this.getInfoFromMediaType(mediaType);
|
|
||||||
let name: string = `${dateTimeUtil.getDate()}_${dateTimeUtil.getTime()}`;
|
|
||||||
let displayName: string = `${info.prefix}${name}${info.suffix}`;
|
|
||||||
Logger.info(TAG, `displayName = ${displayName},mediaType = ${mediaType}`);
|
|
||||||
let publicPath: string = await this.mediaLibraryTest.getPublicDirectory(
|
|
||||||
info.directory
|
|
||||||
);
|
|
||||||
Logger.info(TAG, `publicPath = ${publicPath}`);
|
|
||||||
let fileAsset: mediaLibrary.FileAsset = await this.mediaLibraryTest.createAsset(
|
|
||||||
mediaType,
|
|
||||||
displayName,
|
|
||||||
publicPath
|
|
||||||
);
|
|
||||||
return fileAsset;
|
|
||||||
}
|
|
||||||
|
|
||||||
async getFile(dataUri: mediaLibrary.FileAsset): Promise<mediaLibrary.FileAsset> {
|
|
||||||
let fileKeyObj = mediaLibrary.FileKey;
|
|
||||||
if (dataUri !== undefined) {
|
|
||||||
let args = dataUri.id.toString();
|
|
||||||
let fetchOp = {
|
|
||||||
selections: `${fileKeyObj.ID}=?`,
|
|
||||||
selectionArgs: [args],
|
|
||||||
};
|
|
||||||
const fetchFileResult: mediaLibrary.FetchFileResult = await this.mediaLibraryTest.getFileAssets(
|
|
||||||
fetchOp
|
|
||||||
);
|
|
||||||
Logger.info(
|
|
||||||
TAG,
|
|
||||||
`fetchFileResult.getCount() = ${fetchFileResult.getCount()}`
|
|
||||||
);
|
|
||||||
const fileAssets = await fetchFileResult.getAllObject();
|
|
||||||
let fileAsset: mediaLibrary.FileAsset = fileAssets[0];
|
|
||||||
return fileAsset;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
async getFdPath(fileAsset: mediaLibrary.FileAsset): Promise<number> {
|
|
||||||
let fd: number = await fileAsset.open('Rw');
|
|
||||||
Logger.info(TAG, `fd = ${fd}`);
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
async getFileAssetsFromMediaType(mediaType: number): Promise<Array<mediaLibrary.FileAsset>> {
|
|
||||||
Logger.info(TAG, `getFileAssetsFromType,mediaType = ${mediaType}`);
|
|
||||||
let fileKeyObj = mediaLibrary.FileKey;
|
|
||||||
let fileAssets: Array<mediaLibrary.FileAsset> = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
let fetchOp = {
|
|
||||||
selections: `${fileKeyObj.MEDIA_TYPE}=?`,
|
|
||||||
selectionArgs: [`${mediaType}`],
|
|
||||||
};
|
|
||||||
const fetchFileResult: mediaLibrary.FetchFileResult = await this.mediaLibraryTest.getFileAssets(
|
|
||||||
fetchOp
|
|
||||||
);
|
|
||||||
Logger.info(TAG, `getFileAssetsFromType,fetchFileResult.count = ${fetchFileResult.getCount()}`);
|
|
||||||
if (fetchFileResult.getCount() > 0) {
|
|
||||||
fileAssets = await fetchFileResult.getAllObject();
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.info(`LSQ: err ${JSON.stringify(err)}`);
|
|
||||||
}
|
|
||||||
return fileAssets;
|
|
||||||
}
|
|
||||||
|
|
||||||
onDateChange(callback: () => void): void {
|
|
||||||
this.mediaLibraryTest.on('albumChange', () => {
|
|
||||||
Logger.info(TAG, 'albumChange called');
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
this.mediaLibraryTest.on('imageChange', () => {
|
|
||||||
Logger.info(TAG, 'imageChange called');
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
this.mediaLibraryTest.on('audioChange', () => {
|
|
||||||
Logger.info(TAG, 'audioChange called');
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
this.mediaLibraryTest.on('videoChange', () => {
|
|
||||||
Logger.info(TAG, 'videoChange called');
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
this.mediaLibraryTest.on('fileChange', () => {
|
|
||||||
Logger.info(TAG, 'fileChange called');
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
offDateChange(): void {
|
|
||||||
this.mediaLibraryTest.off('albumChange');
|
|
||||||
this.mediaLibraryTest.off('imageChange');
|
|
||||||
this.mediaLibraryTest.off('audioChange');
|
|
||||||
this.mediaLibraryTest.off('videoChange');
|
|
||||||
this.mediaLibraryTest.off('fileChange');
|
|
||||||
}
|
|
||||||
|
|
||||||
getInfoFromMediaType(mediaType: mediaLibrary.MediaType): FileInfo {
|
|
||||||
let fileInfo: FileInfo = {
|
|
||||||
prefix: '',
|
|
||||||
suffix: '',
|
|
||||||
directory: 0
|
|
||||||
};
|
|
||||||
switch (mediaType) {
|
|
||||||
case mediaLibrary.MediaType.FILE:
|
|
||||||
fileInfo.prefix = 'FILE_';
|
|
||||||
fileInfo.suffix = '.txt';
|
|
||||||
fileInfo.directory = mediaLibrary.DirectoryType.DIR_DOCUMENTS;
|
|
||||||
break;
|
|
||||||
case mediaLibrary.MediaType.IMAGE:
|
|
||||||
fileInfo.prefix = 'IMG_';
|
|
||||||
fileInfo.suffix = '.jpg';
|
|
||||||
fileInfo.directory = mediaLibrary.DirectoryType.DIR_IMAGE;
|
|
||||||
break;
|
|
||||||
case mediaLibrary.MediaType.VIDEO:
|
|
||||||
fileInfo.prefix = 'VID_';
|
|
||||||
fileInfo.suffix = '.mp4';
|
|
||||||
fileInfo.directory = mediaLibrary.DirectoryType.DIR_VIDEO;
|
|
||||||
break;
|
|
||||||
case mediaLibrary.MediaType.AUDIO:
|
|
||||||
fileInfo.prefix = 'AUD_';
|
|
||||||
fileInfo.suffix = '.wav';
|
|
||||||
fileInfo.directory = mediaLibrary.DirectoryType.DIR_AUDIO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return fileInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,254 +0,0 @@
|
|||||||
//@ts-ignore
|
|
||||||
import camera from '@ohos.multimedia.camera';
|
|
||||||
import image from '@ohos.multimedia.image'
|
|
||||||
import buffer from '@ohos.buffer';
|
|
||||||
import call from '@ohos.telephony.call';
|
|
||||||
|
|
||||||
|
|
||||||
export class cameraService {
|
|
||||||
constructor(surfaceId) {
|
|
||||||
this.surfaceId = surfaceId
|
|
||||||
}
|
|
||||||
private surfaceId: any = null;
|
|
||||||
private cameraObj: any = null;
|
|
||||||
private cameraManager: any = null;
|
|
||||||
// 相机会话
|
|
||||||
private captureSession: any = null;
|
|
||||||
// 相机输入流
|
|
||||||
private cameraInput: any = null;
|
|
||||||
// 预览输出流
|
|
||||||
private previewOutput: any = null;
|
|
||||||
// 拍照输出流
|
|
||||||
private photoOutput: any = null;
|
|
||||||
// 照片接收对象
|
|
||||||
private imageRecever: any = null;
|
|
||||||
private imageSrc: String;
|
|
||||||
async releaseSource() {
|
|
||||||
// 停止当前会话
|
|
||||||
await this.captureSession.stop()
|
|
||||||
// 释放相机输入流
|
|
||||||
await this.cameraInput.close()
|
|
||||||
// 释放预览输出流
|
|
||||||
await this.previewOutput.release()
|
|
||||||
// 释放拍照输出流
|
|
||||||
await this.photoOutput.release()
|
|
||||||
// 释放会话
|
|
||||||
await this.captureSession.release()
|
|
||||||
// 会话置空
|
|
||||||
this.captureSession = null
|
|
||||||
}
|
|
||||||
|
|
||||||
async initCamera(callBack){
|
|
||||||
let cameraManager = await camera.getCameraManager(globalThis.context)
|
|
||||||
if (!cameraManager) {
|
|
||||||
console.error("jiangsong camera.getCameraManager error")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 监听相机状态变化
|
|
||||||
cameraManager.on('cameraStatus', (err, cameraStatusInfo) => {
|
|
||||||
// console.info(`jiangsong camera : ${cameraStatusInfo.camera.cameraId}`);
|
|
||||||
// console.info(`jiangsong status: ${cameraStatusInfo.status}`);
|
|
||||||
})
|
|
||||||
|
|
||||||
// 获取相机列表
|
|
||||||
let cameraArray = await cameraManager.getSupportedCameras();
|
|
||||||
if (cameraArray.length <= 0) {
|
|
||||||
console.error("jiangsong cameraManager.getSupportedCameras error")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let index = 0; index < cameraArray.length; index++) {
|
|
||||||
console.info('cameraId : ' + cameraArray[index].cameraId); // 获取相机ID
|
|
||||||
console.info('cameraPosition : ' + cameraArray[index].cameraPosition); // 获取相机位置
|
|
||||||
console.info('cameraType : ' + cameraArray[index].cameraType); // 获取相机类型
|
|
||||||
console.info('connectionType : ' + cameraArray[index].connectionType); // 获取相机连接类型
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建相机输入流
|
|
||||||
try {
|
|
||||||
this.cameraInput = cameraManager.createCameraInput(cameraArray[0]);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('jiangsong Failed to createCameraInput errorCode = ' + error.code);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听cameraInput错误信息
|
|
||||||
let cameraDevice = cameraArray[0];
|
|
||||||
this.cameraInput.on('error', cameraDevice, (error) => {
|
|
||||||
console.info(`jiangsong Camera input error code: ${error.code}`);
|
|
||||||
})
|
|
||||||
|
|
||||||
// 打开相机
|
|
||||||
await this.cameraInput.open((err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error(`jiangsong Failed to open the camera. ${err.code}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log('jiangsong Callback returned with camera opened.');
|
|
||||||
});
|
|
||||||
// 获取相机设备支持的输出流能力
|
|
||||||
let cameraOutputCap = await cameraManager.getSupportedOutputCapability(cameraArray[0]);
|
|
||||||
if (!cameraOutputCap) {
|
|
||||||
console.error("jiangsong cameraManager.getSupportedOutputCapability error")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.info("outputCapability: " + JSON.stringify(cameraOutputCap));
|
|
||||||
|
|
||||||
let previewProfilesArray = cameraOutputCap.previewProfiles;
|
|
||||||
if (!previewProfilesArray) {
|
|
||||||
console.error("jiangsong createOutput previewProfilesArray == null || undefined")
|
|
||||||
}
|
|
||||||
|
|
||||||
let photoProfilesArray = cameraOutputCap.photoProfiles;
|
|
||||||
if (!photoProfilesArray) {
|
|
||||||
console.error("jiangsong createOutput photoProfilesArray == null || undefined")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 创建预览输出流,其中参数 surfaceId 参考上文 XComponent 组件,预览流为XComponent组件提供的surface
|
|
||||||
try {
|
|
||||||
this.previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], this.surfaceId)
|
|
||||||
} catch (error) {
|
|
||||||
console.error("jiangsong Failed to create the PreviewOutput instance.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听预览输出错误信息
|
|
||||||
this.previewOutput.on('error', (error) => {
|
|
||||||
console.info(`jiangosng Preview output error code: ${error.code}`);
|
|
||||||
})
|
|
||||||
|
|
||||||
// 创建ImageReceiver对象,并设置照片参数:分辨率大小是根据前面 photoProfilesArray 获取的当前设备所支持的拍照分辨率大小去设置
|
|
||||||
this.imageRecever = await image.createImageReceiver(1920, 1080, 4, 8);
|
|
||||||
|
|
||||||
this.imageRecever.on('imageArrival',async () => {
|
|
||||||
|
|
||||||
console.info(`jiangsong imageArrival `);
|
|
||||||
let img = await this.imageRecever.readLatestImage()
|
|
||||||
let component = await img.getComponent(4)
|
|
||||||
let buf = buffer.from(component.byteBuffer);
|
|
||||||
let str = buf.toString('base64')
|
|
||||||
|
|
||||||
console.log('jiangsong getComponent buf str. ')
|
|
||||||
if(callBack) {
|
|
||||||
callBack(str)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 获取照片显示SurfaceId
|
|
||||||
let photoSurfaceId = await this.imageRecever.getReceivingSurfaceId()
|
|
||||||
// 创建拍照输出流
|
|
||||||
try {
|
|
||||||
this.photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId)
|
|
||||||
} catch (error) {
|
|
||||||
console.error('jiangsong Failed to createPhotoOutput errorCode = ' + error.code);
|
|
||||||
}
|
|
||||||
//创建会话
|
|
||||||
try {
|
|
||||||
this.captureSession = cameraManager.createCaptureSession()
|
|
||||||
} catch (error) {
|
|
||||||
console.error('jiangsong Failed to create the CaptureSession instance. errorCode = ' + error.code);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听session错误信息
|
|
||||||
this.captureSession.on('error', (error) => {
|
|
||||||
console.info(`jiangsong Capture session error code: ${error.code}`);
|
|
||||||
})
|
|
||||||
|
|
||||||
// 开始配置会话
|
|
||||||
try {
|
|
||||||
this.captureSession.beginConfig()
|
|
||||||
} catch (error) {
|
|
||||||
console.error('jiangsong Failed to beginConfig. errorCode = ' + error.code);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 向会话中添加相机输入流
|
|
||||||
try {
|
|
||||||
this.captureSession.addInput(this.cameraInput)
|
|
||||||
} catch (error) {
|
|
||||||
console.error('jiangsong Failed to addInput. errorCode = ' + error.code);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 向会话中添加预览输出流
|
|
||||||
try {
|
|
||||||
this.captureSession.addOutput(this.previewOutput)
|
|
||||||
} catch (error) {
|
|
||||||
console.error('jiangsong Failed to addOutput(previewOutput). errorCode = ' + error.code);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 向会话中添加拍照输出流
|
|
||||||
try {
|
|
||||||
this.captureSession.addOutput(this.photoOutput)
|
|
||||||
} catch (error) {
|
|
||||||
console.error('jiangsong Failed to addOutput(photoOutput). errorCode = ' + error.code);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提交会话配置
|
|
||||||
await this.captureSession.commitConfig()
|
|
||||||
|
|
||||||
// 启动会话
|
|
||||||
await this.captureSession.start().then(() => {
|
|
||||||
console.info('jiangsong Promise returned to indicate the session start success.');
|
|
||||||
})
|
|
||||||
// 判断设备是否支持闪光灯
|
|
||||||
let flashStatus
|
|
||||||
try {
|
|
||||||
flashStatus = this.captureSession.hasFlash()
|
|
||||||
} catch (error) {
|
|
||||||
console.error('jiangsong Failed to hasFlash. errorCode = ' + error.code);
|
|
||||||
}
|
|
||||||
console.info('jiangsong Promise returned with the flash light support status:' + flashStatus);
|
|
||||||
|
|
||||||
if (flashStatus) {
|
|
||||||
// 判断是否支持自动闪光灯模式
|
|
||||||
let flashModeStatus
|
|
||||||
try {
|
|
||||||
let status = this.captureSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO)
|
|
||||||
flashModeStatus = status
|
|
||||||
} catch (error) {
|
|
||||||
console.error('jiangsong Failed to check whether the flash mode is supported. errorCode = ' + error.code);
|
|
||||||
}
|
|
||||||
if(flashModeStatus) {
|
|
||||||
// 设置自动闪光灯模式
|
|
||||||
try {
|
|
||||||
this.captureSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO)
|
|
||||||
} catch (error) {
|
|
||||||
console.error('jiangsong Failed to set the flash mode. errorCode = ' + error.code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
takePhoto() {
|
|
||||||
let settings = {
|
|
||||||
quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // 设置图片质量高
|
|
||||||
rotation: camera.ImageRotation.ROTATION_0 // 设置图片旋转角度0
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用当前拍照设置进行拍照
|
|
||||||
this.photoOutput.capture(settings, async (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error(`jiangsong Failed to capture the photo ${err.message}` + JSON.stringify(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.info('jiangsong Callback invoked to indicate the photo capture request success.' + JSON.stringify(this.imageRecever))
|
|
||||||
// console.info('jiangsong Callback invoked to indicate the photo capture request success.');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async getPhoto() {
|
|
||||||
// try {
|
|
||||||
// let img = await this.imageRecever.readLatestImage()
|
|
||||||
// // console.log('jiangsong readLatestImage success.' + JSON.stringify(img.clipRect));
|
|
||||||
// let component = await img.getComponent(4)
|
|
||||||
// let buf = buffer.from(component.byteBuffer);
|
|
||||||
// let str = buf.toString('base64')
|
|
||||||
// console.log('jiangsong getComponent buf str. ' + str.length + '--' + str.slice(0, 100))
|
|
||||||
// this.imageSrc = str;
|
|
||||||
// return str;
|
|
||||||
// } catch (e) {
|
|
||||||
// this.sleep(1000);
|
|
||||||
// return await this.getPhoto()
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay))
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user