• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import photoAccessHelper from '@ohos.file.photoAccessHelper';
17import { BusinessError } from '@ohos.base'
18import { GlobalContext } from '../comFile/utils/GlobalContext'
19import camera from '@ohos.multimedia.camera';
20
21const TAG: string = 'CameraService'
22
23class CameraService {
24  private cameraManager: camera.CameraManager | undefined = undefined
25  private cameras: Array<camera.CameraDevice> | Array<camera.CameraDevice> = []
26  private cameraInput: camera.CameraInput | undefined = undefined
27  private previewOutput: camera.PreviewOutput | undefined = undefined
28  private photoOutput: camera.PhotoOutput | undefined = undefined
29  private session: camera.PhotoSession | undefined = undefined
30  private handlePhotoAssetCb: (photoAsset: photoAccessHelper.PhotoAsset) => void = () => {
31  }
32  private curCameraDevice: camera.CameraDevice | undefined = undefined
33  // 推荐拍照分辨率之一
34  private photoProfileObj: camera.Profile = {
35    format: 2000,
36    size: {
37      width: 1920,
38      height: 1080
39    }
40  }
41  // 推荐预览分辨率之一
42  private previewProfileObj: camera.Profile = {
43    format: 1003,
44    size: {
45      width: 1920,
46      height: 1080
47    }
48  }
49  private curSceneMode: camera.SceneMode = camera.SceneMode.NORMAL_PHOTO
50
51  constructor() {
52  }
53
54  setSavePictureCallback(callback: (photoAsset: photoAccessHelper.PhotoAsset) => void): void {
55    this.handlePhotoAssetCb = callback
56  }
57
58  setSceneMode(sceneMode: camera.SceneMode): void {
59    this.curSceneMode = sceneMode
60  }
61
62  getSceneMode(): camera.SceneMode {
63    return this.curSceneMode
64  }
65
66  getPreviewProfile(cameraOutputCapability: camera.CameraOutputCapability): camera.Profile | undefined {
67    let previewProfiles = cameraOutputCapability.previewProfiles
68    if (previewProfiles.length < 1) {
69      return undefined
70    }
71    return previewProfiles[0]
72  }
73
74  getPhotoProfile(cameraOutputCapability: camera.CameraOutputCapability): camera.Profile | undefined {
75    let photoProfiles = cameraOutputCapability.photoProfiles
76    if (photoProfiles.length < 1) {
77      return undefined
78    }
79    return photoProfiles[0]
80  }
81
82  isSupportedSceneMode(cameraManager: camera.CameraManager, cameraDevice: camera.CameraDevice): boolean {
83    let sceneModes = cameraManager.getSupportedSceneModes(cameraDevice)
84    if (sceneModes === undefined) {
85      return false
86    }
87    let index = sceneModes.findIndex((sceneMode: camera.SceneMode) => {
88      return sceneMode === this.curSceneMode
89    })
90    if (index === -1) {
91      return false
92    }
93    return true
94  }
95
96  //初始化相机功能
97  async initCamera(surfaceId: string, cameraDeviceIndex: number): Promise<void> {
98    try {
99      await this.releaseCamera()
100      this.cameraManager = this.getCameraManagerFn()
101      if (this.cameraManager === undefined) {
102        return
103      }
104      //获取支持指定的相机设备对象
105      this.cameras = this.getSupportedCamerasFn(this.cameraManager)
106      if (this.cameras.length < 1 || this.cameras.length < cameraDeviceIndex + 1) {
107        return
108      }
109      this.curCameraDevice = this.cameras[cameraDeviceIndex]
110      let isSupported = this.isSupportedSceneMode(this.cameraManager, this.curCameraDevice)
111      if (!isSupported) {
112        return
113      }
114     let cameraOutputCapability=this.cameraManager.getSupportedOutputCapability(this.curCameraDevice,this.curSceneMode)
115      let previewProfile = this.getPreviewProfile(cameraOutputCapability)
116      if (previewProfile === undefined) {
117        return
118      }
119      this.previewProfileObj = previewProfile
120      let photoProfile = this.getPhotoProfile(cameraOutputCapability)
121      if (photoProfile === undefined) {
122        return
123      }
124      this.photoProfileObj = photoProfile
125      //创建previewOutput输出对象
126      this.previewOutput = this.createPreviewOutputFn(this.cameraManager, this.previewProfileObj, surfaceId)
127      if (this.previewOutput === undefined) {
128        return
129      }
130      //监听预览事件
131      this.previewOutputCallBack(this.previewOutput)
132      //创建photoOutPut输出对象
133      this.photoOutput = this.createPhotoOutputFn(this.cameraManager, this.photoProfileObj)
134      if (this.photoOutput === undefined) {
135        return
136      }
137      //创建cameraInput输出对象
138      this.cameraInput = this.createCameraInputFn(this.cameraManager, this.curCameraDevice)
139      if (this.cameraInput === undefined) {
140        return
141      }
142      //打开相机
143      let isOpenSuccess = await this.cameraInputOpenFn(this.cameraInput)
144      if (!isOpenSuccess) {
145        return
146      }
147      //镜头状态回调
148      this.onCameraStatusChange(this.cameraManager)
149      //监听CameraInput的错误事件
150      this.onCameraInputChange(this.cameraInput, this.curCameraDevice)
151      //会话流程
152      await this.sessionFlowFn(this.cameraManager, this.cameraInput, this.previewOutput, this.photoOutput)
153    } catch (error) {
154      let err = error as BusinessError
155    }
156  }
157
158  //变焦
159  setZoomRatioFn(zoomRatio: number): void {
160    //获取支持的变焦范围
161    try {
162      let zoomRationRange = this.session?.getZoomRatioRange()
163    } catch (error) {
164      let err = error as BusinessError
165    }
166    try {
167      this.session?.setZoomRatio(zoomRatio)
168    } catch (error) {
169      let err = error as BusinessError
170    }
171    try {
172      let nowZoomRatio = this.session?.getZoomRatio()
173    } catch (error) {
174      let err = error as BusinessError
175    }
176  }
177
178  //拍照
179  async takepicture(): Promise<void> {
180    let photoSettings: camera.PhotoCaptureSetting = {
181      quality: camera.QualityLevel.QUALITY_LEVEL_HIGH,
182      mirror: false
183    }
184    await this.photoOutput?.capture(photoSettings)
185  }
186
187  //释放会话及相关参数
188  async releaseCamera(): Promise<void> {
189    if (this.previewOutput) {
190      try {
191        await this.previewOutput.release()
192      } catch (error) {
193        let err = error as BusinessError
194      } finally {
195        this.previewOutput = undefined
196      }
197    }
198    if(this.photoOutput){
199      try {
200
201      } catch (error) {
202        let err = error as BusinessError;
203      } finally {
204        this.photoOutput = undefined;
205      }
206    }
207    if (this.session) {
208      try {
209        await this.session.release()
210      } catch (error) {
211        let err = error as BusinessError
212      } finally {
213        this.session = undefined
214      }
215    }
216    if (this.cameraInput) {
217      try {
218        await this.cameraInput.close()
219      } catch (error) {
220        let err = error as BusinessError
221      } finally {
222        this.cameraInput = undefined
223      }
224    }
225    this.offCameraStatusChange()
226  }
227
228  //获取相机管理器实例
229  getCameraManagerFn(): camera.CameraManager | undefined {
230    if (this.cameraManager) {
231      return this.cameraManager
232    }
233    let cameraManager: camera.CameraManager | undefined = undefined
234    try {
235      cameraManager = camera.getCameraManager(GlobalContext.get().getCameraSettingContext())
236    } catch (error) {
237      let err = error as BusinessError
238    }
239    return cameraManager
240  }
241
242  //获取支持指定的相机设备对象
243  getSupportedCamerasFn(cameraManager: camera.CameraManager): Array<camera.CameraDevice> {
244    let supportedCameras: camera.CameraDevice[] = []
245    try {
246      supportedCameras = cameraManager.getSupportedCameras()
247    } catch (error) {
248      let err = error as BusinessError
249    }
250    return supportedCameras
251  }
252
253  //创建previewOutput输出对象
254  createPreviewOutputFn(cameraManager: camera.CameraManager, previewProfileObj: camera.Profile, surfaceId: string):
255  camera.PreviewOutput | undefined {
256    let previewOutput: camera.PreviewOutput | undefined = undefined
257    try {
258      previewOutput = cameraManager.createPreviewOutput(previewProfileObj, surfaceId)
259    } catch (error) {
260      let err = error as BusinessError
261    }
262    return previewOutput
263  }
264
265  //创建photoOutput输出对象
266  createPhotoOutputFn(cameraManager: camera.CameraManager, photoProfileObj: camera.Profile):
267  camera.PhotoOutput | undefined {
268    let photoOutput: camera.PhotoOutput | undefined = undefined
269    try {
270      photoOutput = cameraManager.createPhotoOutput(photoProfileObj)
271    } catch (error) {
272      let err = error as BusinessError
273    }
274    return photoOutput
275  }
276
277  //创建cameraInput输出对象
278  createCameraInputFn(cameraManager: camera.CameraManager, cameraDevice: camera.CameraDevice):
279  camera.CameraInput | undefined {
280    let cameraInput: camera.CameraInput | undefined = undefined
281    try {
282      cameraInput = cameraManager.createCameraInput(cameraDevice)
283    } catch (error) {
284      let err = error as BusinessError
285    }
286    return cameraInput
287  }
288
289  //打开相机
290  async cameraInputOpenFn(cameraInput: camera.CameraInput): Promise<boolean> {
291    let isOpenSuccess = false
292    try {
293      await cameraInput.open()
294      isOpenSuccess = true
295    } catch (error) {
296      let err = error as BusinessError
297    }
298    return isOpenSuccess
299  }
300
301  /* 会话流程 */
302  async sessionFlowFn(cameraManger: camera.CameraManager, cameraInput: camera.CameraInput,
303  previewOutput: camera.PreviewOutput, photoOutput: camera.PhotoOutput): Promise<void> {
304    try {
305      // 创建captureSession实例
306      this.session = cameraManger.createSession(this.curSceneMode) as camera.PhotoSession
307      if (this.session === undefined) {
308        return
309      }
310      // 监听拍照会话的错误事件
311      this.onCaptureSessionErrorChange(this.session)
312      // 开始配置会话
313      this.session.beginConfig()
314      // 把CameraInput加入会话
315      this.session.addInput(cameraInput)
316      // 把previewOutput加入会话
317      this.session.addOutput(previewOutput)
318      // 把photoOutput加入会话
319      this.session.addOutput(photoOutput)
320      // 拍照监听事件
321      this.photoOutputCallBack(photoOutput)
322      // 提交配置信息
323      await this.session.commitConfig()
324      // 开始会话工作
325      await this.session.start()
326    } catch (error) {
327      let err = error as BusinessError
328    }
329  }
330
331  // 监听拍照事件
332  photoOutputCallBack(photoOutput: camera.PhotoOutput): void {
333    try {
334      // 监听拍照开始
335      photoOutput.on('captureStartWithInfo', (err: BusinessError, captureStartInfo: camera.CaptureStartInfo): void => {
336      })
337      // 监听拍照帧输出捕获
338      photoOutput.on('frameShutter', (err: BusinessError, frameShutterInfo: camera.FrameShutterInfo): void => {
339      })
340      // 监听拍照结束
341      photoOutput.on('captureEnd', (err: BusinessError, captureEndInfo: camera.CaptureEndInfo): void => {
342      })
343      // 监听拍照异常
344      photoOutput.on('error', (data: BusinessError): void => {
345      })
346    } catch (err) {
347    }
348  }
349
350  // 监听预览事件
351  previewOutputCallBack(previewOutput: camera.PreviewOutput): void {
352    try {
353      previewOutput.on('frameStart', (): void => {
354      })
355      previewOutput.on('frameEnd', (): void => {
356      })
357      previewOutput.on('error', (previewOutputError: BusinessError): void => {
358      })
359    } catch (err) {
360    }
361  }
362
363  // 注册相机变化的回调函数
364  registerCameraStatusChange(err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) {
365  }
366
367  // 监听相机状态变化
368  onCameraStatusChange(cameraManager: camera.CameraManager): void {
369    try {
370      cameraManager.on('cameraStatus', this.registerCameraStatusChange)
371    } catch (error) {
372
373    }
374  }
375
376  // 停止监听相机状态变化
377  offCameraStatusChange(): void {
378    this.cameraManager?.off('cameraStatus', this.registerCameraStatusChange)
379  }
380
381  // 监听相机输入变化
382  onCameraInputChange(cameraInput: camera.CameraInput, cameraDevice: camera.CameraDevice): void {
383    try {
384      cameraInput.on('error', cameraDevice, (cameraInputError: BusinessError): void => {
385      })
386    } catch (error) {
387    }
388  }
389
390  // 监听捕获绘画错误变化
391  onCaptureSessionErrorChange(session: camera.PhotoSession): void {
392    try {
393      session.on('error', (captureSessionError: BusinessError): void => {
394      })
395    } catch (error) {
396    }
397  }
398}
399
400export default new CameraService()