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      console.info('www data succeed' + 111)
102      if (this.cameraManager === undefined) {
103        return
104      }
105      //获取支持指定的相机设备对象
106      this.cameras = this.getSupportedCamerasFn(this.cameraManager)
107      if (this.cameras.length < 1 || this.cameras.length < cameraDeviceIndex + 1) {
108        return
109      }
110      console.info('www data 2')
111      this.curCameraDevice = this.cameras[cameraDeviceIndex]
112      let isSupported = this.isSupportedSceneMode(this.cameraManager, this.curCameraDevice)
113      if (!isSupported) {
114        return
115      }
116      console.info('www data 3')
117     let cameraOutputCapability=this.cameraManager.getSupportedOutputCapability(this.curCameraDevice,this.curSceneMode)
118      let previewProfile = this.getPreviewProfile(cameraOutputCapability)
119      if (previewProfile === undefined) {
120        return
121      }
122      console.info('www data 4')
123      this.previewProfileObj = previewProfile
124      let photoProfile = this.getPhotoProfile(cameraOutputCapability)
125      if (photoProfile === undefined) {
126        return
127      }
128      console.info('www data 5')
129      this.photoProfileObj = photoProfile
130      //创建previewOutput输出对象
131      this.previewOutput = this.createPreviewOutputFn(this.cameraManager, this.previewProfileObj, surfaceId)
132      if (this.previewOutput === undefined) {
133        return
134      }
135      console.info('www data 6')
136      //监听预览事件
137      this.previewOutputCallBack(this.previewOutput)
138      //创建photoOutPut输出对象
139      this.photoOutput = this.createPhotoOutputFn(this.cameraManager, this.photoProfileObj)
140      if (this.photoOutput === undefined) {
141        return
142      }
143      console.info('www data 7')
144      //创建cameraInput输出对象
145      this.cameraInput = this.createCameraInputFn(this.cameraManager, this.curCameraDevice)
146      if (this.cameraInput === undefined) {
147        return
148      }
149      console.info('www data 8')
150      //打开相机
151      let isOpenSuccess = await this.cameraInputOpenFn(this.cameraInput)
152      if (!isOpenSuccess) {
153        return
154      }
155      console.info('www data 9')
156      //镜头状态回调
157      this.onCameraStatusChange(this.cameraManager)
158      //监听CameraInput的错误事件
159      this.onCameraInputChange(this.cameraInput, this.curCameraDevice)
160      console.info('www data 9.5')
161      //会话流程
162      await this.sessionFlowFn(this.cameraManager, this.cameraInput, this.previewOutput, this.photoOutput)
163      console.info('www data 10')
164    } catch (error) {
165      console.info('www data3' + error)
166      console.info('www data3' + error.message)
167      let err = error as BusinessError
168    }
169  }
170
171  //变焦
172  setZoomRatioFn(zoomRatio: number): void {
173    //获取支持的变焦范围
174    try {
175      let zoomRationRange = this.session?.getZoomRatioRange()
176    } catch (error) {
177      let err = error as BusinessError
178    }
179    try {
180      this.session?.setZoomRatio(zoomRatio)
181    } catch (error) {
182      let err = error as BusinessError
183    }
184    try {
185      let nowZoomRatio = this.session?.getZoomRatio()
186    } catch (error) {
187      let err = error as BusinessError
188    }
189  }
190
191  //拍照
192  async takepicture(): Promise<void> {
193    let photoSettings: camera.PhotoCaptureSetting = {
194      quality: camera.QualityLevel.QUALITY_LEVEL_HIGH,
195      mirror: false
196    }
197    await this.photoOutput?.capture(photoSettings)
198  }
199
200  //释放会话及相关参数
201  async releaseCamera(): Promise<void> {
202    if (this.previewOutput) {
203      try {
204        await this.previewOutput.release()
205      } catch (error) {
206        let err = error as BusinessError
207      } finally {
208        this.previewOutput = undefined
209      }
210    }
211    if(this.photoOutput){
212      try {
213
214      } catch (error) {
215        let err = error as BusinessError;
216      } finally {
217        this.photoOutput = undefined;
218      }
219    }
220    if (this.session) {
221      try {
222        await this.session.release()
223      } catch (error) {
224        let err = error as BusinessError
225      } finally {
226        this.session = undefined
227      }
228    }
229    if (this.cameraInput) {
230      try {
231        await this.cameraInput.close()
232      } catch (error) {
233        let err = error as BusinessError
234      } finally {
235        this.cameraInput = undefined
236      }
237    }
238    this.offCameraStatusChange()
239  }
240
241  //获取相机管理器实例
242  getCameraManagerFn(): camera.CameraManager | undefined {
243    if (this.cameraManager) {
244      return this.cameraManager
245    }
246    let cameraManager: camera.CameraManager | undefined = undefined
247    try {
248      cameraManager = camera.getCameraManager(GlobalContext.get().getCameraSettingContext())
249    } catch (error) {
250      let err = error as BusinessError
251    }
252    return cameraManager
253  }
254
255  //获取支持指定的相机设备对象
256  getSupportedCamerasFn(cameraManager: camera.CameraManager): Array<camera.CameraDevice> {
257    let supportedCameras: camera.CameraDevice[] = []
258    try {
259      supportedCameras = cameraManager.getSupportedCameras()
260    } catch (error) {
261      let err = error as BusinessError
262    }
263    return supportedCameras
264  }
265
266  //创建previewOutput输出对象
267  createPreviewOutputFn(cameraManager: camera.CameraManager, previewProfileObj: camera.Profile, surfaceId: string): 
268  camera.PreviewOutput | undefined {
269    let previewOutput: camera.PreviewOutput | undefined = undefined
270    try {
271      previewOutput = cameraManager.createPreviewOutput(previewProfileObj, surfaceId)
272    } catch (error) {
273      let err = error as BusinessError
274    }
275    return previewOutput
276  }
277
278  //创建photoOutput输出对象
279  createPhotoOutputFn(cameraManager: camera.CameraManager, photoProfileObj: camera.Profile): 
280  camera.PhotoOutput | undefined {
281    let photoOutput: camera.PhotoOutput | undefined = undefined
282    try {
283      photoOutput = cameraManager.createPhotoOutput(photoProfileObj)
284    } catch (error) {
285      let err = error as BusinessError
286    }
287    return photoOutput
288  }
289
290  //创建cameraInput输出对象
291  createCameraInputFn(cameraManager: camera.CameraManager, cameraDevice: camera.CameraDevice): 
292  camera.CameraInput | undefined {
293    let cameraInput: camera.CameraInput | undefined = undefined
294    try {
295      cameraInput = cameraManager.createCameraInput(cameraDevice)
296    } catch (error) {
297      let err = error as BusinessError
298    }
299    return cameraInput
300  }
301
302  //打开相机
303  async cameraInputOpenFn(cameraInput: camera.CameraInput): Promise<boolean> {
304    let isOpenSuccess = false
305    try {
306      await cameraInput.open()
307      isOpenSuccess = true
308    } catch (error) {
309      let err = error as BusinessError
310    }
311    return isOpenSuccess
312  }
313
314  /* 会话流程 */
315  async sessionFlowFn(cameraManger: camera.CameraManager, cameraInput: camera.CameraInput, 
316  previewOutput: camera.PreviewOutput, photoOutput: camera.PhotoOutput): Promise<void> {
317    try {
318      // 创建captureSession实例
319      this.session = cameraManger.createSession(this.curSceneMode) as camera.PhotoSession
320      if (this.session === undefined) {
321        return
322      }
323      // 监听拍照会话的错误事件
324      this.onCaptureSessionErrorChange(this.session)
325      // 开始配置会话
326      this.session.beginConfig()
327      // 把CameraInput加入会话
328      this.session.addInput(cameraInput)
329      // 把previewOutput加入会话
330      this.session.addOutput(previewOutput)
331      // 把photoOutput加入会话
332      this.session.addOutput(photoOutput)
333      // 拍照监听事件
334      this.photoOutputCallBack(photoOutput)
335      // 提交配置信息
336      await this.session.commitConfig()
337      // 开始会话工作
338      await this.session.start()
339    } catch (error) {
340      let err = error as BusinessError
341    }
342  }
343
344  // 监听拍照事件
345  photoOutputCallBack(photoOutput: camera.PhotoOutput): void {
346    try {
347      // 监听拍照开始
348      photoOutput.on('captureStartWithInfo', (err: BusinessError, captureStartInfo: camera.CaptureStartInfo): void => {
349      })
350      // 监听拍照帧输出捕获
351      photoOutput.on('frameShutter', (err: BusinessError, frameShutterInfo: camera.FrameShutterInfo): void => {
352      })
353      // 监听拍照结束
354      photoOutput.on('captureEnd', (err: BusinessError, captureEndInfo: camera.CaptureEndInfo): void => {
355      })
356      // 监听拍照异常
357      photoOutput.on('error', (data: BusinessError): void => {
358      })
359    } catch (err) {
360    }
361  }
362
363  // 监听预览事件
364  previewOutputCallBack(previewOutput: camera.PreviewOutput): void {
365    try {
366      previewOutput.on('frameStart', (): void => {
367      })
368      previewOutput.on('frameEnd', (): void => {
369      })
370      previewOutput.on('error', (previewOutputError: BusinessError): void => {
371      })
372    } catch (err) {
373    }
374  }
375
376  // 注册相机变化的回调函数
377  registerCameraStatusChange(err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) {
378  }
379
380  // 监听相机状态变化
381  onCameraStatusChange(cameraManager: camera.CameraManager): void {
382    try {
383      cameraManager.on('cameraStatus', this.registerCameraStatusChange)
384    } catch (error) {
385
386    }
387  }
388
389  // 停止监听相机状态变化
390  offCameraStatusChange(): void {
391    this.cameraManager?.off('cameraStatus', this.registerCameraStatusChange)
392  }
393
394  // 监听相机输入变化
395  onCameraInputChange(cameraInput: camera.CameraInput, cameraDevice: camera.CameraDevice): void {
396    try {
397      cameraInput.on('error', cameraDevice, (cameraInputError: BusinessError): void => {
398      })
399    } catch (error) {
400    }
401  }
402
403  // 监听捕获绘画错误变化
404  onCaptureSessionErrorChange(session: camera.PhotoSession): void {
405    try {
406      session.on('error', (captureSessionError: BusinessError): void => {
407      })
408    } catch (error) {
409    }
410  }
411}
412
413export default new CameraService()