1//@ts-nocheck 2/* 3 * Copyright (c) 2022 Huawei Device Co., Ltd. 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import camera from '@ohos.multimedia.camera' 18import deviceManager from '@ohos.distributedHardware.deviceManager' 19import image from '@ohos.multimedia.image' 20import media from '@ohos.multimedia.media' 21import deviceInfo from '@ohos.deviceInfo' 22 23import { CameraId } from '../setting/settingitem/CameraId' 24import { Log } from '../utils/Log' 25import ThumbnailGetter from './ThumbnailGetter' 26import SaveCameraAsset from './SaveCameraAsset' 27import { SettingManager } from '../setting/SettingManager' 28import { CameraPlatformCapability } from './CameraPlatformCapability' 29import Trace from '../utils/Trace' 30 31const DEFAULT_VIDEO_FRAME_RATE = 30 32 33export interface FunctionCallBack { 34 onCapturePhotoOutput(): void 35 36 onCaptureSuccess(thumbnail: any, resourceUri: any): void 37 38 onCaptureFailure(): void 39 40 onRecordSuccess(thumbnail: any): void 41 42 onRecordFailure(): void 43 44 thumbnail(thumbnail: any): void 45} 46 47export interface VideoCallBack { 48 videoUri(videoUri: any): void 49 onRecodeError(errorMsg: any): void 50} 51 52type Callback = (args?: any) => void 53 54export class CameraService { 55 private TAG = '[CameraService]:' 56 private mCameraId: string = CameraId.BACK 57 private mSurfaceId = '' 58 private isVideo: boolean = false 59 private mFileAssetId = 0 60 private mCameraManager!: camera.CameraManager 61 private mCameraIdMap: Map<string, string> = new Map() 62 private mLocalCameraMap: Map<string, string> = new Map() 63 private mCameraMap = new Map() 64 private curCameraName = '' 65 private mCameraCount = 0 66 private mCameraInput!: camera.CameraInput 67 private mCaptureSession!: camera.CaptureSession 68 private mPreviewOutput!: camera.PreviewOutput 69 private mPhotoOutPut!: camera.PhotoOutput 70 private mImageReceiver!: image.ImageReceiver 71 private mVideoOutput!: camera.VideoOutput 72 private mAVRecorder!: media.AVRecorder 73 private mThumbnail!: image.PixelMap 74 private mIsStartRecording = false 75 private mSaveCameraAsset = new SaveCameraAsset() 76 private mThumbnailGetter = new ThumbnailGetter() 77 private camerasCache: any = null 78 private outputCapability: camera.CameraOutputCapability = null 79 80 private mVideoConfig: any = { 81 audioSourceType: 1, 82 videoSourceType: 1, 83 profile: { 84 audioBitrate: 48000, 85 audioChannels: 2, 86 audioCodec: 'audio/mp4a-latm', 87 audioSampleRate: 48000, 88 durationTime: 1000, 89 fileFormat: 'mp4', 90 videoBitrate: 5000000, 91 videoCodec: 'video/avc', 92 videoFrameWidth: 640, 93 videoFrameHeight: 480, 94 videoFrameRate: 30 95 }, 96 url: 'file:///data/media/01.mp4', 97 orientationHint: 0, 98 maxSize: 100, 99 maxDuration: 500, 100 rotation: 0 101 } 102 private mCaptureSetting: any = { 103 rotation: 0, 104 quality: 1, 105 mirror: false 106 } 107 public mImageSize = { 108 imageWidth: 1920, 109 imageHeight: 1080 110 } 111 public mVideoFrameSize = { 112 frameWidth: 1920, 113 frameHeight: 1080 114 } 115 116 117 private constructor() { 118 } 119 120 public static getInstance(): CameraService { 121 if (!globalThis?.sInstanceCameraService) { 122 globalThis.sInstanceCameraService = new CameraService() 123 } 124 return globalThis.sInstanceCameraService; 125 } 126 127 public async initCamera(cameraId: string): Promise<number> { 128 Log.info(`${this.TAG} initCamera invoke E.`) 129 if (!this.mCameraManager) { 130 this.mCameraManager = await camera.getCameraManager(globalThis.cameraAbilityContext) 131 const cameras = await this.mCameraManager.getSupportedCameras() 132 this.camerasCache = cameras 133 this.mCameraCount = cameras.length 134 if (cameras) { 135 Log.info(`${this.TAG} getCameras success.`) 136 for (let i = 0; i < cameras.length; i++) { 137 Log.info(`${this.TAG} --------------Camera Info-------------`) 138 Log.info(`${this.TAG} camera_id: ${cameras[i].cameraId}`) 139 Log.info(`${this.TAG} cameraPosition: ${cameras[i].cameraPosition}`) 140 Log.info(`${this.TAG} cameraType: ${cameras[i].cameraType}`) 141 Log.info(`${this.TAG} connectionType: ${cameras[i].connectionType}`) 142 if(cameras[i].cameraPosition === 2 && cameras[i].connectionType !== 2){ 143 this.mLocalCameraMap.set('front', 'true') 144 } 145 if(cameras[i].cameraPosition !== 2 && cameras[i].connectionType !== 2){ 146 this.mLocalCameraMap.set('back', 'true') 147 } 148 } 149 // TODO 根据底层信息匹配cameraId 目前默认第0个是back, 第1个是front 150 this.mCameraIdMap.set(CameraId.BACK, cameras[0].cameraId); 151 if (cameras.length > 1 && cameras[1].connectionType !== 2) { 152 this.mCameraIdMap.set(CameraId.FRONT, cameras[1].cameraId); 153 } else { 154 this.mCameraIdMap.set(CameraId.FRONT, cameras[0].cameraId); 155 } 156 } 157 } 158 this.curCameraName = cameraId 159 await this.createCameraInput(cameraId, 'init') 160 161 Log.info(`${this.TAG} deviceType = ${deviceInfo.deviceType}`) 162 if (deviceInfo.deviceType == 'default') { 163 this.mVideoConfig.videoSourceType = 1 164 } else { 165 this.mVideoConfig.videoSourceType = 0 166 } 167 Log.info(`${this.TAG} initCamera invoke X.`) 168 return this.mCameraCount 169 } 170 171 public getCameraManager() { 172 return this.mCameraManager 173 } 174 175 public getCameraIdMap() { 176 return this.mCameraIdMap 177 } 178 179 public getLocalCameraMap() { 180 return this.mLocalCameraMap 181 } 182 183 public getCameraMap() { 184 return this.mCameraMap 185 } 186 187 public getCameraCount() { 188 return this.mCameraCount 189 } 190 191 public async createCameraInput(cameraName: string, callType?: string) { 192 Log.info(`${this.TAG} createCameraInput invoke E.`) 193 this.mCameraId = cameraName 194 this.curCameraName = cameraName 195 if (callType === 'modeChange' || callType === 'init') { 196 let targetCamera = this.camerasCache.filter(item=>item.connectionType !== 2) 197 if (targetCamera && targetCamera.length <= 1 && cameraName === 'BACK') { 198 this.curCameraName = 'FRONT' 199 this.mCameraId = 'FRONT' 200 } 201 } 202 if (this.mCameraInput) { 203 this.mCameraInput.release() 204 } 205 let id 206 if (cameraName == CameraId.FRONT || cameraName == CameraId.BACK) { 207 id = this.mCameraIdMap.get(cameraName) 208 } else { 209 id = this.mCameraMap.get(cameraName).cameraId 210 } 211 Log.info(`${this.TAG} createCameraInput id = ${id}`) 212 let cameras = await this.getCameraLists() 213 let targetCamera = cameras.find(item => item.cameraId === id) 214 this.outputCapability = await this.mCameraManager.getSupportedOutputCapability(targetCamera) 215 this.mCameraInput = await this.mCameraManager.createCameraInput(targetCamera) 216 await this.mCameraInput.open() 217 const platformCapability = CameraPlatformCapability.getInstance() 218 await platformCapability.calcSupportedSizes(this.mCameraInput, this.outputCapability) 219 SettingManager.getInstance().setCameraPlatformCapability(platformCapability) 220 Log.info(`${this.TAG} createCameraInput invoke X.`) 221 } 222 223 public async releaseCameraInput() { 224 Log.info(`${this.TAG} releaseCameraInput invoke E.`) 225 if (this.mCameraInput) { 226 try { 227 await this.mCameraInput.release() 228 } catch (err) { 229 Log.error(`${this.TAG} releaseCameraInput ${err}`) 230 } 231 this.mCameraInput = null 232 } 233 Log.info(`${this.TAG} releaseCameraInput invoke X.`) 234 } 235 236 public async createPreviewOutput(surfaceId: string, mode: string) { 237 Log.info(`${this.TAG} createPreviewOutput invoke ${surfaceId} E. `) 238 this.mSurfaceId = surfaceId 239 const size = SettingManager.getInstance().getPreviewSize(mode) 240 Log.info(`${this.TAG} createPreviewOutput size = ${JSON.stringify(size)}`) 241 globalThis.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: size.width , surfaceHeight: size.height }) 242 let previewProfiles = this.outputCapability.previewProfiles 243 let previewProfile; 244 if (deviceInfo.deviceType == 'default') { 245 previewProfile = previewProfiles[0] 246 } else { 247 Log.info(`${this.TAG} previewProfiles length.` + previewProfiles.length) 248 previewProfile = previewProfiles.find(item => item.size.width === size.width 249 && item.size.height === size.height && item.format === 1003) 250 } 251 this.mPreviewOutput = await this.mCameraManager.createPreviewOutput(previewProfile, surfaceId) 252 Log.info(`${this.TAG} createPreviewOutput invoke ${this.mPreviewOutput} X.`) 253 } 254 255 public async releasePreviewOutput() { 256 Log.info(`${this.TAG} releasePreviewOutput invoke E.`) 257 if (this.mPreviewOutput) { 258 await this.mPreviewOutput.release() 259 this.mPreviewOutput = null 260 } 261 Log.info(`${this.TAG} releasePreviewOutput invoke X.`) 262 } 263 264 public async createPhotoOutput(functionCallback: FunctionCallBack) { 265 Log.info(`${this.TAG} createPhotoOutput invoke E.`) 266 const size = SettingManager.getInstance().getImageSize() 267 Log.info(`${this.TAG} createPhotoOutput size = ${JSON.stringify(size)}`) 268 this.mImageReceiver = image.createImageReceiver(size.width, size.height, image.ImageFormat.JPEG, 8) 269 Log.info(`${this.TAG} createPhotoOutput receiver: ${this.mImageReceiver}.`) 270 const surfaceId = await this.mImageReceiver.getReceivingSurfaceId() 271 Log.info(`${this.TAG} createPhotoOutput surfaceId: ${surfaceId}.`) 272 let photoProfiles = this.outputCapability.photoProfiles 273 let photoProfile; 274 if (deviceInfo.deviceType == 'default') { 275 photoProfile = photoProfiles[0] 276 } else { 277 Log.info(`${this.TAG} videoProfiles length.` + photoProfiles.length) 278 photoProfile = photoProfiles.find(item => item.size.width === size.width && item.size.height === size.height) 279 } 280 this.mPhotoOutPut = await this.mCameraManager.createPhotoOutput(photoProfile, surfaceId) 281 Log.info(`${this.TAG} createPhotoOutput mPhotoOutPut: ${this.mPhotoOutPut}.`) 282 this.mSaveCameraAsset.saveImage(this.mImageReceiver, 40, 40, this.mThumbnailGetter, functionCallback) 283 Log.info(`${this.TAG} createPhotoOutput invoke X.`) 284 } 285 286 public async releasePhotoOutput() { 287 Log.info(`${this.TAG} releasePhotoOutput invoke E.`) 288 if (this.mPhotoOutPut) { 289 await this.mPhotoOutPut.release() 290 this.mPhotoOutPut = null 291 } 292 if (this.mImageReceiver) { 293 await this.mImageReceiver.release() 294 this.mImageReceiver = null 295 } 296 Log.info(`${this.TAG} releasePhotoOutput invoke X.`) 297 } 298 299 public async createSession(surfaceId: string, isVideo: boolean) { 300 Log.info(`${this.TAG} createSession invoke E.`) 301 this.mSurfaceId = surfaceId 302 this.isVideo = isVideo 303 globalThis.isSessionCreating = true 304 this.mCaptureSession = await this.mCameraManager.createCaptureSession() 305 globalThis.isSessionCreating = false 306 Log.info(`${this.TAG} createSession captureSession: ${this.mCaptureSession}, cameraInput: ${this.mCameraInput}, 307 videoOutPut: ${this.mVideoOutput}, photoOutPut: ${this.mPhotoOutPut}, mPreviewOutput: ${this.mPreviewOutput}`) 308 Log.info(`${this.TAG} createSession beginConfig.`) 309 Trace.start(Trace.STREAM_DISTRIBUTION) 310 try { 311 await this.mCaptureSession?.beginConfig() 312 await new Promise((resolve) => setTimeout(resolve, 1)); 313 Log.info(`${this.TAG} createSession addInput.`) 314 await this.mCaptureSession?.addInput(this.mCameraInput) 315 if (!isVideo) { 316 Log.info(`${this.TAG} createSession photo addOutput.`) 317 await this.mCaptureSession?.addOutput(this.mPhotoOutPut) 318 } 319 Log.info(`${this.TAG} createSession preview addOutput.`) 320 await this.mCaptureSession?.addOutput(this.mPreviewOutput) 321 } catch(err) { 322 if (err) { 323 Trace.write(Trace.CAMERA_ERROR) 324 } 325 } 326 Log.info(`${this.TAG} createSession commitConfig.`) 327 Trace.start(Trace.OPEN_CAMERA) 328 try { 329 await this.mCaptureSession?.commitConfig() 330 } catch(err) { 331 if (err) { 332 Trace.write(Trace.OPEN_FAIL) 333 } 334 } 335 Trace.end(Trace.OPEN_CAMERA) 336 Trace.end(Trace.STREAM_DISTRIBUTION) 337 await this.mCaptureSession?.start() 338 if(globalThis.cameraStartFlag && (new Date().getTime() - globalThis.cameraStartTime) > 2000){ 339 Trace.write(Trace.START_TIMEOUT) 340 } 341 globalThis.cameraStartFlag = false 342 Log.info(`${this.TAG} createSession invoke X.`) 343 } 344 345 public async releaseSession() { 346 Log.info(`${this.TAG} releasePhotoSession invoke E.`) 347 if (this.mCaptureSession) { 348 await this.mCaptureSession.stop() 349 await this.mCaptureSession.release() 350 this.mCaptureSession = null 351 } 352 Log.info(`${this.TAG} releasePhotoSession invoke X.`) 353 } 354 355 public async startPreview() { 356 Log.info(`${this.TAG} startPreview invoke E.`) 357 if (!this.mCaptureSession) { 358 return 359 } 360 await this.mCaptureSession.start() 361 Log.info(`${this.TAG} startPreview invoke X.`) 362 } 363 364 public async stopPreview() { 365 Log.info(`${this.TAG} stopPreview invoke E.`) 366 if (!this.mCaptureSession) { 367 return 368 } 369 await this.mCaptureSession.stop() 370 Log.info(`${this.TAG} stopPreview invoke X.`) 371 } 372 373 public async takePicture() { 374 Log.info(`${this.TAG} takePicture invoke E.`) 375 if (!this.mCaptureSession) { 376 Log.info(`${this.TAG} takePicture session is release`) 377 return 378 } 379 if (!this.mPhotoOutPut) { 380 Log.info(`${this.TAG} takePicture photoOutPut is release`) 381 return 382 } 383 Log.info(`${this.TAG} takePicture SelfMirror setting: ${SettingManager.getInstance().getSelfMirror()}`) 384 if (this.mCameraId === CameraId.FRONT) { 385 this.mCaptureSetting.mirror = SettingManager.getInstance().getSelfMirror() 386 } 387 const locationData = SettingManager.getInstance().getCurGeoLocation() 388 if (locationData) { 389 this.mCaptureSetting.location = { 390 latitude: locationData.latitude, 391 longitude: locationData.longitude, 392 altitude: locationData.altitude 393 } 394 } 395 Log.info(`${this.TAG} takePicture captureSetting ${JSON.stringify(this.mCaptureSetting)}`) 396 // todo modify the location and mirror config 397 try { 398 await this.mPhotoOutPut.capture(this.mCaptureSetting) 399 } catch(err) { 400 if(err){ 401 Trace.write(Trace.CAPTURE_FAIL) 402 } 403 } 404 Log.info(`${this.TAG} takePicture invoke X.`) 405 Trace.end(Trace.TAKE_PICTURE) 406 if((new Date().getTime() - globalThis.startCaptureTime) > 2000){ 407 Trace.write(Trace.CAPTURE_TIMEOUT) 408 } 409 } 410 411 public async createVideoOutput(functionCallBack: VideoCallBack) { 412 Log.info(`${this.TAG} createVideoOutput invoke E.`) 413 Log.info(`${this.TAG} createVideoOutput this.mSurfaceId:saveCameraAsset: ${this.mSaveCameraAsset}`) 414 this.mFileAssetId = await this.mSaveCameraAsset.createVideoFd(functionCallBack) 415 if (this.mFileAssetId === undefined) { 416 Log.error(`${this.TAG} createVideoOutput error: mFileAssetId undefined`) 417 functionCallBack.onRecodeError(`createVideoOutput error: mFileAssetId undefined`) 418 } 419 this.mVideoConfig.url = `fd://${this.mFileAssetId.toString()}` 420 await media.createAVRecorder().then((recorder) => { 421 Log.info(`${this.TAG} createVideoOutput createAVRecorder record: ${recorder}`) 422 this.mAVRecorder = recorder 423 }) 424 const size = SettingManager.getInstance().getVideoSize() 425 if (this.mAVRecorder != null) { 426 this.mAVRecorder.on('error', (error) => { 427 if (error) { 428 Log.error(`${this.TAG} createVideoOutput error: ${error}`) 429 functionCallBack.onRecodeError(`createVideoOutput error: ${error}`) 430 } 431 }) 432 Log.info(`${this.TAG} createVideoOutput size = ${JSON.stringify(size)}`) 433 this.mVideoConfig.profile.videoFrameWidth = size.width 434 this.mVideoConfig.profile.videoFrameHeight = size.height 435 const locationData = SettingManager.getInstance().getCurGeoLocation() 436 if (locationData) { 437 this.mVideoConfig.location = { 438 latitude: locationData.latitude, 439 longitude: locationData.longitude 440 } 441 } 442 443 if (deviceInfo.deviceType != 'tablet') { 444 if (this.curCameraName === 'BACK') { 445 this.mVideoConfig.rotation = 90 446 } else { 447 this.mVideoConfig.rotation = 270 448 } 449 } 450 Log.info(`${this.TAG} createVideoOutput AVRecorder.prepare called.`) 451 Log.info(`${this.TAG} createVideoOutput mVideoConfig = ${JSON.stringify(this.mVideoConfig)}.`) 452 await this.mAVRecorder.prepare(this.mVideoConfig) 453 Log.info(`${this.TAG} createVideoOutput AVRecorder.prepare succeed.`) 454 } else { 455 Log.error(`${this.TAG} createVideoOutput createAVRecorder failed.`) 456 return 457 } 458 459 let profileVideo; 460 if (deviceInfo.deviceType == 'default') { 461 profileVideo = this.outputCapability.videoProfiles[0] 462 } else { 463 let videoProfiles = this.outputCapability.videoProfiles 464 Log.info(`${this.TAG} videoProfiles length.` + videoProfiles.length) 465 profileVideo = videoProfiles.find(item => 466 item.size.width === size.width && item.size.height === size.height 467 && item.frameRateRange.min === DEFAULT_VIDEO_FRAME_RATE && item.frameRateRange.max === DEFAULT_VIDEO_FRAME_RATE 468 ) 469 } 470 471 const videoId = await this.mAVRecorder.getInputSurface() 472 Log.info(`${this.TAG} createVideoOutput profileVideo = ${JSON.stringify(profileVideo)}.`) 473 this.mVideoOutput = await this.mCameraManager.createVideoOutput(profileVideo, videoId) 474 Log.info(`${this.TAG} createVideoOutput invoke X.`) 475 } 476 477 public async releaseVideoOutput() { 478 Log.info(`${this.TAG} releaseVideoOutput invoke E.`) 479 if (this.mVideoOutput) { 480 Log.info(`${this.TAG} releaseVideoOutput start`) 481 await this.mVideoOutput.release() 482 Log.info(`${this.TAG} releaseVideoOutput end`) 483 this.mVideoOutput = null 484 } 485 Log.info(`${this.TAG} releaseVideoOutput invoke X.`) 486 } 487 488 public async StartRecording(functionCallBack: VideoCallBack) { 489 let startRecordingTime = new Date().getTime() 490 Log.info(`${this.TAG} StartRecording invoke E.`) 491 Log.info(`${this.TAG} StartRecording codec ${this.mVideoConfig.profile.videoCodec}`) 492 await this.mCaptureSession.stop() 493 await this.mCaptureSession.beginConfig() 494 if (this.mVideoOutput) { 495 try { 496 await this.mCaptureSession.removeOutput(this.mVideoOutput) 497 Log.info(`${this.TAG} old videoOutput has been removed.`) 498 } catch (err) { 499 globalThis.startRecordingFlag = false 500 Log.error(`${this.TAG} remove videoOutput ${err}`) 501 } 502 } 503 await this.createVideoOutput(functionCallBack) 504 await this.mCaptureSession.addOutput(this.mVideoOutput) 505 Log.info(`${this.TAG} StartRecording addOutput finished.`) 506 await this.mCaptureSession.commitConfig() 507 Log.info(`${this.TAG} StartRecording commitConfig finished.`) 508 await this.mCaptureSession.start() 509 Log.info(`${this.TAG} StartRecording Session.start finished.`) 510 await this.mVideoOutput.start().then(() => { 511 Log.info(`${this.TAG} videoOutput.start()`) 512 }) 513 await this.mAVRecorder.start().then(() => { 514 Log.info(`${this.TAG} AVRecorder.start()`) 515 }) 516 this.mIsStartRecording = true 517 Log.info(`${this.TAG} StartRecording invoke X.`) 518 if(new Date().getTime() - startRecordingTime > 2000){ 519 Trace.write(Trace.START_RECORD_TIMEOUT) 520 } 521 } 522 523 public async stopRecording() { 524 Trace.start(Trace.STOP_RECORDING) 525 let stopRecordingTime = new Date().getTime() 526 Log.info(`${this.TAG} stopRecording invoke E.`) 527 if (!this.mVideoOutput || !this.mAVRecorder) { 528 Log.error(`${this.TAG} stopRecording error videoOutPut: ${this.mVideoOutput}, 529 AVRecorder: ${this.mAVRecorder} .`) 530 return 531 } 532 this.mIsStartRecording = false 533 try { 534 await this.mAVRecorder.stop() 535 await this.mAVRecorder.release() 536 } catch (err) { 537 Log.error(`${this.TAG} stop AVRecorder ${err}`) 538 } 539 540 try { 541 await this.mVideoOutput.stop() 542 } catch (err) { 543 Log.error(`${this.TAG} stop videoOutput ${err}`) 544 } 545 546 if (this.mFileAssetId != undefined) { 547 await this.mSaveCameraAsset.videoPrepareFile.close(this.mFileAssetId) 548 this.mFileAssetId = undefined 549 Log.info(`${this.TAG} fileAsset.close().`) 550 } 551 Trace.start(Trace.UPDATE_VIDEO_THUMBNAIL) 552 const thumbnailPixelMap = await this.mThumbnailGetter.getThumbnailInfo(40, 40) 553 Trace.end(Trace.UPDATE_VIDEO_THUMBNAIL) 554 Log.info(`${this.TAG} stopRecording invoke X.`) 555 if(new Date().getTime() - stopRecordingTime > 2000){ 556 Trace.write(Trace.FINISH_RECORD_TIMEOUT) 557 } 558 Trace.end(Trace.STOP_RECORDING) 559 return thumbnailPixelMap 560 } 561 562 public async pauseRecording() { 563 Log.info(`${this.TAG} pauseRecording invoke E.`) 564 if (!this.mVideoOutput || !this.mAVRecorder) { 565 Log.error(`${this.TAG} pauseRecording error videoOutPut: ${this.mVideoOutput}, 566 AVRecorder: ${this.mAVRecorder} .`) 567 return 568 } 569 await this.mAVRecorder.pause() 570 await this.mVideoOutput.stop() 571 Log.info(`${this.TAG} pauseRecording invoke X.`) 572 } 573 574 public async resumeRecording() { 575 Log.info(`${this.TAG} resumeRecording invoke E.`) 576 if (!this.mVideoOutput || !this.mAVRecorder) { 577 Log.error(`${this.TAG} resumeRecording error videoOutPut: ${this.mVideoOutput}, 578 AVRecorder: ${this.mAVRecorder} .`) 579 return 580 } 581 await this.mVideoOutput.start().then(() => { 582 Log.info(`${this.TAG} videoOutput.start()`) 583 }) 584 await this.mAVRecorder.resume() 585 Log.debug(`${this.TAG} resumeRecording invoke X.`) 586 } 587 588 public async releaseRecording() { 589 Log.info(`${this.TAG} releaseRecording invoke E.`) 590 if (!this.mAVRecorder) { 591 Log.info(`${this.TAG} AVRecorder has not been created.`) 592 return 593 } 594 if (this.mIsStartRecording) { 595 await this.stopRecording() 596 } 597 await this.mAVRecorder.release().then(() => { 598 Log.info(`${this.TAG} AVRecorder.release() success.`) 599 this.mAVRecorder = undefined 600 }) 601 Log.debug(`${this.TAG} releaseRecording invoke X.`) 602 } 603 604 public async releaseCamera() { 605 Log.info(`${this.TAG} releaseCamera invoke E.`) 606 try { 607 await this.releaseRecording() 608 } catch(err) { 609 Log.error(`${this.TAG} releaseRecording: ${err}`) 610 } 611 await this.releaseVideoOutput() 612 await this.releasePhotoOutput() 613 await this.releaseSession() 614 Log.info(`${this.TAG} releaseCamera invoke X.`) 615 } 616 617 public async setZoomRatio(zoomRatio: number) { 618 Log.info(`${this.TAG} setZoomRatio invoke E ${zoomRatio}`) 619 if (!this.mCaptureSession) { 620 Log.info(`${this.TAG} setZoomRatio mCaptureSession is release`) 621 return 622 } 623 await this.mCaptureSession.setZoomRatio(zoomRatio) 624 Log.info(`${this.TAG} setZoomRatio invoke X.`) 625 } 626 627 public async getZoomRatio(): Promise<number> { 628 Log.info(`${this.TAG} getZoomRatio invoke E.`) 629 if (!this.mCaptureSession) { 630 Log.info(`${this.TAG} getZoomRatio mCaptureSession is release`) 631 return 1; 632 } 633 Log.info(`${this.TAG} getZoomRatio invoke X.`) 634 return await this.mCaptureSession.getZoomRatio() 635 } 636 637 public async setVideoConfig(videoConfig: any) { 638 Log.info(`${this.TAG} setVideoConfig invoke E.`) 639 if (videoConfig) { 640 this.mVideoConfig = videoConfig 641 } else { 642 Log.info(`${this.TAG} setVideoConfig videoConfig is null.`) 643 } 644 Log.info(`${this.TAG} setVideoConfig invoke X.`) 645 } 646 647 public async setCaptureSetting(captureSetting: any) { 648 Log.info(`${this.TAG} setCaptureSetting invoke E.`) 649 if (captureSetting) { 650 this.mCaptureSetting = captureSetting 651 } else { 652 Log.info(`${this.TAG} setCaptureSetting captureSetting is null.`) 653 } 654 Log.debug(`${this.TAG} setCaptureSetting invoke X.`) 655 } 656 657 public getThumbnail(functionCallBack: FunctionCallBack) { 658 Log.info(`${this.TAG} getThumbnail invoke E.`) 659 this.mThumbnailGetter.getThumbnailInfo(40, 40).then((thumbnail) => { 660 Log.info(`${this.TAG} getThumbnail thumbnail: ${thumbnail}`) 661 functionCallBack.thumbnail(thumbnail) 662 }) 663 Log.info(`${this.TAG} getThumbnail invoke X.`) 664 return this.mThumbnail 665 } 666 667 public async getMultiCameraInfo(callback: Callback) { 668 Log.info(`${this.TAG} getMultiCameraInfo called.`) 669 // return ['MatePad Pro(前置)', 'MatePad Pro(后置)'] 670 const deviceNames = [] 671 const deviceIds = [] 672 const cameraMap = new Map() 673 const cameras = await this.getCameraLists() 674 deviceManager.createDeviceManager('com.ohos.camera', (err, manager) => { 675 if (err) { 676 Log.info(`${this.TAG} deviceManager.createDeviceManager failed.`) 677 } 678 Log.info(`${this.TAG} deviceManager.createDeviceManager success.`) 679 const deviceInfoList = manager.getTrustedDeviceListSync() 680 Log.info(`${this.TAG} deviceManager.deviceInfoList: ${JSON.stringify(deviceInfoList)}`) 681 if (typeof (deviceInfoList) != undefined && typeof (deviceInfoList.length) != undefined) { 682 deviceInfoList.forEach(item => { 683 deviceNames.push(item.deviceName) 684 deviceIds.push(item.deviceId) 685 let hasFront = false 686 let hasBack = false 687 let cameraName 688 for (let i = 0; i < cameras.length; i++) { 689 if (cameras[i].connectionType == 2) { 690 if (cameras[i].cameraId.split('_')[0] == item.deviceId) { 691 if (cameras[i].cameraPosition == 2 && !hasFront) { 692 cameraName = item.deviceId + '_FRONT' 693 cameraMap.set(cameraName, {deviceName: item.deviceName, cameraId: cameras[i].cameraId}) 694 Log.info(`${this.TAG} deviceManager add cameraName: ${cameraName}`) 695 hasFront = true 696 } else if (cameras[i].cameraPosition == 1 && !hasBack) { 697 cameraName = item.deviceId + '_BACK' 698 cameraMap.set(cameraName, {deviceName: item.deviceName, cameraId: cameras[i].cameraId}) 699 Log.info(`${this.TAG} deviceManager add cameraName: ${cameraName}`) 700 hasBack = true 701 } 702 if (hasFront && hasBack) { 703 break 704 } 705 } 706 } 707 } 708 }) 709 this.mCameraMap = new Map(cameraMap) 710 callback() 711 } 712 }) 713 } 714 715 private async getCameraLists() { 716 const cameras = await this.mCameraManager.getSupportedCameras() 717 this.camerasCache = cameras 718 return cameras 719 } 720 721 public getCameraName(): string { 722 return this.curCameraName 723 } 724 725 public setCameraId(name: string) { 726 this.curCameraName = name 727 } 728 729 public getPhotoUri() { 730 return this.mSaveCameraAsset.getPhotoUri() 731 } 732}