自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

小白也能開發(fā)相機(jī)?Sample來(lái)教你

開發(fā) 前端
相機(jī)是智能設(shè)備最重要的功能之一,它能捕捉美好的瞬間、記錄關(guān)鍵的時(shí)刻,被廣泛應(yīng)用于日常生活中。本文將詳細(xì)地講解一個(gè)帶有拍攝照片和錄制視頻功能的相機(jī)開發(fā)過程。

[[418309]]

想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

上期我們給大家介紹了HarmonyOS Sample,收到了不少小伙伴的反饋,想學(xué)習(xí)一下HarmonyOS相機(jī)開發(fā),現(xiàn)在,他來(lái)了!

相機(jī)開發(fā)概覽

相機(jī)是智能設(shè)備最重要的功能之一,它能捕捉美好的瞬間、記錄關(guān)鍵的時(shí)刻,被廣泛應(yīng)用于日常生活中。本文將詳細(xì)地講解一個(gè)帶有拍攝照片和錄制視頻功能的相機(jī)開發(fā)過程。

小白也能開發(fā)相機(jī)?Sample來(lái)教你-鴻蒙HarmonyOS技術(shù)社區(qū)

目前,HarmonyOS相機(jī)模塊支持相機(jī)業(yè)務(wù)的開發(fā),開發(fā)者可以通過已開放的接口實(shí)現(xiàn)相機(jī)硬件的訪問、操作和新功能開發(fā)。如下圖所示,是HarmonyOS為相機(jī)應(yīng)用開發(fā)者提供的3個(gè)包的內(nèi)容,包括方法、枚舉、以及常量/變量,方便開發(fā)者更容易地實(shí)現(xiàn)相機(jī)功能:

小白也能開發(fā)相機(jī)?Sample來(lái)教你-鴻蒙HarmonyOS技術(shù)社區(qū)

相機(jī)的開發(fā)流程如圖所示:

小白也能開發(fā)相機(jī)?Sample來(lái)教你-鴻蒙HarmonyOS技術(shù)社區(qū)

相機(jī)權(quán)限申請(qǐng)

在使用相機(jī)之前,需要申請(qǐng)相機(jī)的相關(guān)權(quán)限,比如獲取設(shè)備的相機(jī)權(quán)限、麥克風(fēng)權(quán)限、存儲(chǔ)權(quán)限等。保證應(yīng)用擁有相機(jī)硬件及其他功能權(quán)限。

視頻鏈接

