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