From 8f102452c8396837e9042db5a47aff3a0a95a60d Mon Sep 17 00:00:00 2001 From: zhangchao Date: Wed, 30 Aug 2023 17:36:17 +0800 Subject: [PATCH] =?UTF-8?q?cameraFramework=20ArkTs=E6=95=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangchao --- .../media/camera-device-input.md | 88 ++-- .../application-dev/media/camera-metadata.md | 69 ++- zh-cn/application-dev/media/camera-mode.md | 472 +++++++++--------- .../media/camera-performance-improvement.md | 104 ++-- zh-cn/application-dev/media/camera-preview.md | 111 ++-- .../media/camera-recording-case.md | 436 ++++++++-------- .../application-dev/media/camera-recording.md | 185 +++---- .../media/camera-session-management.md | 143 +++--- .../media/camera-shooting-case.md | 416 +++++++-------- .../application-dev/media/camera-shooting.md | 187 +++---- 10 files changed, 1189 insertions(+), 1022 deletions(-) diff --git a/zh-cn/application-dev/media/camera-device-input.md b/zh-cn/application-dev/media/camera-device-input.md index 67f66c0641..e0238db57a 100644 --- a/zh-cn/application-dev/media/camera-device-input.md +++ b/zh-cn/application-dev/media/camera-device-input.md @@ -10,14 +10,18 @@ ```ts import camera from '@ohos.multimedia.camera'; + import type { BusinessError } from '@ohos.base'; + import type featureAbility from '@ohos.ability.featureAbility'; ``` 2. 通过getCameraManager()方法,获取cameraManager对象。 [各类Context的获取方式](../application-models/application-context-stage.md)。 ```ts - let cameraManager: camera.CameraManager; - let context: Context = getContext(this); - cameraManager = camera.getCameraManager(context); + function getCameraManager(context: featureAbility.Context): camera.CameraManager { + let cameraManager: camera.CameraManager; + cameraManager = camera.getCameraManager(context); + return cameraManager; + } ``` > **说明:** @@ -27,45 +31,49 @@ 3. 通过cameraManager类中的getSupportedCameras()方法,获取当前设备支持的相机列表,列表中存储了设备支持的所有相机ID。若列表不为空,则说明列表中的每个ID都支持独立创建相机对象;否则,说明当前设备无可用相机,不可继续后续操作。 ```ts - let cameraArray: Array = cameraManager.getSupportedCameras(); - if (cameraArray != undefined && cameraArray.length <= 0) { - console.error("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); // 获取相机连接类型 + function getCameraDevices(cameraManager: camera.CameraManager): Array { + let cameraArray: Array = cameraManager.getSupportedCameras(); + if (cameraArray != undefined && cameraArray.length <= 0) { + console.error("cameraManager.getSupportedCameras error"); + return null; + } + 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); // 获取相机连接类型 + } + return cameraArray; } ``` 4. 通过getSupportedOutputCapability()方法,获取当前设备支持的所有输出流,如预览流、拍照流等。输出流在CameraOutputCapability中的各个profile字段中。 ```ts - // 创建相机输入流 - let cameraInput: camera.CameraInput; - try { - cameraInput = cameraManager.createCameraInput(cameraArray[0]); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to createCameraInput errorCode = ' + err.code); - } - // 监听cameraInput错误信息 - let cameraDevice: camera.CameraDevice = cameraArray[0]; - cameraInput.on('error', cameraDevice, (error: BusinessError) => { - console.info(`Camera input error code: ${error.code}`); - }); - // 打开相机 - await cameraInput.open(); - // 获取相机设备支持的输出流能力 - let cameraOutputCapability: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraArray[0]); - if (!cameraOutputCapability) { - console.error("cameraManager.getSupportedOutputCapability error"); - return; + async function getSupportedOutputCapability(cameraDevice: camera.CameraDevice, cameraManager: camera.CameraManager): Promise { + // 创建相机输入流 + let cameraInput: camera.CameraInput; + try { + cameraInput = cameraManager.createCameraInput(cameraDevice); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to createCameraInput errorCode = ' + err.code); + } + // 监听cameraInput错误信息 + cameraInput.on('error', cameraDevice, (error: BusinessError) => { + console.info(`Camera input error code: ${error.code}`); + }); + // 打开相机 + await cameraInput.open(); + // 获取相机设备支持的输出流能力 + let cameraOutputCapability: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraDevice); + if (!cameraOutputCapability) { + console.error("cameraManager.getSupportedOutputCapability error"); + return null; + } + console.info("outputCapability: " + JSON.stringify(cameraOutputCapability)); + return cameraOutputCapability; } - console.info("outputCapability: " + JSON.stringify(cameraOutputCapability)); ``` @@ -76,8 +84,10 @@ 通过注册cameraStatus事件,通过回调返回监听结果,callback返回CameraStatusInfo参数,参数的具体内容可参考相机管理器回调接口实例[CameraStatusInfo](../reference/apis/js-apis-camera.md#camerastatusinfo)。 ```ts -cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { - console.info(`camera: ${cameraStatusInfo.camera.cameraId}`); - console.info(`status: ${cameraStatusInfo.status}`); -}); +function onCameraStatus(cameraManager: camera.CameraManager): void { + cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { + console.info(`camera: ${cameraStatusInfo.camera.cameraId}`); + console.info(`status: ${cameraStatusInfo.status}`); + }); +} ``` diff --git a/zh-cn/application-dev/media/camera-metadata.md b/zh-cn/application-dev/media/camera-metadata.md index cc7c8aa2c1..290c0ea90a 100644 --- a/zh-cn/application-dev/media/camera-metadata.md +++ b/zh-cn/application-dev/media/camera-metadata.md @@ -8,37 +8,50 @@ Metadata主要是通过一个TAG(Key),去找对应的Data,用于传递 详细的API说明请参考[Camera API参考](../reference/apis/js-apis-camera.md)。 -1. 调用CameraOutputCapability类中的supportedMetadataObjectTypes()方法,获取当前设备支持的元数据类型,并通过createMetadataOutput()方法创建元数据输出流。 +1. 导入相关接口,导入方法如下。 + ```ts + import camera from '@ohos.multimedia.camera'; + import type { BusinessError } from '@ohos.base'; + ``` + +2. 调用CameraOutputCapability类中的supportedMetadataObjectTypes()方法,获取当前设备支持的元数据类型,并通过createMetadataOutput()方法创建元数据输出流。 ```ts - let metadataObjectTypes: Array = cameraOutputCapability.supportedMetadataObjectTypes; - let metadataOutput: camera.MetadataOutput; - try { - metadataOutput = cameraManager.createMetadataOutput(metadataObjectTypes); - } catch (error) { - let err = error as BusinessError; - console.info('Failed to createMetadataOutput, error code: '+ err.code); + function getMetadataOutput(cameraManager: camera.CameraManager, cameraOutputCapability: camera.CameraOutputCapability): camera.MetadataOutput { + let metadataObjectTypes: Array = cameraOutputCapability.supportedMetadataObjectTypes; + let metadataOutput: camera.MetadataOutput; + try { + metadataOutput = cameraManager.createMetadataOutput(metadataObjectTypes); + } catch (error) { + let err = error as BusinessError; + console.info('Failed to createMetadataOutput, error code: '+ err.code); + } + return metadataOutput; } ``` -2. 调用start()方法输出metadata数据,接口调用失败时,会返回相应错误码,错误码类型参见CameraErrorCode。 +3. 调用start()方法输出metadata数据,接口调用失败时,会返回相应错误码,错误码类型参见CameraErrorCode。 ```ts - metadataOutput.start().then(() => { - console.info('Callback returned with metadataOutput started.'); - }).catch((err: BusinessError) => { - console.info('Failed to metadataOutput start, error code: '+ err.code); - }); + function startMetadataOutput(metadataOutput: camera.MetadataOutput): void { + metadataOutput.start().then(() => { + console.info('Callback returned with metadataOutput started.'); + }).catch((err: BusinessError) => { + console.info('Failed to metadataOutput start, error code: '+ err.code); + }); + } ``` -3. 调用stop方法停止输出metadata数据,接口调用失败会返回相应错误码,错误码类型参见CameraErrorCode。 +4. 调用stop方法停止输出metadata数据,接口调用失败会返回相应错误码,错误码类型参见CameraErrorCode。 ```ts - metadataOutput.stop().then(() => { - console.info('Callback returned with metadataOutput stopped.'); - }).catch((err: BusinessError) => { - console.info('Failed to metadataOutput stop '+ err.code); - }); + function stopMetadataOutput(metadataOutput: camera.MetadataOutput): void { + metadataOutput.stop().then(() => { + console.info('Callback returned with metadataOutput stopped.'); + }).catch((err: BusinessError) => { + console.info('Failed to metadataOutput stop '+ err.code); + }); + } ``` ## 状态监听 @@ -48,9 +61,11 @@ Metadata主要是通过一个TAG(Key),去找对应的Data,用于传递 - 通过注册监听获取metadata对象,监听事件固定为metadataObjectsAvailable。检测到有效metadata数据时,callback返回相应的metadata数据信息,metadataOutput创建成功时可监听。 ```ts - metadataOutput.on('metadataObjectsAvailable', (err: BusinessError, metadataObjectArr: Array) => { - console.info(`metadata output metadataObjectsAvailable`); - }); + function onMetadataObjectsAvailable(metadataOutput: camera.MetadataOutput): void { + metadataOutput.on('metadataObjectsAvailable', (err: BusinessError, metadataObjectArr: Array) => { + console.info(`metadata output metadataObjectsAvailable`); + }); + } ``` > **说明:** @@ -60,7 +75,9 @@ Metadata主要是通过一个TAG(Key),去找对应的Data,用于传递 - 通过注册回调函数,获取监听metadata流的错误结果,callback返回metadata输出接口使用错误时返回的错误码,错误码类型参见[CameraErrorCode](../reference/apis/js-apis-camera.md#cameraerrorcode)。 ```ts - metadataOutput.on('error', (metadataOutputError: BusinessError) => { - console.info(`Metadata output error code: ${metadataOutputError.code}`); - }); + function onMetadataError(metadataOutput: camera.MetadataOutput): void { + metadataOutput.on('error', (metadataOutputError: BusinessError) => { + console.info(`Metadata output error code: ${metadataOutputError.code}`); + }); + } ``` diff --git a/zh-cn/application-dev/media/camera-mode.md b/zh-cn/application-dev/media/camera-mode.md index 7657436bed..3bc2c80f3b 100644 --- a/zh-cn/application-dev/media/camera-mode.md +++ b/zh-cn/application-dev/media/camera-mode.md @@ -12,265 +12,267 @@ [各类Context的获取方式](../application-models/application-context-stage.md) ```ts import camera from '@ohos.multimedia.camera'; +import type { BusinessError } from '@ohos.base'; import image from '@ohos.multimedia.image'; -import media from '@ohos.multimedia.media'; +import type featureAbility from '@ohos.ability.featureAbility'; +async function cameraModeCase(context: featureAbility.Context, surfaceId: string): Promise { + // 创建CameraManager对象 + let cameraManager: camera.CameraManager = camera.getCameraManager(context); + if (!cameraManager) { + console.error("camera.getCameraManager error"); + return; + } + // 创建ModeManager对象 + let modeManager: camera.ModeManager = camera.getModeManager(context); + if (!cameraManager) { + console.error("camera.getModeManager error"); + return; + } + // 监听相机状态变化 + cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { + console.info(`camera : ${cameraStatusInfo.camera.cameraId}`); + console.info(`status: ${cameraStatusInfo.status}`); + }); + // 获取相机列表 + let cameraArray: Array = cameraManager.getSupportedCameras(); + if (cameraArray.length <= 0) { + console.error("cameraManager.getSupportedCameras error"); + return; + } -// 创建CameraManager对象 -let context: Context = getContext(this); -let cameraManager: camera.CameraManager = camera.getCameraManager(context); -if (!cameraManager) { - console.error("camera.getCameraManager error"); - return; -} -// 创建ModeManager对象 -let modeManager: camera.ModeManager = camera.getModeManager(context); -if (!cameraManager) { - console.error("camera.getModeManager error"); - return; -} -// 监听相机状态变化 -cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { - console.info(`camera : ${cameraStatusInfo.camera.cameraId}`); - console.info(`status: ${cameraStatusInfo.status}`); -}); -// 获取相机列表 -let cameraArray: Array = cameraManager.getSupportedCameras(); -if (cameraArray.length <= 0) { - console.error("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); // 获取相机连接类型 + } -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); // 获取相机连接类型 -} + // 获取模式列表 + let cameraModeArray: Array = modeManager.getSupportedModes(cameraArray[0]); + if (cameraModeArray.length <= 0) { + console.error("modeManager.getSupportedModes error"); + return; + } + // 创建相机输入流 + let cameraInput: camera.CameraInput; + try { + cameraInput = cameraManager.createCameraInput(cameraArray[0]); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to createCameraInput errorCode = ' + err.code); + } + // 监听cameraInput错误信息 + let cameraDevice: camera.CameraDevice = cameraArray[0]; + cameraInput.on('error', cameraDevice, (error: BusinessError) => { + console.info(`Camera input error code: ${error.code}`); + }) -// 获取模式列表 -let cameraModeArray: Array = modeManager.getSupportedModes(cameraArray[0]); -if (cameraModeArray.length <= 0) { - console.error("modeManager.getSupportedModes error"); - return; -} -// 创建相机输入流 -let cameraInput: camera.CameraInput; -try { - cameraInput = cameraManager.createCameraInput(cameraArray[0]); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to createCameraInput errorCode = ' + err.code); -} -// 监听cameraInput错误信息 -let cameraDevice: camera.CameraDevice = cameraArray[0]; -cameraInput.on('error', cameraDevice, (error: BusinessError) => { - console.info(`Camera input error code: ${error.code}`); -}) + // 打开相机 + await cameraInput.open(); -// 打开相机 -await cameraInput.open(); + // 获取当前模式相机设备支持的输出流能力 + let cameraOutputCap: camera.CameraOutputCapability = modeManager.getSupportedOutputCapability(cameraArray[0], cameraModeArray[0]); + if (!cameraOutputCap) { + console.error("modeManager.getSupportedOutputCapability error"); + return; + } + console.info("outputCapability: " + JSON.stringify(cameraOutputCap)); -// 获取当前模式相机设备支持的输出流能力 -let cameraOutputCap: camera.CameraOutputCapability = modeManager.getSupportedOutputCapability(cameraArray[0], cameraModeArray[0]); -if (!cameraOutputCap) { - console.error("modeManager.getSupportedOutputCapability error"); - return; -} -console.info("outputCapability: " + JSON.stringify(cameraOutputCap)); + let previewProfilesArray: Array = cameraOutputCap.previewProfiles; + if (!previewProfilesArray) { + console.error("createOutput previewProfilesArray == null || undefined"); + } -let previewProfilesArray: Array = cameraOutputCap.previewProfiles; -if (!previewProfilesArray) { - console.error("createOutput previewProfilesArray == null || undefined"); -} + let photoProfilesArray: Array = cameraOutputCap.photoProfiles; + if (!photoProfilesArray) { + console.error("createOutput photoProfilesArray == null || undefined"); + } -let photoProfilesArray: Array = cameraOutputCap.photoProfiles; -if (!photoProfilesArray) { - console.error("createOutput photoProfilesArray == null || undefined"); -} + // 创建预览输出流,其中参数 surfaceId 参考上文 XComponent 组件,预览流为XComponent组件提供的surface + let previewOutput: camera.PreviewOutput; + try { + previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId); + } catch (error) { + let err = error as BusinessError; + console.error("Failed to create the PreviewOutput instance. error code:" + err.code); + } + // 监听预览输出错误信息 + previewOutput.on('error', (error: BusinessError) => { + console.info(`Preview output error code: ${error.code}`); + }) + // 创建ImageReceiver对象,并设置照片参数:分辨率大小是根据前面 photoProfilesArray 获取的当前设备所支持的拍照分辨率大小去设置 + let imageReceiver: image.ImageReceiver = image.createImageReceiver(1920, 1080, 4, 8); + // 获取照片显示SurfaceId + let photoSurfaceId: string = await imageReceiver.getReceivingSurfaceId(); + // 创建拍照输出流 + let photoOutput: camera.PhotoOutput; + try { + photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to createPhotoOutput errorCode = ' + err.code); + } + //创建portrait会话 + let portraitSession: camera.CaptureSession; + try { + portraitSession = modeManager.createCaptureSession(cameraModeArray[0]); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to create the CaptureSession instance. errorCode = ' + err.code); + } -// 创建预览输出流,其中参数 surfaceId 参考上文 XComponent 组件,预览流为XComponent组件提供的surface -let previewOutput: camera.PreviewOutput; -try { - previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId); -} catch (error) { - let err = error as BusinessError; - console.error("Failed to create the PreviewOutput instance. error code:" + err.code); -} -// 监听预览输出错误信息 -previewOutput.on('error', (error: BusinessError) => { - console.info(`Preview output error code: ${error.code}`); -}) -// 创建ImageReceiver对象,并设置照片参数:分辨率大小是根据前面 photoProfilesArray 获取的当前设备所支持的拍照分辨率大小去设置 -let imageReceiver: image.ImageReceiver = image.createImageReceiver(1920, 1080, 4, 8); -// 获取照片显示SurfaceId -let photoSurfaceId: string = await imageReceiver.getReceivingSurfaceId(); -// 创建拍照输出流 -let photoOutput: camera.PhotoOutput; -try { - photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to createPhotoOutput errorCode = ' + err.code); -} -//创建portrait会话 -let portraitSession: camera.CaptureSession; -try { - portraitSession = modeManager.createCaptureSession(cameraModeArray[0]); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to create the CaptureSession instance. errorCode = ' + err.code); -} + // 监听portraitSession错误信息 + portraitSession.on('error', (error: BusinessError) => { + console.info(`Capture session error code: ${error.code}`); + }); -// 监听portraitSession错误信息 -portraitSession.on('error', (error: BusinessError) => { - console.info(`Capture session error code: ${error.code}`); -}); + // 开始配置会话 + try { + portraitSession.beginConfig(); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to beginConfig. errorCode = ' + err.code); + } -// 开始配置会话 -try { - portraitSession.beginConfig(); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to beginConfig. errorCode = ' + err.code); -} + // 向会话中添加相机输入流 + try { + portraitSession.addInput(cameraInput); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to addInput. errorCode = ' + err.code); + } -// 向会话中添加相机输入流 -try { - portraitSession.addInput(cameraInput); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to addInput. errorCode = ' + err.code); -} + // 向会话中添加预览输出流 + try { + portraitSession.addOutput(previewOutput); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to addOutput(previewOutput). errorCode = ' + err.code); + } -// 向会话中添加预览输出流 -try { - portraitSession.addOutput(previewOutput); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to addOutput(previewOutput). errorCode = ' + err.code); -} + // 向会话中添加拍照输出流 + try { + portraitSession.addOutput(photoOutput); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to addOutput(photoOutput). errorCode = ' + err.code); + } -// 向会话中添加拍照输出流 -try { - portraitSession.addOutput(photoOutput); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to addOutput(photoOutput). errorCode = ' + err.code); -} + // 提交会话配置 + await portraitSession.commitConfig(); -// 提交会话配置 -await portraitSession.commitConfig(); + // 启动会话 + await portraitSession.start().then(() => { + console.info('Promise returned to indicate the session start success.'); + }) -// 启动会话 -await portraitSession.start().then(() => { - console.info('Promise returned to indicate the session start success.'); -}) + // 获取支持的美颜类型 + let beautyTypes: Array; + try { + beautyTypes = portraitSession.getSupportedBeautyTypes(); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to get the beauty types. errorCode = ' + err.code); + } + // 获取支持的美颜类型对应的美颜强度范围 + let beautyRanges: Array; + try { + beautyRanges = portraitSession.getSupportedBeautyRanges(beautyTypes[0]); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to get the beauty types ranges. errorCode = ' + err.code); + } + // 设置美颜类型及对应的美颜强度 + try { + portraitSession.setBeauty(beautyTypes[0], beautyRanges[0]); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to set the beauty type value. errorCode = ' + err.code); + } + // 获取已经设置的美颜类型对应的美颜强度 + let beautyLevel: number; + try { + beautyLevel = portraitSession.getBeauty(beautyTypes[0]); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to get the beauty type value. errorCode = ' + err.code); + } -// 获取支持的美颜类型 -let beautyTypes: Array; -try { - beautyTypes = portraitSession.getSupportedBeautyTypes(); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to get the beauty types. errorCode = ' + err.code); -} -// 获取支持的美颜类型对应的美颜强度范围 -let beautyRanges: Array; -try { - beautyRanges = portraitSession.getSupportedBeautyRanges(beautyTypes[0]); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to get the beauty types ranges. errorCode = ' + err.code); -} -// 设置美颜类型及对应的美颜强度 -try { - portraitSession.setBeauty(beautyTypes[0], beautyRanges[0]); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to set the beauty type value. errorCode = ' + err.code); -} -// 获取已经设置的美颜类型对应的美颜强度 -let beautyLevel: number; -try { - beautyLevel = portraitSession.getBeauty(beautyTypes[0]); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to get the beauty type value. errorCode = ' + err.code); -} + // 获取支持的滤镜类型 + let filterTypes: Array; + try { + filterTypes = portraitSession.getSupportedFilters(); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to get the filter types. errorCode = ' + err.code); + } + // 设置滤镜类型 + try { + portraitSession.setFilter(filterTypes[0]); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to set the filter type value. errorCode = ' + err.code); + } + // 获取已经设置的滤镜类型 + let filter: number; + try { + filter = portraitSession.getFilter(); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to get the filter type value. errorCode = ' + err.code); + } -// 获取支持的滤镜类型 -let filterTypes: Array; -try { - filterTypes = portraitSession.getSupportedFilters(); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to get the filter types. errorCode = ' + err.code); -} -// 设置滤镜类型 -try { - portraitSession.setFilter(filterTypes[0]); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to set the filter type value. errorCode = ' + err.code); -} -// 获取已经设置的滤镜类型 -let filter: number; -try { - filter = portraitSession.getFilter(); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to get the filter type value. errorCode = ' + err.code); -} + // 获取支持的虚化类型 + let portraitTypes: Array; + try { + portraitTypes = portraitSession.getSupportedPortraitEffects(); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to get the portrait effects types. errorCode = ' + err.code); + } + // 设置虚化类型 + try { + portraitSession.setPortraitEffect(portraitTypes[0]); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to set the portrait effects value. errorCode = ' + err.code); + } + // 获取已经设置的虚化类型 + let effect: camera.PortraitEffect; + try { + effect = portraitSession.getPortraitEffect(); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to get the portrait effects value. errorCode = ' + err.code); + } -// 获取支持的虚化类型 -let portraitTypes: Array; -try { - portraitTypes = portraitSession.getSupportedPortraitEffects(); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to get the portrait effects types. errorCode = ' + err.code); -} -// 设置虚化类型 -try { - portraitSession.setPortraitEffect(portraitTypes[0]); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to set the portrait effects value. errorCode = ' + err.code); -} -// 获取已经设置的虚化类型 -let effect: camera.PortraitEffect; -try { - effect = portraitSession.getPortraitEffect(); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to get the portrait effects value. errorCode = ' + err.code); -} + let captureSettings: camera.PhotoCaptureSetting; + // 使用当前拍照设置进行拍照 + photoOutput.capture(captureSettings, async (err: BusinessError) => { + if (err) { + console.error('Failed to capture the photo ${err.message}'); + return; + } + console.info('Callback invoked to indicate the photo capture request success.'); + }); + // 停止当前会话 + portraitSession.stop(); -let captureSettings: camera.PhotoCaptureSetting; -// 使用当前拍照设置进行拍照 -photoOutput.capture(captureSettings, async (err: BusinessError) => { - if (err) { - console.error('Failed to capture the photo ${err.message}'); - return; - } - console.info('Callback invoked to indicate the photo capture request success.'); -}); -// 停止当前会话 -portraitSession.stop(); + // 释放相机输入流 + cameraInput.close(); -// 释放相机输入流 -cameraInput.close(); + // 释放预览输出流 + previewOutput.release(); -// 释放预览输出流 -previewOutput.release(); + // 释放拍照输出流 + photoOutput.release(); -// 释放拍照输出流 -photoOutput.release(); + // 释放会话 + portraitSession.release(); -// 释放会话 -portraitSession.release(); + // 会话置空 + portraitSession = null; +} -// 会话置空 -portraitSession = null; ``` diff --git a/zh-cn/application-dev/media/camera-performance-improvement.md b/zh-cn/application-dev/media/camera-performance-improvement.md index 7f1bc46078..bd1aceb385 100644 --- a/zh-cn/application-dev/media/camera-performance-improvement.md +++ b/zh-cn/application-dev/media/camera-performance-improvement.md @@ -35,8 +35,9 @@ ```js import camera from '@ohos.multimedia.camera'; +import type featureAbility from '@ohos.ability.featureAbility'; -async function Preview(context: Context, cameraInfo: camera.CameraDevice, previewProfile: camera.Profile, photoProfile: camera.Profile, surfaceId: string): Promise { +async function preview(context: featureAbility.Context, cameraInfo: camera.CameraDevice, previewProfile: camera.Profile, photoProfile: camera.Profile, surfaceId: string): Promise { const cameraManager: camera.CameraManager = camera.getCameraManager(context); const cameraInput: camera.CameraInput = cameraManager.createCameraInput(cameraInfo); const previewOutput: camera.PreviewOutput = await cameraManager.createDeferredPreviewOutput(previewProfile); @@ -84,32 +85,41 @@ async function Preview(context: Context, cameraInfo: camera.CameraDevice, previe [各类Context的获取方式](../application-models/application-context-stage.md) ```js import camera from '@ohos.multimedia.camera'; -let context: Context = getContext(this); -let cameraManager: camera.CameraManager = camera.getCameraManager(context); -let cameras: Array = cameraManager.getSupportedCameras(); -// 创建CaptureSession实例 -let captureSession: camera.CaptureSession = cameraManager.createCaptureSession(); -// 开始配置会话 -captureSession.beginConfig(); -// 把CameraInput加入到会话 -let cameraInput: camera.CameraInput = cameraManager.createCameraInput(cameras[0]); -cameraInput.open(); -captureSession.addInput(cameraInput); -// 把PhotoOutPut加入到会话 -let photoOutPut: camera.PhotoOutput = cameraManager.createPhotoOutput(photoProfile, surfaceId); -captureSession.addOutput(photoOutPut); -let isSupported: boolean = photoOutPut.isQuickThumbnailSupported(); -if (isSupported) { - // 使能快速缩略图 - photoOutPut.enableQuickThumbnail(true); - photoOutPut.on('quickThumbnail', (err: BusinessError, pixelmap: image.PixelMap) => { - if (err || pixelmap === undefined) { - console.error('photoOutPut on thumbnail failed'); - return; - } - // 显示或保存pixelmap - showOrSavePicture(pixelmap); - }) +import type { BusinessError } from '@ohos.base'; +import image from '@ohos.multimedia.image'; +import type featureAbility from '@ohos.ability.featureAbility'; + +async function enableQuickThumbnail(context: featureAbility.Context, surfaceId: string, photoProfile: camera.Profile): Promise { + let cameraManager: camera.CameraManager = camera.getCameraManager(context); + let cameras: Array = cameraManager.getSupportedCameras(); + // 创建CaptureSession实例 + let captureSession: camera.CaptureSession = cameraManager.createCaptureSession(); + // 开始配置会话 + captureSession.beginConfig(); + // 把CameraInput加入到会话 + let cameraInput: camera.CameraInput = cameraManager.createCameraInput(cameras[0]); + cameraInput.open(); + captureSession.addInput(cameraInput); + // 把PhotoOutPut加入到会话 + let photoOutPut: camera.PhotoOutput = cameraManager.createPhotoOutput(photoProfile, surfaceId); + captureSession.addOutput(photoOutPut); + let isSupported: boolean = photoOutPut.isQuickThumbnailSupported(); + if (isSupported) { + // 使能快速缩略图 + photoOutPut.enableQuickThumbnail(true); + photoOutPut.on('quickThumbnail', (err: BusinessError, pixelMap: image.PixelMap) => { + if (err || pixelMap === undefined) { + console.error('photoOutPut on thumbnail failed'); + return; + } + // 显示或保存pixelmap + showOrSavePicture(pixelMap); + }) + } +} + +function showOrSavePicture(pixelMap: image.PixelMap): void { + //do something } ``` @@ -144,13 +154,17 @@ if (isSupported) { ```js import camera from '@ohos.multimedia.camera'; - let context: Context = getContext(this); - let cameraManager: camera.CameraManager = camera.getCameraManager(context); - try { - cameraManager.prelaunch(); - } catch (error) { - let err = error as BusinessError; - console.error(`catch error: Code: ${err.code}, message: ${err.message}`); + import type { BusinessError } from '@ohos.base'; + import type featureAbility from '@ohos.ability.featureAbility'; + + function preLaunch(context: featureAbility.Context): void { + let cameraManager: camera.CameraManager = camera.getCameraManager(context); + try { + cameraManager.prelaunch(); + } catch (error) { + let err = error as BusinessError; + console.error(`catch error: Code: ${err.code}, message: ${err.message}`); + } } ``` @@ -162,15 +176,19 @@ if (isSupported) { ```js import camera from '@ohos.multimedia.camera'; - let context: Context = getContext(this); - let cameraManager: camera.CameraManager = camera.getCameraManager(context); - let cameras: Array = cameraManager.getSupportedCameras(); - if(cameraManager.isPrelaunchSupported(cameras[0])) { - try { - cameraManager.setPrelaunchConfig({cameraDevice: cameras[0]}); - } catch (error) { - let err = error as BusinessError; - console.error(`catch error: Code: ${err.code}, message: ${err.message}`); + import type { BusinessError } from '@ohos.base'; + import type featureAbility from '@ohos.ability.featureAbility'; + + function setPreLaunchConfig(context: featureAbility.Context): void { + let cameraManager: camera.CameraManager = camera.getCameraManager(context); + let cameras: Array = cameraManager.getSupportedCameras(); + if(cameraManager.isPrelaunchSupported(cameras[0])) { + try { + cameraManager.setPrelaunchConfig({cameraDevice: cameras[0]}); + } catch (error) { + let err = error as BusinessError; + console.error(`catch error: Code: ${err.code}, message: ${err.message}`); + } } } ``` diff --git a/zh-cn/application-dev/media/camera-preview.md b/zh-cn/application-dev/media/camera-preview.md index ccb84119ac..838f4dee9b 100644 --- a/zh-cn/application-dev/media/camera-preview.md +++ b/zh-cn/application-dev/media/camera-preview.md @@ -6,55 +6,74 @@ 详细的API说明请参考[Camera API参考](../reference/apis/js-apis-camera.md)。 -1. 创建Surface。 +1. 导入camera接口,接口中提供了相机相关的属性和方法,导入方法如下。 + + ```ts + import camera from '@ohos.multimedia.camera'; + import type { BusinessError } from '@ohos.base'; + ``` + +2. 创建Surface。 XComponent组件为预览流提供的Surface,而XComponent的能力由UI提供,相关介绍可参考[XComponent组件参考](../reference/arkui-ts/ts-basic-components-xcomponent.md)。 - ```ts + ```ets + // xxx.ets // 创建XComponentController - mXComponentController: XComponentController = new XComponentController; - build() { - Flex() { - // 创建XComponent - XComponent({ - id: '', - type: 'surface', - libraryname: '', - controller: this.mXComponentController - }) - .onLoad(() => { - // 设置Surface宽高(1920*1080),预览尺寸设置参考前面 previewProfilesArray 获取的当前设备所支持的预览分辨率大小去设置 - this.mXComponentController.setXComponentSurfaceSize({surfaceWidth:1920,surfaceHeight:1080}); - // 获取Surface ID - globalThis.surfaceId = this.mXComponentController.getXComponentSurfaceId(); - }) - .width('1920px') - .height('1080px') + @Component + struct XComponentPage { + // 创建XComponentController + mXComponentController: XComponentController = new XComponentController; + surfaceId: string; + + build() { + Flex() { + // 创建XComponent + XComponent({ + id: '', + type: 'surface', + libraryname: '', + controller: this.mXComponentController + }) + .onLoad(() => { + // 设置Surface宽高(1920*1080),预览尺寸设置参考前面 previewProfilesArray 获取的当前设备所支持的预览分辨率大小去设置 + this.mXComponentController.setXComponentSurfaceSize({surfaceWidth:1920,surfaceHeight:1080}); + // 获取Surface ID + this.surfaceId: string = this.mXComponentController.getXComponentSurfaceId(); + }) + .width('1920px') + .height('1080px') + } } } ``` -2. 通过CameraOutputCapability类中的previewProfiles()方法获取当前设备支持的预览能力,返回previewProfilesArray数组 。通过createPreviewOutput()方法创建预览输出流,其中,createPreviewOutput()方法中的两个参数分别是previewProfilesArray数组中的第一项和步骤一中获取的surfaceId。 +3. 通过CameraOutputCapability类中的previewProfiles()方法获取当前设备支持的预览能力,返回previewProfilesArray数组 。通过createPreviewOutput()方法创建预览输出流,其中,createPreviewOutput()方法中的两个参数分别是previewProfilesArray数组中的第一项和步骤一中获取的surfaceId。 ```ts - let previewProfilesArray: Array = cameraOutputCapability.previewProfiles; - let previewOutput: camera.PreviewOutput; - try { - previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId); - } catch (error) { - let err = error as BusinessError; - console.error("Failed to create the PreviewOutput instance. error code: " + err.code); + function getPreviewOutput(cameraManager: camera.CameraManager, cameraOutputCapability: camera.CameraOutputCapability, surfaceId: string): camera.PreviewOutput { + let previewProfilesArray: Array = cameraOutputCapability.previewProfiles; + let previewOutput: camera.PreviewOutput; + try { + previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId); + } catch (error) { + let err = error as BusinessError; + console.error("Failed to create the PreviewOutput instance. error code: " + err.code); + } + return previewOutput; } ``` -3. 使能。通过start()方法输出预览流,接口调用失败会返回相应错误码,错误码类型参见[CameraErrorCode](../reference/apis/js-apis-camera.md#cameraerrorcode)。 +4. 使能。通过start()方法输出预览流,接口调用失败会返回相应错误码,错误码类型参见[CameraErrorCode](../reference/apis/js-apis-camera.md#cameraerrorcode)。 ```ts - previewOutput.start().then(() => { - console.info('Callback returned with previewOutput started.'); - }).catch((err: BusinessError) => { - console.info('Failed to previewOutput start '+ err.code); - }); + function startPreviewOutput(previewOutput: camera.PreviewOutput): void { + previewOutput.start().then(() => { + console.info('Callback returned with previewOutput started.'); + }).catch((err: BusinessError) => { + console.info('Failed to previewOutput start '+ err.code); + }); + } ``` @@ -65,23 +84,29 @@ - 通过注册固定的frameStart回调函数获取监听预览启动结果,previewOutput创建成功时即可监听,预览第一次曝光时触发,有该事件返回结果则认为预览流已启动。 ```ts - previewOutput.on('frameStart', () => { - console.info('Preview frame started'); - }); + function onPreviewOutputFrameStart(previewOutput: camera.PreviewOutput): void { + previewOutput.on('frameStart', () => { + console.info('Preview frame started'); + }); + } ``` - 通过注册固定的frameEnd回调函数获取监听预览结束结果,previewOutput创建成功时即可监听,预览完成最后一帧时触发,有该事件返回结果则认为预览流已结束。 ```ts - previewOutput.on('frameEnd', () => { - console.info('Preview frame ended'); - }); + function onPreviewOutputFrameEnd(previewOutput: camera.PreviewOutput): void { + previewOutput.on('frameEnd', () => { + console.info('Preview frame ended'); + }); + } ``` - 通过注册固定的error回调函数获取监听预览输出错误结果,callback返回预览输出接口使用错误时对应的错误码,错误码类型参见[CameraErrorCode](../reference/apis/js-apis-camera.md#cameraerrorcode)。 ```ts - previewOutput.on('error', (previewOutputError: BusinessError) => { - console.info(`Preview output error code: ${previewOutputError.code}`); - }); + function onPreviewOutputError(previewOutput: camera.PreviewOutput): void { + previewOutput.on('error', (previewOutputError: BusinessError) => { + console.info(`Preview output error code: ${previewOutputError.code}`); + }); + } ``` diff --git a/zh-cn/application-dev/media/camera-recording-case.md b/zh-cn/application-dev/media/camera-recording-case.md index 5b9d965fc2..d957680100 100644 --- a/zh-cn/application-dev/media/camera-recording-case.md +++ b/zh-cn/application-dev/media/camera-recording-case.md @@ -11,236 +11,266 @@ [各类Context的获取方式](../application-models/application-context-stage.md) ```ts import camera from '@ohos.multimedia.camera'; +import type { BusinessError } from '@ohos.base'; import media from '@ohos.multimedia.media'; +import type featureAbility from '@ohos.ability.featureAbility'; -// 创建CameraManager对象 -let context: Context = getContext(this); -let cameraManager: camera.CameraManager = camera.getCameraManager(context); -if (!cameraManager) { - console.error("camera.getCameraManager error"); - return; -} - -// 监听相机状态变化 -cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { - console.log(`camera : ${cameraStatusInfo.camera.cameraId}`); - console.log(`status: ${cameraStatusInfo.status}`); -}); - -// 获取相机列表 -let cameraArray: Array = cameraManager.getSupportedCameras(); -if (cameraArray.length <= 0) { - console.error("cameraManager.getSupportedCameras error") - return; -} -// 获取相机设备支持的输出流能力 -let cameraOutputCap: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraArray[0]); -if (!cameraOutputCap) { - console.error("cameraManager.getSupportedOutputCapability error") - return; -} -console.log("outputCapability: " + JSON.stringify(cameraOutputCap)); - -let previewProfilesArray: Array = cameraOutputCap.previewProfiles; -if (!previewProfilesArray) { - console.error("createOutput previewProfilesArray == null || undefined"); -} - -let photoProfilesArray: Array = cameraOutputCap.photoProfiles; -if (!photoProfilesArray) { - console.error("createOutput photoProfilesArray == null || undefined"); -} +async function videoRecording(context: featureAbility.Context, surfaceId: string): Promise { + // 创建CameraManager对象 + let cameraManager: camera.CameraManager = camera.getCameraManager(context); + if (!cameraManager) { + console.error("camera.getCameraManager error"); + return; + } -let videoProfilesArray: Array = cameraOutputCap.videoProfiles; -if (!videoProfilesArray) { - console.error("createOutput videoProfilesArray == null || undefined"); -} + // 监听相机状态变化 + cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { + console.log(`camera : ${cameraStatusInfo.camera.cameraId}`); + console.log(`status: ${cameraStatusInfo.status}`); + }); -let metadataObjectTypesArray: Array = cameraOutputCap.supportedMetadataObjectTypes; -if (!metadataObjectTypesArray) { - console.error("createOutput metadataObjectTypesArray == null || undefined"); -} + // 获取相机列表 + let cameraArray: Array = cameraManager.getSupportedCameras(); + if (cameraArray.length <= 0) { + console.error("cameraManager.getSupportedCameras error") + return; + } + // 获取相机设备支持的输出流能力 + let cameraOutputCap: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraArray[0]); + if (!cameraOutputCap) { + console.error("cameraManager.getSupportedOutputCapability error") + return; + } + console.log("outputCapability: " + JSON.stringify(cameraOutputCap)); -// 配置参数以实际硬件设备支持的范围为准 -let AVRecorderProfile = { - audioBitrate : 48000, - audioChannels : 2, - audioCodec : media.CodecMimeType.AUDIO_AAC, - audioSampleRate : 48000, - fileFormat : media.ContainerFormatType.CFT_MPEG_4, - videoBitrate : 2000000, - videoCodec : media.CodecMimeType.VIDEO_MPEG4, - videoFrameWidth : 640, - videoFrameHeight : 480, - videoFrameRate : 30 -}; -let aVRecorderConfig = { - audioSourceType : media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC, - videoSourceType : media.VideoSourceType.VIDEO_SOURCE_TYPE_SURFACE_YUV, - profile : AVRecorderProfile, - url : 'fd://', // 文件需先由调用者创建,赋予读写权限,将文件fd传给此参数,eg.fd://45--file:///data/media/01.mp4 - rotation : 0, // 合理值0、90、180、270,非合理值prepare接口将报错 - location : { latitude : 30, longitude : 130 } -}; - -let avRecorder: media.AVRecorder; -media.createAVRecorder((error: BusinessError, recorder: media.AVRecorder) => { - if (recorder != null) { - avRecorder = recorder; - console.log('createAVRecorder success'); - } else { - console.log(`createAVRecorder fail, error:${error}`); - } -}); - -avRecorder.prepare(aVRecorderConfig, (err: BusinessError) => { - if (err == null) { - console.log('prepare success'); - } else { - console.log('prepare failed and error is ' + err.message); - } -}) - -let videoSurfaceId: string = null; // 该surfaceID用于传递给相机接口创造videoOutput -avRecorder.getInputSurface((err: BusinessError, surfaceId: string) => { - if (err == null) { - console.log('getInputSurface success'); - videoSurfaceId = surfaceId; - } else { - console.log('getInputSurface failed and error is ' + err.message); - } -}); - -// 创建VideoOutput对象 -let videoOutput: camera.VideoOutput; -try { - videoOutput = cameraManager.createVideoOutput(videoProfilesArray[0], videoSurfaceId) -} catch (error) { - console.error('Failed to create the videoOutput instance. errorCode = ' + error.code); -} + let previewProfilesArray: Array = cameraOutputCap.previewProfiles; + if (!previewProfilesArray) { + console.error("createOutput previewProfilesArray == null || undefined"); + } -// 监听视频输出错误信息 -videoOutput.on('error', (error: BusinessError) => { - console.log(`Preview output error code: ${error.code}`); -}); - -//创建会话 -let captureSession: camera.CaptureSession; -try { - captureSession = cameraManager.createCaptureSession(); -} catch (error) { - console.error('Failed to create the CaptureSession instance. errorCode = ' + error.code); -} + let photoProfilesArray: Array = cameraOutputCap.photoProfiles; + if (!photoProfilesArray) { + console.error("createOutput photoProfilesArray == null || undefined"); + } -// 监听session错误信息 -captureSession.on('error', (error: BusinessError) => { - console.log(`Capture session error code: ${error.code}`); -}); + let videoProfilesArray: Array = cameraOutputCap.videoProfiles; + if (!videoProfilesArray) { + console.error("createOutput videoProfilesArray == null || undefined"); + } -// 开始配置会话 -try { - captureSession.beginConfig(); -} catch (error) { - console.error('Failed to beginConfig. errorCode = ' + error.code); -} + let metadataObjectTypesArray: Array = cameraOutputCap.supportedMetadataObjectTypes; + if (!metadataObjectTypesArray) { + console.error("createOutput metadataObjectTypesArray == null || undefined"); + } -// 创建相机输入流 -let cameraInput: camera.CameraInput; -try { - cameraInput = cameraManager.createCameraInput(cameraArray[0]); -} catch (error) { - console.error('Failed to createCameraInput errorCode = ' + error.code); -} + // 配置参数以实际硬件设备支持的范围为准 + let aVRecorderProfile: media.AVRecorderProfile = { + audioBitrate: 48000, + audioChannels: 2, + audioCodec: media.CodecMimeType.AUDIO_AAC, + audioSampleRate: 48000, + fileFormat: media.ContainerFormatType.CFT_MPEG_4, + videoBitrate: 2000000, + videoCodec: media.CodecMimeType.VIDEO_MPEG4, + videoFrameWidth: 640, + videoFrameHeight: 480, + videoFrameRate: 30 + }; + let aVRecorderConfig: media.AVRecorderConfig = { + audioSourceType: media.AudioSourceType.AUDIO_SOURCE_TYPE_MIC, + videoSourceType: media.VideoSourceType.VIDEO_SOURCE_TYPE_SURFACE_YUV, + profile: aVRecorderProfile, + url: 'fd://', // 文件需先由调用者创建,赋予读写权限,将文件fd传给此参数,eg.fd://45--file:///data/media/01.mp4 + rotation: 0, // 合理值0、90、180、270,非合理值prepare接口将报错 + location: { latitude: 30, longitude: 130 } + }; + + let avRecorder: media.AVRecorder; + media.createAVRecorder((error: BusinessError, recorder: media.AVRecorder) => { + if (recorder != null) { + avRecorder = recorder; + console.log('createAVRecorder success'); + } else { + console.log(`createAVRecorder fail, error:${error}`); + } + }); + + avRecorder.prepare(aVRecorderConfig, (err: BusinessError) => { + if (err == null) { + console.log('prepare success'); + } else { + console.log(`prepare failed. error: ${JSON.stringify(err)}`); + } + }) + + let videoSurfaceId: string = null; // 该surfaceID用于传递给相机接口创造videoOutput + avRecorder.getInputSurface((err: BusinessError, surfaceId: string) => { + if (err == null) { + console.log('getInputSurface success'); + videoSurfaceId = surfaceId; + } else { + console.log(`getInputSurface failed. error: ${JSON.stringify(err)}`); + } + }); + + // 创建VideoOutput对象 + let videoOutput: camera.VideoOutput; + try { + videoOutput = cameraManager.createVideoOutput(videoProfilesArray[0], videoSurfaceId); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to create the videoOutput instance. error: ${JSON.stringify(err)}`); + } -// 监听cameraInput错误信息 -let cameraDevice: camera.CameraDevice = cameraArray[0]; -cameraInput.on('error', cameraDevice, (error: BusinessError) => { - console.log(`Camera input error code: ${error.code}`); -}); + // 监听视频输出错误信息 + videoOutput.on('error', (error: BusinessError) => { + console.log(`Preview output error code: ${error.code}`); + }); + + //创建会话 + let captureSession: camera.CaptureSession; + try { + captureSession = cameraManager.createCaptureSession(); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to create the CaptureSession instance. error: ${JSON.stringify(err)}`); + } -// 打开相机 -await cameraInput.open(); + // 监听session错误信息 + captureSession.on('error', (error: BusinessError) => { + console.log(`Capture session error code: ${error.code}`); + }); + + // 开始配置会话 + try { + captureSession.beginConfig(); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to beginConfig. error: ${JSON.stringify(err)}`); + } -// 向会话中添加相机输入流 -try { - captureSession.addInput(cameraInput); -} catch (error) { - console.error('Failed to addInput. errorCode = ' + error.code); -} + // 创建相机输入流 + let cameraInput: camera.CameraInput; + try { + cameraInput = cameraManager.createCameraInput(cameraArray[0]); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to createCameraInput. error: ${JSON.stringify(err)}`); + } -// 创建预览输出流,其中参数 surfaceId 参考下面 XComponent 组件,预览流为XComponent组件提供的surface -let previewOutput: camera.PreviewOutput; -try { - previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId); -} catch (error) { - console.error("Failed to create the PreviewOutput instance.") -} + // 监听cameraInput错误信息 + let cameraDevice: camera.CameraDevice = cameraArray[0]; + cameraInput.on('error', cameraDevice, (error: BusinessError) => { + console.log(`Camera input error code: ${error.code}`); + }); + + // 打开相机 + try { + await cameraInput.open(); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to open cameraInput. error: ${JSON.stringify(err)}`); + } -// 向会话中添加预览输入流 -try { - captureSession.addOutput(previewOutput); -} catch (error) { - console.error('Failed to addOutput(previewOutput). errorCode = ' + error.code); -} + // 向会话中添加相机输入流 + try { + captureSession.addInput(cameraInput); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to add cameraInput. error: ${JSON.stringify(err)}`); + } -// 向会话中添加录像输出流 -try { - captureSession.addOutput(videoOutput); -} catch (error) { - console.error('Failed to addOutput(videoOutput). errorCode = ' + error.code); -} + // 创建预览输出流,其中参数 surfaceId 参考下面 XComponent 组件,预览流为XComponent组件提供的surface + let previewOutput: camera.PreviewOutput; + try { + previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to create the PreviewOutput instance. error: ${JSON.stringify(err)}`); + } -// 提交会话配置 -await captureSession.commitConfig(); + // 向会话中添加预览输入流 + try { + captureSession.addOutput(previewOutput); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to add previewOutput. error: ${JSON.stringify(err)}`); + } -// 启动会话 -await captureSession.start().then(() => { - console.log('Promise returned to indicate the session start success.'); -}); + // 向会话中添加录像输出流 + try { + captureSession.addOutput(videoOutput); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to add videoOutput. error: ${JSON.stringify(err)}`); + } -// 启动录像输出流 -videoOutput.start(async (err: BusinessError) => { - if (err) { - console.error('Failed to start the video output ${err.message}'); - return; + // 提交会话配置 + try { + await captureSession.commitConfig(); + } catch (error) { + let err = error as BusinessError; + console.error(`captureSession commitConfig error: ${JSON.stringify(err)}`); } - console.log('Callback invoked to indicate the video output start success.'); -}); -// 开始录像 -avRecorder.start().then(() => { - console.log('videoRecorder start success'); -}); + // 启动会话 + try { + await captureSession.start(); + } catch (error) { + let err = error as BusinessError; + console.error(`captureSession start error: ${JSON.stringify(err)}`); + } -// 停止录像输出流 -videoOutput.stop((err: BusinessError) => { - if (err) { - console.error('Failed to stop the video output ${err.message}'); - return; + // 启动录像输出流 + videoOutput.start((err: BusinessError) => { + if (err) { + console.error(`Failed to start the video output. error: ${JSON.stringify(err)}`); + return; + } + console.log('Callback invoked to indicate the video output start success.'); + }); + + // 开始录像 + try { + await avRecorder.start(); + } catch (error) { + let err = error as BusinessError; + console.error(`avRecorder start error: ${JSON.stringify(err)}`); } - console.log('Callback invoked to indicate the video output stop success.'); -}); -// 停止录像 -avRecorder.stop().then(() => { - console.log('stop success'); -}); + // 停止录像输出流 + videoOutput.stop((err: BusinessError) => { + if (err) { + console.error(`Failed to stop the video output. error: ${JSON.stringify(err)}`); + return; + } + console.log('Callback invoked to indicate the video output stop success.'); + }); + + // 停止录像 + try { + await avRecorder.stop(); + } catch (error) { + let err = error as BusinessError; + console.error(`avRecorder stop error: ${JSON.stringify(err)}`); + } -// 停止当前会话 -captureSession.stop(); + // 停止当前会话 + captureSession.stop(); -// 释放相机输入流 -cameraInput.close(); + // 释放相机输入流 + cameraInput.close(); -// 释放预览输出流 -previewOutput.release(); + // 释放预览输出流 + previewOutput.release(); -// 释放录像输出流 -videoOutput.release(); + // 释放录像输出流 + videoOutput.release(); -// 释放会话 -captureSession.release(); + // 释放会话 + captureSession.release(); -// 会话置空 -captureSession = null; + // 会话置空 + captureSession = null; +} ``` diff --git a/zh-cn/application-dev/media/camera-recording.md b/zh-cn/application-dev/media/camera-recording.md index 5847ea529c..8e8a8433ff 100644 --- a/zh-cn/application-dev/media/camera-recording.md +++ b/zh-cn/application-dev/media/camera-recording.md @@ -9,6 +9,7 @@ 1. 导入media模块。创建拍照输出流的SurfaceId以及拍照输出的数据,都需要用到系统提供的[media接口](../reference/apis/js-apis-media.md)能力,导入media接口的方法如下。 ```ts + import type { BusinessError } from '@ohos.base'; import media from '@ohos.multimedia.media'; ``` @@ -17,32 +18,27 @@ 系统提供的media接口可以创建一个录像AVRecorder实例,通过该实例的getInputSurface方法获取SurfaceId,与录像输出流做关联,处理录像输出流输出的数据。 ```ts - let avRecorder: media.AVRecorder; - media.createAVRecorder((error: BusinessError, recorder: media.AVRecorder) => { - if (recorder != null) { - avRecorder = recorder; - console.info('createAVRecorder success'); - } else { - console.info(`createAVRecorder fail, error:${error}`); - } - }); - // aVRecorderConfig可参考下一章节 - let aVRecorderConfig: media.AVRecorderConfig; - avRecorder.prepare(aVRecorderConfig, (err: BusinessError) => { - if (err == null) { - console.log('prepare success'); - } else { - console.log('prepare failed and error is ' + err.message); - } - }); + async function getVideoSurfaceId(aVRecorderConfig: media.AVRecorderConfig): Promise { // aVRecorderConfig可参考下一章节 + let avRecorder: media.AVRecorder; + media.createAVRecorder((error: BusinessError, recorder: media.AVRecorder) => { + if (recorder != null) { + avRecorder = recorder; + console.info('createAVRecorder success'); + } else { + console.info(`createAVRecorder fail, error:${error}`); + } + }); - let videoSurfaceId: string = null; - avRecorder.getInputSurface().then((surfaceId: string) => { - console.info('getInputSurface success'); - videoSurfaceId = surfaceId; - }).catch((err: BusinessError) => { - console.info('getInputSurface failed and catch error is ' + err.message); - }); + avRecorder.prepare(aVRecorderConfig, (err: BusinessError) => { + if (err == null) { + console.log('prepare success'); + } else { + console.log('prepare failed and error is ' + err.message); + } + }); + let videoSurfaceId = await avRecorder.getInputSurface(); + return videoSurfaceId; + } ``` 3. 创建录像输出流。 @@ -50,44 +46,49 @@ 通过CameraOutputCapability类中的videoProfiles,可获取当前设备支持的录像输出流。然后,定义创建录像的参数,通过createVideoOutput方法创建录像输出流。 ```ts - let videoProfilesArray: Array = cameraOutputCapability.videoProfiles; - if (!videoProfilesArray) { - console.error("createOutput videoProfilesArray == null || undefined"); - } - - // 创建视频录制的参数 - let videoConfig = { - videoSourceType: media.VideoSourceType.VIDEO_SOURCE_TYPE_SURFACE_YUV, - profile: { + function getVideoOutput(cameraManager: camera.CameraManager, videoSurfaceId: string, cameraOutputCapability: camera.CameraOutputCapability): camera.VideoOutput { + let videoProfilesArray: Array = cameraOutputCapability.videoProfiles; + if (!videoProfilesArray) { + console.error("createOutput videoProfilesArray == null || undefined"); + return null; + } + // AVRecorderProfile + let aVRecorderProfile: media.AVRecorderProfile = { fileFormat : media.ContainerFormatType.CFT_MPEG_4, // 视频文件封装格式,只支持MP4 videoBitrate : 100000, // 视频比特率 videoCodec : media.CodecMimeType.VIDEO_MPEG4, // 视频文件编码格式,支持mpeg4和avc两种格式 videoFrameWidth : 640, // 视频分辨率的宽 videoFrameHeight : 480, // 视频分辨率的高 videoFrameRate : 30 // 视频帧率 - }, - url: 'fd://35', - rotation: 90 // 90°为默认竖屏显示角度,如果由于设备原因或应用期望以其他方式显示等原因,请根据实际情况调整该参数 - } - // 创建avRecorder - let avRecorder: media.AVRecorder; - media.createAVRecorder((error: BusinessError, recorder: media.AVRecorder) => { - if (recorder != null) { - avRecorder = recorder; - console.info('createAVRecorder success'); - } else { - console.info(`createAVRecorder fail, error:${error}`); } - }); - // 设置视频录制的参数 - avRecorder.prepare(videoConfig); - // 创建VideoOutput对象 - let videoOutput: camera.VideoOutput; - try { - videoOutput = cameraManager.createVideoOutput(videoProfilesArray[0], videoSurfaceId); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to create the videoOutput instance. errorCode = ' + err.code); + // 创建视频录制的参数 + let aVRecorderConfig: media.AVRecorderConfig = { + videoSourceType: media.VideoSourceType.VIDEO_SOURCE_TYPE_SURFACE_YUV, + profile: aVRecorderProfile, + url: 'fd://35', + rotation: 90 // 90°为默认竖屏显示角度,如果由于设备原因或应用期望以其他方式显示等原因,请根据实际情况调整该参数 + } + // 创建avRecorder + let avRecorder: media.AVRecorder; + media.createAVRecorder((error: BusinessError, recorder: media.AVRecorder) => { + if (recorder != null) { + avRecorder = recorder; + console.info('createAVRecorder success'); + } else { + console.info(`createAVRecorder fail, error:${error}`); + } + }); + // 设置视频录制的参数 + avRecorder.prepare(aVRecorderConfig); + // 创建VideoOutput对象 + let videoOutput: camera.VideoOutput; + try { + videoOutput = cameraManager.createVideoOutput(videoProfilesArray[0], videoSurfaceId); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to create the videoOutput instance. errorCode = ' + err.code); + } + return videoOutput; } ``` @@ -96,17 +97,21 @@ 先通过videoOutput的start方法启动录像输出流,再通过avRecorder的start方法开始录像。 ```ts - videoOutput.start(async (err: BusinessError) => { - if (err) { - console.error('Failed to start the video output ${err.message}'); - return; + async function startVideo(videoOutput: camera.VideoOutput, avRecorder: media.AVRecorder): Promise { + videoOutput.start(async (err: BusinessError) => { + if (err) { + console.error('Failed to start the video output ${err.message}'); + return; + } + console.info('Callback invoked to indicate the video output start success.'); + }); + try { + await avRecorder.start(); + } catch (error) { + let err = error as BusinessError; + console.error(`avRecorder start error: ${JSON.stringify(err)}`); } - console.info('Callback invoked to indicate the video output start success.'); - }); - - avRecorder.start().then(() => { - console.info('avRecorder start success'); - }); + } ``` 5. 停止录像。 @@ -114,17 +119,21 @@ 先通过avRecorder的stop方法停止录像,再通过videoOutput的stop方法停止录像输出流。 ```ts - videoRecorder.stop().then(() => { - console.info('stop success'); - }); - - videoOutput.stop((err: BusinessError) => { - if (err) { - console.error('Failed to stop the video output ${err.message}'); - return; + async function stopVideo(videoOutput: camera.VideoOutput, avRecorder: media.AVRecorder): Promise { + try { + await avRecorder.stop(); + } catch (error) { + let err = error as BusinessError; + console.error(`avRecorder stop error: ${JSON.stringify(err)}`); } - console.info('Callback invoked to indicate the video output stop success.'); - }); + videoOutput.stop((err: BusinessError) => { + if (err) { + console.error('Failed to stop the video output ${err.message}'); + return; + } + console.info('Callback invoked to indicate the video output stop success.'); + }); + } ``` @@ -135,23 +144,29 @@ - 通过注册固定的frameStart回调函数获取监听录像开始结果,videoOutput创建成功时即可监听,录像第一次曝光时触发,有该事件返回结果则认为录像开始。 ```ts - videoOutput.on('frameStart', () => { - console.info('Video frame started'); - }); + function onVideoOutputFrameStart(videoOutput: camera.VideoOutput): void { + videoOutput.on('frameStart', () => { + console.info('Video frame started'); + }); + } ``` - 通过注册固定的frameEnd回调函数获取监听录像结束结果,videoOutput创建成功时即可监听,录像完成最后一帧时触发,有该事件返回结果则认为录像流已结束。 ```ts - videoOutput.on('frameEnd', () => { - console.info('Video frame ended'); - }); + function onVideoOutputFrameEnd(videoOutput: camera.VideoOutput): void { + videoOutput.on('frameEnd', () => { + console.info('Video frame ended'); + }); + } ``` - 通过注册固定的error回调函数获取监听录像输出错误结果,callback返回预览输出接口使用错误时对应的错误码,错误码类型参见[CameraErrorCode](../reference/apis/js-apis-camera.md#cameraerrorcode)。 ```ts - videoOutput.on('error', (error: BusinessError) => { - console.info(`Video output error code: ${error.code}`); - }); + function onVideoOutputError(videoOutput: camera.VideoOutput): void { + videoOutput.on('error', (error: BusinessError) => { + console.info(`Video output error code: ${error.code}`); + }); + } ``` diff --git a/zh-cn/application-dev/media/camera-session-management.md b/zh-cn/application-dev/media/camera-session-management.md index 1d40506b33..1ea15016fb 100644 --- a/zh-cn/application-dev/media/camera-session-management.md +++ b/zh-cn/application-dev/media/camera-session-management.md @@ -14,81 +14,112 @@ 完成会话配置后,应用提交和开启会话,可以开始调用相机相关功能。 ## 开发步骤 +1. 导入相关接口,导入方法如下。 + + ```ts + import camera from '@ohos.multimedia.camera'; + import type { BusinessError } from '@ohos.base'; + import type featureAbility from '@ohos.ability.featureAbility'; + ``` -1. 调用cameraManager类中的createCaptureSession()方法创建一个会话。 +2. 调用cameraManager类中的createCaptureSession()方法创建一个会话。 ```ts - let captureSession: camera.CaptureSession; - try { - captureSession = cameraManager.createCaptureSession(); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to create the CaptureSession instance. errorCode = ' + err.code); + function getCaptureSession(cameraManager: camera.CameraManager): camera.CaptureSession { + let captureSession: camera.CaptureSession; + try { + captureSession = cameraManager.createCaptureSession(); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to create the CaptureSession instance. error: ${JSON.stringify(err)}`); + } + return captureSession; } ``` -2. 调用captureSession类中的beginConfig()方法配置会话。 +3. 调用captureSession类中的beginConfig()方法配置会话。 ```ts - try { - captureSession.beginConfig(); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to beginConfig. errorCode = ' + err.code); + function beginConfig(captureSession: camera.CaptureSession): void { + try { + captureSession.beginConfig(); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to beginConfig. error: ${JSON.stringify(err)}`); + } } ``` -3. 使能。向会话中添加相机的输入流和输出流,调用captureSession.addInput()添加相机的输入流;调用captureSession.addOutput()添加相机的输出流。以下示例代码以添加预览流previewOutput和拍照流photoOutput为例,即当前模式支持拍照和预览。 +4. 使能。向会话中添加相机的输入流和输出流,调用captureSession.addInput()添加相机的输入流;调用captureSession.addOutput()添加相机的输出流。以下示例代码以添加预览流previewOutput和拍照流photoOutput为例,即当前模式支持拍照和预览。 调用captureSession类中的commitConfig()和start()方法提交相关配置,并启动会话。 ```ts - try { - captureSession.addInput(cameraInput); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to addInput. errorCode = ' + err.code); - } - try { - captureSession.addOutput(previewOutput); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to addOutput(previewOutput). errorCode = ' + err.code); - } - try { - captureSession.addOutput(photoOutput); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to addOutput(photoOutput). errorCode = ' + err.code); + async function startSession(captureSession: camera.CaptureSession, cameraInput: camera.CameraInput, previewOutput: camera.PreviewOutput, photoOutput: camera.PhotoOutput): Promise { + try { + captureSession.addInput(cameraInput); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to addInput. error: ${JSON.stringify(err)}`); + } + try { + captureSession.addOutput(previewOutput); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to add previewOutput. error: ${JSON.stringify(err)}`); + } + try { + captureSession.addOutput(photoOutput); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to add photoOutput. error: ${JSON.stringify(err)}`); + } + try { + await captureSession.commitConfig(); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to commitConfig. error: ${JSON.stringify(err)}`); + } + + try { + await captureSession.start() + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to start. error: ${JSON.stringify(err)}`); + } } - await captureSession.commitConfig(); - await captureSession.start().then(() => { - console.info('Promise returned to indicate the session start success.'); - }); ``` -4. 会话控制。调用captureSession类中的stop()方法可以停止当前会话。调用removeOutput()和addOutput()方法可以完成会话切换控制。以下示例代码以移除拍照流photoOutput,添加视频流videoOutput为例,完成了拍照到录像的切换。 +5. 会话控制。调用captureSession类中的stop()方法可以停止当前会话。调用removeOutput()和addOutput()方法可以完成会话切换控制。以下示例代码以移除拍照流photoOutput,添加视频流videoOutput为例,完成了拍照到录像的切换。 ```ts - await captureSession.stop(); - try { - captureSession.beginConfig(); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to beginConfig. errorCode = ' + err.code); - } - // 从会话中移除拍照输出流 - try { - captureSession.removeOutput(photoOutput); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to removeOutput(photoOutput). errorCode = ' + err.code); - } - // 向会话中添加视频输出流 - try { - captureSession.addOutput(videoOutput); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to addOutput(videoOutput). errorCode = ' + err.code); + async function switchOutput(captureSession: camera.CaptureSession, videoOutput: camera.VideoOutput, photoOutput: camera.PhotoOutput): Promise { + try { + await captureSession.stop(); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to stop. error: ${JSON.stringify(err)}`); + } + + try { + captureSession.beginConfig(); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to beginConfig. error: ${JSON.stringify(err)}`); + } + // 从会话中移除拍照输出流 + try { + captureSession.removeOutput(photoOutput); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to remove photoOutput. error: ${JSON.stringify(err)}`); + } + // 向会话中添加视频输出流 + try { + captureSession.addOutput(videoOutput); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to add videoOutput. error: ${JSON.stringify(err)}`); + } } ``` diff --git a/zh-cn/application-dev/media/camera-shooting-case.md b/zh-cn/application-dev/media/camera-shooting-case.md index 1f1b908192..c961ba5fc7 100644 --- a/zh-cn/application-dev/media/camera-shooting-case.md +++ b/zh-cn/application-dev/media/camera-shooting-case.md @@ -11,245 +11,247 @@ ```ts import camera from '@ohos.multimedia.camera'; import image from '@ohos.multimedia.image'; -import media from '@ohos.multimedia.media'; - -// 创建CameraManager对象 -let context: Context = getContext(this); -let cameraManager: camera.CameraManager = camera.getCameraManager(context); -if (!cameraManager) { - console.error("camera.getCameraManager error"); - return; -} -// 监听相机状态变化 -cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { - console.info(`camera : ${cameraStatusInfo.camera.cameraId}`); - console.info(`status: ${cameraStatusInfo.status}`); -}); - -// 获取相机列表 -let cameraArray: Array = cameraManager.getSupportedCameras(); -if (cameraArray.length <= 0) { - console.error("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); // 获取相机连接类型 -} +import { BusinessError } from '@ohos.base'; +import featureAbility from '@ohos.ability.featureAbility'; + +async function cameraShootingCase(context: featureAbility.Context, surfaceId: string) { + // 创建CameraManager对象 + let cameraManager: camera.CameraManager = camera.getCameraManager(context); + if (!cameraManager) { + console.error("camera.getCameraManager error"); + return; + } + // 监听相机状态变化 + cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { + console.info(`camera : ${cameraStatusInfo.camera.cameraId}`); + console.info(`status: ${cameraStatusInfo.status}`); + }); + + // 获取相机列表 + let cameraArray: Array = cameraManager.getSupportedCameras(); + if (cameraArray.length <= 0) { + console.error("cameraManager.getSupportedCameras error"); + return; + } -// 创建相机输入流 -let cameraInput: camera.CameraInput; -try { - cameraInput = cameraManager.createCameraInput(cameraArray[0]); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to createCameraInput errorCode = ' + err.code); -} + 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); // 获取相机连接类型 + } -// 监听cameraInput错误信息 -let cameraDevice: camera.CameraDevice = cameraArray[0]; -cameraInput.on('error', cameraDevice, (error: BusinessError) => { - console.info(`Camera input error code: ${error.code}`); -}) + // 创建相机输入流 + let cameraInput: camera.CameraInput; + try { + cameraInput = cameraManager.createCameraInput(cameraArray[0]); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to createCameraInput errorCode = ' + err.code); + } -// 打开相机 -await cameraInput.open(); + // 监听cameraInput错误信息 + let cameraDevice: camera.CameraDevice = cameraArray[0]; + cameraInput.on('error', cameraDevice, (error: BusinessError) => { + console.info(`Camera input error code: ${error.code}`); + }) -// 获取相机设备支持的输出流能力 -let cameraOutputCap: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraArray[0]); -if (!cameraOutputCap) { - console.error("cameraManager.getSupportedOutputCapability error"); - return; -} -console.info("outputCapability: " + JSON.stringify(cameraOutputCap)); - -let previewProfilesArray: Array = cameraOutputCap.previewProfiles; -if (!previewProfilesArray) { - console.error("createOutput previewProfilesArray == null || undefined"); -} - -let photoProfilesArray: Array = cameraOutputCap.photoProfiles; -if (!photoProfilesArray) { - console.error("createOutput photoProfilesArray == null || undefined"); -} - -// 创建预览输出流,其中参数 surfaceId 参考上文 XComponent 组件,预览流为XComponent组件提供的surface -let previewOutput: camera.PreviewOutput; -try { - previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId); -} catch (error) { - let err = error as BusinessError; - console.error(`Failed to create the PreviewOutput instance. error code: ${err.code}`); -} + // 打开相机 + await cameraInput.open(); -// 监听预览输出错误信息 -previewOutput.on('error', (error: BusinessError) => { - console.info(`Preview output error code: ${error.code}`); -}); - -// 创建ImageReceiver对象,并设置照片参数:分辨率大小是根据前面 photoProfilesArray 获取的当前设备所支持的拍照分辨率大小去设置 -let imageReceiver: image.ImageReceiver = image.createImageReceiver(1920, 1080, 4, 8); -// 获取照片显示SurfaceId -let photoSurfaceId: string = await imageReceiver.getReceivingSurfaceId(); -// 创建拍照输出流 -let photoOutput: camera.PhotoOutput; -try { - photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to createPhotoOutput errorCode = ' + err.code); -} -//创建会话 -let captureSession: camera.CaptureSession; -try { - captureSession = cameraManager.createCaptureSession(); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to create the CaptureSession instance. errorCode = ' + err.code); -} + // 获取相机设备支持的输出流能力 + let cameraOutputCap: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraArray[0]); + if (!cameraOutputCap) { + console.error("cameraManager.getSupportedOutputCapability error"); + return; + } + console.info("outputCapability: " + JSON.stringify(cameraOutputCap)); -// 监听session错误信息 -captureSession.on('error', (error: BusinessError) => { - console.info(`Capture session error code: ${error.code}`); -}); - -// 开始配置会话 -try { - captureSession.beginConfig(); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to beginConfig. errorCode = ' + err.code); -} + let previewProfilesArray: Array = cameraOutputCap.previewProfiles; + if (!previewProfilesArray) { + console.error("createOutput previewProfilesArray == null || undefined"); + } -// 向会话中添加相机输入流 -try { - captureSession.addInput(cameraInput); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to addInput. errorCode = ' + err.code); -} + let photoProfilesArray: Array = cameraOutputCap.photoProfiles; + if (!photoProfilesArray) { + console.error("createOutput photoProfilesArray == null || undefined"); + } -// 向会话中添加预览输出流 -try { - captureSession.addOutput(previewOutput); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to addOutput(previewOutput). errorCode = ' + err.code); -} + // 创建预览输出流,其中参数 surfaceId 参考上文 XComponent 组件,预览流为XComponent组件提供的surface + let previewOutput: camera.PreviewOutput; + try { + previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to create the PreviewOutput instance. error code: ${err.code}`); + } -// 向会话中添加拍照输出流 -try { - captureSession.addOutput(photoOutput); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to addOutput(photoOutput). errorCode = ' + err.code); -} + // 监听预览输出错误信息 + previewOutput.on('error', (error: BusinessError) => { + console.info(`Preview output error code: ${error.code}`); + }); + + // 创建ImageReceiver对象,并设置照片参数:分辨率大小是根据前面 photoProfilesArray 获取的当前设备所支持的拍照分辨率大小去设置 + let imageReceiver: image.ImageReceiver = image.createImageReceiver(1920, 1080, 4, 8); + // 获取照片显示SurfaceId + let photoSurfaceId: string = await imageReceiver.getReceivingSurfaceId(); + // 创建拍照输出流 + let photoOutput: camera.PhotoOutput; + try { + photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to createPhotoOutput errorCode = ' + err.code); + } + //创建会话 + let captureSession: camera.CaptureSession; + try { + captureSession = cameraManager.createCaptureSession(); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to create the CaptureSession instance. errorCode = ' + err.code); + } -// 提交会话配置 -await captureSession.commitConfig(); - -// 启动会话 -await captureSession.start().then(() => { - console.info('Promise returned to indicate the session start success.'); -}); -// 判断设备是否支持闪光灯 -let flashStatus: boolean; -try { - flashStatus = captureSession.hasFlash(); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to hasFlash. errorCode = ' + err.code); -} -console.info('Promise returned with the flash light support status:' + flashStatus); + // 监听session错误信息 + captureSession.on('error', (error: BusinessError) => { + console.info(`Capture session error code: ${error.code}`); + }); + + // 开始配置会话 + try { + captureSession.beginConfig(); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to beginConfig. errorCode = ' + err.code); + } -if (flashStatus) { - // 判断是否支持自动闪光灯模式 - let flashModeStatus: boolean; + // 向会话中添加相机输入流 try { - let status: boolean = captureSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO); - flashModeStatus = status; + captureSession.addInput(cameraInput); } catch (error) { let err = error as BusinessError; - console.error('Failed to check whether the flash mode is supported. errorCode = ' + err.code); + console.error('Failed to addInput. errorCode = ' + err.code); } - if(flashModeStatus) { - // 设置自动闪光灯模式 + + // 向会话中添加预览输出流 + try { + captureSession.addOutput(previewOutput); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to addOutput(previewOutput). errorCode = ' + err.code); + } + + // 向会话中添加拍照输出流 + try { + captureSession.addOutput(photoOutput); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to addOutput(photoOutput). errorCode = ' + err.code); + } + + // 提交会话配置 + await captureSession.commitConfig(); + + // 启动会话 + await captureSession.start().then(() => { + console.info('Promise returned to indicate the session start success.'); + }); + // 判断设备是否支持闪光灯 + let flashStatus: boolean; + try { + flashStatus = captureSession.hasFlash(); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to hasFlash. errorCode = ' + err.code); + } + console.info('Promise returned with the flash light support status:' + flashStatus); + + if (flashStatus) { + // 判断是否支持自动闪光灯模式 + let flashModeStatus: boolean; try { - captureSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO); + let status: boolean = captureSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO); + flashModeStatus = status; } catch (error) { let err = error as BusinessError; - console.error('Failed to set the flash mode. errorCode = ' + err.code); + console.error('Failed to check whether the flash mode is supported. errorCode = ' + err.code); + } + if(flashModeStatus) { + // 设置自动闪光灯模式 + try { + captureSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to set the flash mode. errorCode = ' + err.code); + } } } -} -// 判断是否支持连续自动变焦模式 -let focusModeStatus: boolean; -try { - let status: boolean = captureSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); - focusModeStatus = status; -} catch (error) { - let err = error as BusinessError; - console.error('Failed to check whether the focus mode is supported. errorCode = ' + err.code); -} - -if (focusModeStatus) { - // 设置连续自动变焦模式 + // 判断是否支持连续自动变焦模式 + let focusModeStatus: boolean; try { - captureSession.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); + let status: boolean = captureSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); + focusModeStatus = status; } catch (error) { let err = error as BusinessError; - console.error('Failed to set the focus mode. errorCode = ' + err.code); + console.error('Failed to check whether the focus mode is supported. errorCode = ' + err.code); } -} -// 获取相机支持的可变焦距比范围 -let zoomRatioRange: Array; -try { - zoomRatioRange = captureSession.getZoomRatioRange(); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to get the zoom ratio range. errorCode = ' + err.code); -} + if (focusModeStatus) { + // 设置连续自动变焦模式 + try { + captureSession.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to set the focus mode. errorCode = ' + err.code); + } + } -// 设置可变焦距比 -try { - captureSession.setZoomRatio(zoomRatioRange[0]); -} catch (error) { - let err = error as BusinessError; - console.error('Failed to set the zoom ratio value. errorCode = ' + err.code); -} -let settings: camera.PhotoCaptureSetting = { - quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // 设置图片质量高 - rotation: camera.ImageRotation.ROTATION_0 // 设置图片旋转角度0 -} -// 使用当前拍照设置进行拍照 -photoOutput.capture(settings, async (err: BusinessError) => { - if (err) { - console.error('Failed to capture the photo ${err.message}'); - return; + // 获取相机支持的可变焦距比范围 + let zoomRatioRange: Array; + try { + zoomRatioRange = captureSession.getZoomRatioRange(); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to get the zoom ratio range. errorCode = ' + err.code); + } + + // 设置可变焦距比 + try { + captureSession.setZoomRatio(zoomRatioRange[0]); + } catch (error) { + let err = error as BusinessError; + console.error('Failed to set the zoom ratio value. errorCode = ' + err.code); + } + let photoCaptureSetting: camera.PhotoCaptureSetting = { + quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // 设置图片质量高 + rotation: camera.ImageRotation.ROTATION_0 // 设置图片旋转角度0 } - console.info('Callback invoked to indicate the photo capture request success.'); -}); -// 停止当前会话 -captureSession.stop(); + // 使用当前拍照设置进行拍照 + photoOutput.capture(photoCaptureSetting, (err: BusinessError) => { + if (err) { + console.error('Failed to capture the photo ${err.message}'); + return; + } + console.info('Callback invoked to indicate the photo capture request success.'); + }); + // 停止当前会话 + captureSession.stop(); -// 释放相机输入流 -cameraInput.close(); + // 释放相机输入流 + cameraInput.close(); -// 释放预览输出流 -previewOutput.release(); + // 释放预览输出流 + previewOutput.release(); -// 释放拍照输出流 -photoOutput.release(); + // 释放拍照输出流 + photoOutput.release(); -// 释放会话 -captureSession.release(); + // 释放会话 + captureSession.release(); -// 会话置空 -captureSession = null; + // 会话置空 + captureSession = null; +} ``` diff --git a/zh-cn/application-dev/media/camera-shooting.md b/zh-cn/application-dev/media/camera-shooting.md index 210264a6f3..0466deeb96 100644 --- a/zh-cn/application-dev/media/camera-shooting.md +++ b/zh-cn/application-dev/media/camera-shooting.md @@ -10,6 +10,8 @@ ```ts import image from '@ohos.multimedia.image'; + import camera from '@ohos.multimedia.camera'; + import type { BusinessError } from '@ohos.base'; ``` 2. 获取SurfaceId。 @@ -17,16 +19,18 @@ 通过image的createImageReceiver方法创建ImageReceiver实例,再通过实例的getReceivingSurfaceId方法获取SurfaceId,与拍照输出流相关联,获取拍照输出流的数据。 ```ts - async function getImageReceiverSurfaceId() { + async function getImageReceiverSurfaceId(): Promise { + let photoSurfaceId: string; let receiver: image.ImageReceiver = image.createImageReceiver(640, 480, 4, 8); console.info('before ImageReceiver check'); if (receiver !== undefined) { console.info('ImageReceiver is ok'); - let photoSurfaceId: string = await receiver.getReceivingSurfaceId(); - console.info('ImageReceived id: ' + JSON.stringify(photoSurfaceId)); + photoSurfaceId = await receiver.getReceivingSurfaceId(); + console.info(`ImageReceived id: ${JSON.stringify(photoSurfaceId)}`); } else { console.info('ImageReceiver is not ok'); } + return photoSurfaceId; } ``` @@ -35,16 +39,19 @@ 通过CameraOutputCapability类中的photoProfiles()方法,可获取当前设备支持的拍照输出流,通过createPhotoOutput()方法传入支持的某一个输出流及步骤一获取的SurfaceId创建拍照输出流。 ```ts - let photoProfilesArray: Array = cameraOutputCapability.photoProfiles; - if (!photoProfilesArray) { - console.error("createOutput photoProfilesArray == null || undefined"); - } - let photoOutput: camera.PhotoOutput; - try { - photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to createPhotoOutput errorCode = ' + err.code); + function getPhotoOutput(cameraManager: camera.CameraManager, cameraOutputCapability: camera.CameraOutputCapability, photoSurfaceId: string): camera.PhotoOutput { + let photoProfilesArray: Array = cameraOutputCapability.photoProfiles; + if (!photoProfilesArray) { + console.error("createOutput photoProfilesArray == null || undefined"); + } + let photoOutput: camera.PhotoOutput; + try { + photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to createPhotoOutput. error: ${JSON.stringify(err)}`); + } + return photoOutput; } ``` @@ -53,67 +60,69 @@ 配置相机的参数可以调整拍照的一些功能,包括闪光灯、变焦、焦距等。 ```ts - // 判断设备是否支持闪光灯 - let flashStatus: boolean; - try { - flashStatus = captureSession.hasFlash(); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to hasFlash. errorCode = ' + err.code); - } - console.info('Promise returned with the flash light support status:' + flashStatus); - if (flashStatus) { - // 判断是否支持自动闪光灯模式 - let flashModeStatus: boolean; + function configuringSession(captureSession: camera.CaptureSession): void { + // 判断设备是否支持闪光灯 + let flashStatus: boolean; try { - let status: boolean = captureSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO); - flashModeStatus = status; + flashStatus = captureSession.hasFlash(); } catch (error) { let err = error as BusinessError; - console.error('Failed to check whether the flash mode is supported. errorCode = ' + err.code); - } - if(flashModeStatus) { - // 设置自动闪光灯模式 + console.error(`Failed to hasFlash. error: ${JSON.stringify(err)}`); + } + console.info(`Promise returned with the flash light support status: ${flashStatus}`); + if (flashStatus) { + // 判断是否支持自动闪光灯模式 + let flashModeStatus: boolean; try { - captureSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO); + let status: boolean = captureSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO); + flashModeStatus = status; } catch (error) { let err = error as BusinessError; - console.error('Failed to set the flash mode. errorCode = ' + err.code); + console.error(`Failed to check whether the flash mode is supported. error: ${JSON.stringify(err)}`); + } + if (flashModeStatus) { + // 设置自动闪光灯模式 + try { + captureSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to set the flash mode. error: ${JSON.stringify(err)}`); + } } } - } - // 判断是否支持连续自动变焦模式 - let focusModeStatus: boolean; - try { - let status: boolean = captureSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); - focusModeStatus = status; - } catch (error) { - let err = error as BusinessError; - console.error('Failed to check whether the focus mode is supported. errorCode = ' + err.code); - } - if (focusModeStatus) { - // 设置连续自动变焦模式 + // 判断是否支持连续自动变焦模式 + let focusModeStatus: boolean; try { + let status: boolean = captureSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); + focusModeStatus = status; + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to check whether the focus mode is supported. error: ${JSON.stringify(err)}`); + } + if (focusModeStatus) { + // 设置连续自动变焦模式 + try { captureSession.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to set the focus mode. error: ${JSON.stringify(err)}`); + } + } + // 获取相机支持的可变焦距比范围 + let zoomRatioRange: Array; + try { + zoomRatioRange = captureSession.getZoomRatioRange(); } catch (error) { - let err = error as BusinessError; - console.error('Failed to set the focus mode. errorCode = ' + err.code); + let err = error as BusinessError; + console.error(`Failed to get the zoom ratio range. error: ${JSON.stringify(err)}`); + } + // 设置可变焦距比 + try { + captureSession.setZoomRatio(zoomRatioRange[0]); + } catch (error) { + let err = error as BusinessError; + console.error(`Failed to set the zoom ratio value. error: ${JSON.stringify(err)}`); } - } - // 获取相机支持的可变焦距比范围 - let zoomRatioRange: Array; - try { - zoomRatioRange = captureSession.getZoomRatioRange(); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to get the zoom ratio range. errorCode = ' + err.code); - } - // 设置可变焦距比 - try { - captureSession.setZoomRatio(zoomRatioRange[0]); - } catch (error) { - let err = error as BusinessError; - console.error('Failed to set the zoom ratio value. errorCode = ' + err.code); } ``` @@ -122,19 +131,21 @@ 通过photoOutput类的capture()方法,执行拍照任务。该方法有两个参数,第一个参数为拍照设置参数的setting,setting中可以设置照片的质量和旋转角度,第二参数为回调函数。 ```ts - let settings: camera.PhotoCaptureSetting = { - quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // 设置图片质量高 - rotation: camera.ImageRotation.ROTATION_0, // 设置图片旋转角度0 - location: captureLocation, // 设置图片地理位置 - mirror: false // 设置镜像使能开关(默认关) - }; - photoOutput.capture(settings, async (err: BusinessError) => { - if (err) { - console.error('Failed to capture the photo ${err.message}'); - return; - } - console.info('Callback invoked to indicate the photo capture request success.'); - }); + function capture(captureLocation: camera.Location, photoOutput: camera.PhotoOutput): void { + let settings: camera.PhotoCaptureSetting = { + quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // 设置图片质量高 + rotation: camera.ImageRotation.ROTATION_0, // 设置图片旋转角度0 + location: captureLocation, // 设置图片地理位置 + mirror: false // 设置镜像使能开关(默认关) + }; + photoOutput.capture(settings, (err: BusinessError) => { + if (err) { + console.error(`Failed to capture the photo. error: ${JSON.stringify(err)}`); + return; + } + console.info('Callback invoked to indicate the photo capture request success.'); + }); + } ``` ## 状态监听 @@ -144,24 +155,30 @@ - 通过注册固定的captureStart回调函数获取监听拍照开始结果,photoOutput创建成功时即可监听,拍照第一次曝光时触发,该事件返回此次拍照的captureId。 ```ts - photoOutput.on('captureStart', (err: BusinessError, captureId: number) => { - console.info(`photo capture stated, captureId : ${captureId}`); - }); + function onPhotoOutputCaptureStart(photoOutput: camera.PhotoOutput): void { + photoOutput.on('captureStart', (err: BusinessError, captureId: number) => { + console.info(`photo capture stated, captureId : ${captureId}`); + }); + } ``` - 通过注册固定的captureEnd回调函数获取监听拍照结束结果,photoOutput创建成功时即可监听,该事件返回结果为拍照完全结束后的相关信息[CaptureEndInfo](../reference/apis/js-apis-camera.md#captureendinfo)。 ```ts - photoOutput.on('captureEnd', (err: BusinessError, captureEndInfo: camera.CaptureEndInfo) => { - console.info(`photo capture end, captureId : ${captureEndInfo.captureId}`); - console.info(`frameCount : ${captureEndInfo.frameCount}`); - }); + function onPhotoOutputCaptureEnd(photoOutput: camera.PhotoOutput): void { + photoOutput.on('captureEnd', (err: BusinessError, captureEndInfo: camera.CaptureEndInfo) => { + console.info(`photo capture end, captureId : ${captureEndInfo.captureId}`); + console.info(`frameCount : ${captureEndInfo.frameCount}`); + }); + } ``` - 通过注册固定的error回调函数获取监听拍照输出流的错误结果。callback返回拍照输出接口使用错误时的对应错误码,错误码类型参见[CameraErrorCode](../reference/apis/js-apis-camera.md#cameraerrorcode)。 ```ts - photoOutput.on('error', (error: BusinessError) => { - console.info(`Photo output error code: ${error.code}`); - }); + function onPhotoOutputError(photoOutput: camera.PhotoOutput): void { + photoOutput.on('error', (error: BusinessError) => { + console.info(`Photo output error code: ${error.code}`); + }); + } ``` -- GitLab