開發(fā)者需在config.json中配置相關(guān)的權(quán)限,如下所示:

  1. "reqPermissions": [ 
  2.   { 
  3.     "name""ohos.permission.CAMERA" 
  4.   }, 
  5.   { 
  6.     "name""ohos.permission.WRITE_USER_STORAGE" 
  7.   }, 
  8.   { 
  9.     "name""ohos.permission.READ_USER_STORAGE" 
  10.   }, 
  11.   { 
  12.     "name""ohos.permission.MICROPHONE" 
  13.   }, 
  14.   { 
  15.     "name""ohos.permission.LOCATION" 
  16.   } 

獲取相關(guān)權(quán)限的具體代碼如下所示:

  1. private void requestPermissions() { 
  2.     String[] permissions = { 
  3.             //允許應(yīng)用程序創(chuàng)建或刪除文件,或?qū)?shù)據(jù)寫入設(shè)備存儲(chǔ)中的文件。 
  4.             SystemPermission.WRITE_USER_STORAGE, 
  5.             //允許應(yīng)用程序從設(shè)備存儲(chǔ)中讀取文件。 
  6.             SystemPermission.READ_USER_STORAGE, 
  7.             //允許應(yīng)用程序使用相機(jī)。 
  8.             SystemPermission.CAMERA, 
  9.             //允許應(yīng)用程序訪問麥克風(fēng)。 
  10.             SystemPermission.MICROPHONE, 
  11.             //允許應(yīng)用程序獲取設(shè)備位置。 
  12.             SystemPermission.LOCATION 
  13.     }; 
  14.     List<String> permissionFiltered = Arrays.stream(permissions) 
  15.         .filter(permission -> verifySelfPermission(permission) != IBundleManager.PERMISSION_GRANTED) 
  16.         .collect(Collectors.toList()); 
  17.     requestPermissionsFromUser(permissionFiltered.toArray(new String[permissionFiltered.size()]), 0); 

初始化相機(jī)界面

獲取到設(shè)備權(quán)限后,需要初始化相機(jī)界面。通過getWindow()獲取當(dāng)前Ability對(duì)應(yīng)的窗口,再通過addCallback()添加界面操作的回調(diào)。代碼如下所示:

  1. private void initSurface() { 
  2.     //獲取當(dāng)前Ability對(duì)應(yīng)的窗口,設(shè)置是否啟用透明度。isEnable -指定是否啟用透明度。True表示啟用透明度,False表示禁用。 
  3.     getWindow().setTransparent(true); 
  4.     DirectionalLayout.LayoutConfig params = new DirectionalLayout.LayoutConfig( 
  5.         ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT); 
  6.     surfaceProvider = new SurfaceProvider(this); 
  7.     surfaceProvider.setLayoutConfig(params); 
  8.     /** 
  9.      * 設(shè)置是否將此SurfaceProvider的Surface放置在AGP容器組件的頂層。 
  10.      * 參數(shù)說明: 
  11.      * toTop -指定是否將相機(jī)界面固定在頂部。值true表示將Surface放在AGP容器組件的頂層,而值false表示相反。*/ 
  12.     surfaceProvider.pinToZTop(false); 
  13.     //通過addCallback()添加界面操作的回調(diào) 
  14.     surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceCallBack()); 
  15.     surfaceContainer.addComponent(surfaceProvider); 

通過postTask()來(lái)執(zhí)行相機(jī)任務(wù):

  1. private class SurfaceCallBack implements SurfaceOps.Callback { 
  2.     @Override 
  3.     public void surfaceCreated(SurfaceOps callbackSurfaceOps) { 
  4.         if (callbackSurfaceOps != null) { 
  5.             //setFixedSize:設(shè)置界面的固定大小。參數(shù)說明:寬度-指示界面的寬度。高度-指示界面的高度。 
  6.             callbackSurfaceOps.setFixedSize(SCREEN_HEIGHT,SCREEN_WIDTH); 
  7.         } 
  8. //設(shè)置延時(shí)200ms的postTask,用于相機(jī)界面的顯示 
  9.         eventHandler.postTask(new Runnable() { 
  10.             @Override 
  11.             public void run() { 
  12.                 openCamera(); 
  13.             } 
  14.         },200); 
  15.     } 

相機(jī)設(shè)備創(chuàng)建

1.創(chuàng)建相機(jī)對(duì)象

相機(jī)界面準(zhǔn)備好后,我們需要?jiǎng)?chuàng)建相機(jī)設(shè)備。在實(shí)現(xiàn)一個(gè)相機(jī)應(yīng)用之前必須先創(chuàng)建一個(gè)獨(dú)立的相機(jī)設(shè)備,然后才能繼續(xù)相機(jī)的其他操作。CameraKit類是相機(jī)的入口API類,如下所示:

小白也能開發(fā)相機(jī)?Sample來(lái)教你-鴻蒙HarmonyOS技術(shù)社區(qū)

相機(jī)設(shè)備創(chuàng)建的代碼如下:

  1. private void openCamera() { 
  2.     //ImageReceiver:連接到圖像輸出設(shè)備的圖像接收器,并提供一個(gè)緩沖隊(duì)列來(lái)接收?qǐng)D像數(shù)據(jù) 
  3.     //create:根據(jù)指定的圖像寬度、高度、格式和緩沖隊(duì)列容量創(chuàng)建ImageReceiver實(shí)例 
  4.     imageReceiver = ImageReceiver.create(SCREEN_WIDTH, SCREEN_HEIGHT, ImageFormat.JPEG, IMAGE_RCV_CAPACITY); 
  5.     //設(shè)置接收到新圖像數(shù)據(jù)時(shí)將調(diào)用的圖像偵聽器。 
  6.     imageReceiver.setImageArrivalListener(this::saveImage); 
  7.     //獲取CameraKit實(shí)例 
  8.     CameraKit cameraKit = CameraKit.getInstance(getApplicationContext()); 
  9.     //獲取當(dāng)前使用的設(shè)備支持的邏輯相機(jī)列表 
  10.     String[] cameraList = cameraKit.getCameraIds(); 
  11.     String cameraId = ""
  12.     //獲取當(dāng)前邏輯相機(jī)的信息 
  13.     for (String logicalCameraId : cameraList) { 
  14.         int faceType = cameraKit.getCameraInfo(logicalCameraId).getFacingType(); 
  15.         switch (faceType){ 
  16.             case CameraInfo.FacingType.CAMERA_FACING_FRONT: 
  17.                 if (isFrontCamera) { 
  18.                     cameraId = logicalCameraId; 
  19.                 } 
  20.                 break; 
  21.             case CameraInfo.FacingType.CAMERA_FACING_BACK: 
  22.                 if (!isFrontCamera) { 
  23.                     cameraId = logicalCameraId; 
  24.                 } 
  25.                 break; 
  26.             case CameraInfo.FacingType.CAMERA_FACING_OTHERS: 
  27.             default
  28.                 break; 
  29.         } 
  30.     } 
  31.     if (cameraId != null && !cameraId.isEmpty()) { 
  32.         CameraStateCallbackImpl cameraStateCallback = new CameraStateCallbackImpl(); 
  33.         /**createCamera()用于創(chuàng)建相機(jī)對(duì)象 
  34.          * 該方法的第一個(gè)參數(shù)代表要打開的攝像頭ID; 
  35.          * 第二個(gè)參數(shù)用于監(jiān)聽攝像頭的狀態(tài); 
  36.          * 第三個(gè)參數(shù)代表執(zhí)行callback的Handler,如果程序希望直接在當(dāng)前線程中執(zhí)行callback,則可將handler參數(shù)設(shè)為null。*/ 
  37.         cameraKit.createCamera(cameraId, cameraStateCallback, eventHandler); 
  38.     } 

創(chuàng)建相機(jī)設(shè)備成功后,在CameraStateCallback中會(huì)觸發(fā)onCreated(Camera camera)回調(diào),并且?guī)Щ谻amera對(duì)象,用于執(zhí)行相機(jī)設(shè)備的操作。

  1. @Override 
  2. public void onCreated(Camera camera) { 
  3.     previewSurface = surfaceProvider.getSurfaceOps().get().getSurface(); 
  4.     if (previewSurface == null) { 
  5.         HiLog.error(LABEL_LOG, "%{public}s""Create camera filed, preview surface is null"); 
  6.         return
  7.     } 
  8.     //獲取相機(jī)Config.Builder實(shí)例。 
  9.     CameraConfig.Builder cameraConfigBuilder = camera.getCameraConfigBuilder(); 
  10.     //addSurface:添加界面作為相機(jī)流的輸出。 
  11.     cameraConfigBuilder.addSurface(previewSurface); 
  12.     cameraConfigBuilder.addSurface(imageReceiver.getRecevingSurface()); 
  13.     camera.configure(cameraConfigBuilder.build()); 
  14.     cameraDevice = camera; 
  15.     updateComponentVisible(true); 

2.配置預(yù)覽

在使用相機(jī)的過程中,用戶一般都是先看見預(yù)覽畫面才執(zhí)行拍照或者其他功能,所以對(duì)于一個(gè)普通的相機(jī)應(yīng)用,預(yù)覽是必不可少的。在上述CameraStateCallback中,會(huì)調(diào)用configure()方法實(shí)現(xiàn)預(yù)覽配置,通過triggerLoopingCapture()方法實(shí)現(xiàn)循環(huán)幀捕獲,從而達(dá)到預(yù)覽的目的。具體代碼如下:

  1. @Override 
  2. public void onConfigured(Camera camera) { 
  3.     FrameConfig.Builder framePreviewConfigBuilder = camera.getFrameConfigBuilder(FRAME_CONFIG_PREVIEW); 
  4.     framePreviewConfigBuilder.addSurface(previewSurface); 
  5.     //triggerLoopingCapture:開始循環(huán)幀捕獲。循環(huán)幀捕獲通常用于預(yù)覽或錄制 
  6.     camera.triggerLoopingCapture(framePreviewConfigBuilder.build()); 

相機(jī)功能實(shí)現(xiàn)

相機(jī)的基本功能主要分為拍攝照片和錄制視頻,目前HarmonyOS為開發(fā)者提供了如下相機(jī)拍照功能實(shí)現(xiàn)的Camera操作類,開發(fā)者可以通過這些方法,實(shí)現(xiàn)各種相機(jī)應(yīng)用的開發(fā):

小白也能開發(fā)相機(jī)?Sample來(lái)教你-鴻蒙HarmonyOS技術(shù)社區(qū)

如下圖所示是相機(jī)的使用過程,接下來(lái)的相機(jī)功能實(shí)現(xiàn),也會(huì)根據(jù)此流程圖來(lái)實(shí)現(xiàn)。

小白也能開發(fā)相機(jī)?Sample來(lái)教你-鴻蒙HarmonyOS技術(shù)社區(qū)

(1)選擇功能

通過初始化相機(jī)界面組件,設(shè)置點(diǎn)擊事件偵聽器來(lái)實(shí)現(xiàn)相機(jī)功能選擇。代碼如下所示:

  1. private void initComponents() { 
  2.     Component takePhoto = findComponentById(ResourceTable.Id_take_photo); 
  3.     Component videoRecord = findComponentById(ResourceTable.Id_video_record); 
  4.     //設(shè)置點(diǎn)擊事件偵聽器,用于拍攝照片 
  5.     takePhoto.setClickedListener((component) -> startAbility(TakePhotoAbility.class.getName())); 
  6.     //設(shè)置點(diǎn)擊事件偵聽器,用于錄制視頻 
  7.     videoRecord.setClickedListener((component) -> startAbility(VideoRecordAbility.class.getName())); 

(2)切換攝像頭

開始拍攝照片或錄制視頻時(shí),由于相機(jī)默認(rèn)打開后置攝像頭,需根據(jù)場(chǎng)景切換前置攝像頭或后置攝像頭。如果檢測(cè)到相機(jī)正在工作中,將執(zhí)行release()方法釋放當(dāng)前相機(jī)設(shè)備。代碼如下:

  1. Image takePhotoImage = (Image) findComponentById(ResourceTable.Id_tack_picture_btn); 
  2. //setClickedListener:為組件中的單擊事件注冊(cè)偵聽器。 
  3. takePhotoImage.setClickedListener(this::takeSingleCapture); 
  4.  
  5. private void takeSingleCapture(Component component) { 
  6.     if (cameraDevice == null || imageReceiver == null) { 
  7.         return
  8.     } 
  9.     //用于配置幀捕獲、圖像處理和圖像輸出的接口 
  10.     FrameConfig.Builder framePictureConfigBuilder = cameraDevice.getFrameConfigBuilder(FRAME_CONFIG_PICTURE); 
  11.     framePictureConfigBuilder.addSurface(imageReceiver.getRecevingSurface()); 
  12.     FrameConfig pictureFrameConfig = framePictureConfigBuilder.build(); 
  13.     //triggerSingleCapture():開始單幀捕獲。這種方法通常用于拍照。 
  14.     cameraDevice.triggerSingleCapture(pictureFrameConfig); 

(3)拍攝照片

拍照功能屬于相機(jī)應(yīng)用的最重要功能之一,而且照片質(zhì)量對(duì)用戶至關(guān)重要。相機(jī)模塊基于相機(jī)復(fù)雜的邏輯,從應(yīng)用接口層到器件驅(qū)動(dòng)層都已經(jīng)默認(rèn)的做好了最適合用戶的配置,這些默認(rèn)配置盡可能地保證用戶拍出的每張照片的質(zhì)量。

實(shí)現(xiàn)單幀拍照

單幀拍照,其實(shí)就是單幀捕獲的過程。通過設(shè)置點(diǎn)擊事件偵聽器setClickedListener(),來(lái)觸發(fā)takeSingleCapture()方法,實(shí)現(xiàn)單幀捕獲。具體代碼如下:

  1. Image takePhotoImage = (Image) findComponentById(ResourceTable.Id_tack_picture_btn); 
  2. //setClickedListener:為組件中的單擊事件注冊(cè)偵聽器。 
  3. takePhotoImage.setClickedListener(this::takeSingleCapture); 
  4.  
  5. private void takeSingleCapture(Component component) { 
  6.     if (cameraDevice == null || imageReceiver == null) { 
  7.         return
  8.     } 
  9.     //用于配置幀捕獲、圖像處理和圖像輸出的接口 
  10.     FrameConfig.Builder framePictureConfigBuilder = cameraDevice.getFrameConfigBuilder(FRAME_CONFIG_PICTURE); 
  11.     framePictureConfigBuilder.addSurface(imageReceiver.getRecevingSurface()); 
  12.     FrameConfig pictureFrameConfig = framePictureConfigBuilder.build(); 
  13.     //triggerSingleCapture():開始單幀捕獲。這種方法通常用于拍照。 
  14.     cameraDevice.triggerSingleCapture(pictureFrameConfig); 

實(shí)現(xiàn)連拍

連拍功能方便用戶一次拍照獲取多張照片,用于捕捉精彩瞬間。

同單幀拍照的實(shí)現(xiàn)流程一致,但連拍需要使用triggerMultiCapture(frameConfigs)方法用于多幀捕獲。

  1. private void takeMultiCapture(Component component) { 
  2.     FrameConfig.Builder framePictureConfigBuilder = cameraDevice.getFrameConfigBuilder(FRAME_CONFIG_PICTURE); 
  3.     framePictureConfigBuilder.addSurface(imageReceiver.getRecevingSurface()); 
  4.     List<FrameConfig> frameConfigs = new ArrayList<>(); 
  5.     FrameConfig firstFrameConfig = framePictureConfigBuilder.build(); 
  6.     frameConfigs.add(firstFrameConfig); 
  7.     FrameConfig secondFrameConfig = framePictureConfigBuilder.build(); 
  8.     frameConfigs.add(secondFrameConfig); 
  9.     /**triggerMultiCapture(frameConfigs):啟動(dòng)多幀捕獲。 
  10.     cameraDevice.triggerMultiCapture(frameConfigs); 

存儲(chǔ)照片

拍攝后的照片通過saveImage()實(shí)現(xiàn)照片存儲(chǔ)。具體代碼如下:

  1. /** 
  2.   * 存儲(chǔ)照片*/ 
  3. private void saveImage(ImageReceiver receiver) { 
  4.     //getFilesDir():獲取應(yīng)用程序在設(shè)備內(nèi)部存儲(chǔ)上的文件存儲(chǔ)目錄。 
  5.     File saveFile = new File(getFilesDir(), "IMG_" + System.currentTimeMillis() + ".jpg"); 
  6.     ohos.media.image.Image image = receiver.readNextImage(); 
  7.     //定義圖像格式,提供獲取圖像格式信息的接口。 
  8.     ohos.media.image.Image.Component component = image.getComponent(ImageFormat.ComponentType.JPEG); 
  9.     byte[] bytes = new byte[component.remaining()]; 
  10.     component.read(bytes); 
  11.     try (FileOutputStream output = new FileOutputStream(saveFile)) { 
  12.         output.write(bytes); 
  13.         output.flush(); 
  14.         showTips(this, "Take photo succeed"); 
  15.     } catch (IOException e) { 
  16.         HiLog.error(LABEL_LOG, "%{public}s""saveImage IOException"); 
  17.     } 

(4)錄制視頻

配置音視頻模塊

錄制視頻除了要進(jìn)行預(yù)覽配置,還需要進(jìn)行音視頻模塊的配置。

比如視頻編碼格式配置:

  1. setRecorderVideoEncoder(Recorder.VideoEncoder.H264) 

音頻編碼格式配置:

  1. setRecorderAudioEncoder(Recorder.AudioEncoder.AAC) 

以及視頻的編碼碼率、幀捕獲率、幀率配置等。代碼如下所示:

  1. private void initMediaRecorder() { 
  2.     mediaRecorder = new Recorder(); 
  3.     VideoProperty.Builder videoPropertyBuilder = new VideoProperty.Builder(); 
  4.     videoPropertyBuilder.setRecorderBitRate(10000000);//setRecorderBitRate:設(shè)置視頻編碼碼率。 
  5.     videoPropertyBuilder.setRecorderDegrees(90);  //setRecorderDegrees:設(shè)置視頻旋轉(zhuǎn)角度。 
  6.     videoPropertyBuilder.setRecorderFps(30);//setRecorderFps:設(shè)置視頻幀捕獲速率。 
  7.     videoPropertyBuilder.setRecorderHeight(Math.min(1440, 720));//設(shè)置視頻高度。 
  8.     videoPropertyBuilder.setRecorderWidth(Math.max(1440, 720));//設(shè)置視頻寬度。 
  9.     videoPropertyBuilder.setRecorderVideoEncoder(Recorder.VideoEncoder.H264);//setRecorderVideoEncoder:設(shè)置視頻編碼格式。 
  10.     videoPropertyBuilder.setRecorderRate(30);//setRecorderRate:設(shè)置視頻幀率。 
  11.  
  12.     Source source = new Source(); 
  13.     //表示使用麥克風(fēng)作為音頻源。 
  14.     source.setRecorderAudioSource(Recorder.AudioSource.MIC); 
  15.     //表示使用相機(jī)界面作為視頻源。 
  16.     source.setRecorderVideoSource(Recorder.VideoSource.SURFACE); 
  17.     mediaRecorder.setSource(source); 
  18.     //setOutputFormat:設(shè)置輸出文件格式。 
  19.     mediaRecorder.setOutputFormat(Recorder.OutputFormat.MPEG_4); 
  20.     //getFilesDir():獲取文件存儲(chǔ)目錄。 
  21.     File file = new File(getFilesDir(), "VID_" + System.currentTimeMillis() + ".mp4"); 
  22.     StorageProperty.Builder storagePropertyBuilder = new StorageProperty.Builder(); 
  23.     storagePropertyBuilder.setRecorderFile(file); 
  24.     mediaRecorder.setStorageProperty(storagePropertyBuilder.build()); 
  25.  
  26.     AudioProperty.Builder audioPropertyBuilder = new AudioProperty.Builder(); 
  27.     //setRecorderAudioEncoder:設(shè)置音頻編碼格式。 
  28.     audioPropertyBuilder.setRecorderAudioEncoder(Recorder.AudioEncoder.AAC); 
  29.     mediaRecorder.setAudioProperty(audioPropertyBuilder.build()); 
  30.     mediaRecorder.setVideoProperty(videoPropertyBuilder.build()); 
  31.     mediaRecorder.prepare(); 

開始錄制

通過設(shè)置長(zhǎng)按點(diǎn)擊事件偵聽器setLongClickedListener()來(lái)觸發(fā)startRecord(),實(shí)現(xiàn)開始錄制。代碼如下:

  1. //為組件中的長(zhǎng)單擊事件注冊(cè)偵聽器(單擊并按住組件)。所有注冊(cè)的觀察員都將收到調(diào)度到組件的長(zhǎng)單擊事件的通知。 
  2. videoRecord.setLongClickedListener(component -> { 
  3.     startRecord(); 
  4.     isRecording = true
  5.     videoRecord.setPixelMap(ResourceTable.Media_ic_camera_video_press); 
  6. }); 
  7.  
  8. private void startRecord() { 
  9.     if (cameraDevice == null) { 
  10.         HiLog.error(LABEL_LOG, "%{public}s""startRecord failed, parameters is illegal"); 
  11.         return
  12.     } 
  13.     synchronized (lock) { 
  14.         initMediaRecorder(); 
  15.         recorderSurface = mediaRecorder.getVideoSurface(); 
  16.         cameraConfigBuilder = cameraDevice.getCameraConfigBuilder(); 
  17.         try { 
  18.             cameraConfigBuilder.addSurface(previewSurface); 
  19.             if (recorderSurface != null) { 
  20.                 //添加界面作為相機(jī)流的輸出。 
  21.                 cameraConfigBuilder.addSurface(recorderSurface); 
  22.             } 
  23.             cameraDevice.configure(cameraConfigBuilder.build()); 
  24.         } catch (IllegalStateException | IllegalArgumentException e) { 
  25.             HiLog.error(LABEL_LOG, "%{public}s""startRecord IllegalStateException "); 
  26.         } 
  27.     } 
  28.     new ToastDialog(this).setText("Recording").show(); 

停止錄制

通過設(shè)置觸摸事件偵聽器setTouchEventListener()來(lái)觸發(fā)stopRecord(),實(shí)現(xiàn)停止錄制。

  1. //在組件中注冊(cè)觸摸事件的偵聽器。所有注冊(cè)的觀察員都將收到調(diào)度到組件的觸摸事件的通知。 
  2. videoRecord.setTouchEventListener((component, touchEvent) -> { 
  3.     if (touchEvent != null && touchEvent.getAction() == TouchEvent.PRIMARY_POINT_UP && isRecording) { 
  4.         stopRecord(); 
  5.         isRecording = false
  6.         videoRecord.setPixelMap(ResourceTable.Media_ic_camera_video_ready); 
  7.     } 
  8.     return true
  9. }); 
  10.  
  11. private void stopRecord() { 
  12.     synchronized (lock) { 
  13.         try { 
  14.             eventHandler.postTask(() -> mediaRecorder.stop());//stop():停止錄制。 
  15.             if (cameraDevice == null || cameraDevice.getCameraConfigBuilder() == null) { 
  16.                 HiLog.error(LABEL_LOG, "%{public}s""StopRecord cameraDevice or getCameraConfigBuilder is null"); 
  17.                 return
  18.             } 
  19.             cameraConfigBuilder = cameraDevice.getCameraConfigBuilder(); 
  20.             cameraConfigBuilder.addSurface(previewSurface); 
  21.             cameraConfigBuilder.removeSurface(recorderSurface); 
  22.             cameraDevice.configure(cameraConfigBuilder.build()); 
  23.         } catch (IllegalStateException | IllegalArgumentException exception) { 
  24.             HiLog.error(LABEL_LOG, "%{public}s""stopRecord occur exception"); 
  25.         } 
  26.     } 
  27.     new ToastDialog(this).setText("video saved").show(); 

視頻存儲(chǔ)和照片存儲(chǔ)類似,本文就不做贅述,更多相機(jī)的開發(fā)請(qǐng)參照HarmonyOS相機(jī)開發(fā)指導(dǎo):

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/media-camera-overview-0000000000031783

相機(jī)設(shè)備釋放

使用完相機(jī)后,必須通過release()來(lái)關(guān)閉相機(jī)和釋放資源,否則可能導(dǎo)致其他相機(jī)應(yīng)用無(wú)法啟動(dòng)。一旦相機(jī)被釋放,它所提供的操作就不能再被調(diào)用,否則會(huì)導(dǎo)致不可預(yù)期的結(jié)果,或是會(huì)引發(fā)狀態(tài)異常。相機(jī)設(shè)備釋放的示例代碼如下:

  1. private void releaseCamera() { 
  2.     if (cameraDevice != null) { 
  3.         //release():釋放攝像機(jī)。 
  4.         //釋放攝像機(jī)后,攝像機(jī)的所有操作都不可用。任何操作都會(huì)導(dǎo)致意外結(jié)果或異常。 
  5.         cameraDevice.release(); 
  6.     } 
  7.     if (imageReceiver != null) { 
  8.         imageReceiver.release(); 
  9.     } 

 至此,就完成了一個(gè)具有拍攝照片和錄制視頻功能的相機(jī)開發(fā),開發(fā)者也可以通過合適的接口或者接口組合實(shí)現(xiàn)閃光燈控制、曝光時(shí)間控制、手動(dòng)對(duì)焦和自動(dòng)對(duì)焦控制、變焦控制、人臉識(shí)別以及更多的功能。

文章相關(guān)附件可以點(diǎn)擊下面的原文鏈接前往下載

相機(jī)示例程序的完整代碼.zip

想了解更多內(nèi)容,請(qǐng)?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來(lái)源: 鴻蒙社區(qū)
相關(guān)推薦

2025-03-11 14:45:31

2011-12-19 20:54:28

iOS

2021-11-02 10:10:49

鴻蒙HarmonyOS應(yīng)用

2023-05-15 16:12:32

GitHub項(xiàng)目

2010-03-22 15:06:05

WiMAX無(wú)線技術(shù)

2015-08-07 14:48:26

移動(dòng)開發(fā)企業(yè)APPiUAP Mobile

2017-02-22 15:04:52

2025-04-14 00:00:00

MCPjson 信息地理編碼

2025-02-10 11:11:47

2012-03-07 14:37:03

JavaJavaMail

2012-11-05 10:36:40

IBMdw

2024-05-16 10:59:16

Vue項(xiàng)目前端

2025-03-03 10:00:00

2023-05-30 14:58:05

智能開發(fā)鴻蒙

2023-05-26 16:01:32

驅(qū)動(dòng)開發(fā)鴻蒙

2015-11-12 09:57:57

前端零基礎(chǔ)學(xué)習(xí)

2022-08-26 01:46:33

注冊(cè)中心NacosDNS

2018-08-31 21:59:53

2022-03-23 15:17:00

Harmony鴻蒙操作系統(tǒng)

2020-05-22 08:24:21

SQLMySQL數(shù)據(jù)庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)