一、简介
媒体子系统为开发者提供了媒体相关的很多功能,本文针对其中的视频录制功能做个详细的介绍。首先,我将通过媒体子系统提供的视频录制Test代码作为切入点,给大家梳理一下整个录制的流程。
二、目录
foundation/multimedia/camera_framework
├── frameworks
│ ├── js
│ │ └── camera_napi #napi实现
│ │ └── src
│ │ ├── input #Camera输入
│ │ ├── output #Camera输出
│ │ └── session #会话管理
│ └── native #native实现
│ └── camera
│ ├── BUILD.gn
│ ├── src
│ │ ├── input #Camera输入
│ │ ├── output #Camera输出
│ │ └── session #会话管理
├── interfaces #接口定义
│ ├── inner_api #内部native实现
│ │ └── native
│ │ ├── camera
│ │ │ └── include
│ │ │ ├── input
│ │ │ ├── output
│ │ │ └── session
│ └── kits #napi接口
│ └── js
│ └── camera_napi
│ ├── BUILD.gn
│ ├── include
│ │ ├── input
│ │ ├── output
│ │ └── session
│ └── @ohos.multimedia.camera.d.ts
└── services #服务端
└── camera_service
├── binder
│ ├── base
│ ├── client #IPC的客户端
│ │ └── src
│ └── server #IPC的服务端
│ └── src
└── src
三、录制的总体流程
四、Native接口使用
在OpenAtom OpenHarmony(以下简称“OpenHarmony”)系统中,多媒体子系统通过N-API接口提供给上层JS调用,N-API相当于是JS和Native之间的桥梁,在OpenHarmony源码中,提供了C++直接调用视频录制功能的例子,foundation/multimedia/camera_framework/interfaces/inner_api/native/test目录中。本文章主要参考了camera_video.cpp文件中的视频录制流程。
首先根据camera_video.cpp的main方法,了解下视频录制的主要流程代码。
int main(int argc, char **argv)
{
......
// 创建CameraManager实例
sptr<CameraManager> camManagerObj = CameraManager::GetInstance();
// 设置回调
camManagerObj->SetCallback(std::make_shared<TestCameraMngerCallback>(testName));
// 获取支持的相机设备列表
std::vector<sptr<CameraDevice>> cameraObjList = camManagerObj->GetSupportedCameras();
// 创建采集会话
sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession();
// 开始配置采集会话
captureSession->BeginConfig();
// 创建CameraInput
sptr<CaptureInput> captureInput = camManagerObj->CreateCameraInput(cameraObjList[0]);
sptr<CameraInput> cameraInput = (sptr<CameraInput> &)captureInput;
// 开启CameraInput
cameraInput->Open();
// 设置CameraInput的Error回调
cameraInput->SetErrorCallback(std::make_shared<TestDeviceCallback>(testName));
// 添加CameraInput实例到采集会话中
ret = captureSession->AddInput(cameraInput);
sptr<Surface> videoSurface = nullptr;
std::shared_ptr<Recorder> recorder = nullptr;
// 创建Video的Surface
videoSurface = Surface::CreateSurfaceAsConsumer();
sptr<SurfaceListener> videoListener = new SurfaceListener("Video", SurfaceType::VIDEO, g_videoFd, videoSurface);
// 注册Surface的事件监听
videoSurface->RegisterConsumerListener((sptr<IBufferConsumerListener> &)videoListener);
// 视频的配置
VideoProfile videoprofile = VideoProfile(static_cast<CameraFormat>(videoFormat), videosize, videoframerates);
// 创建VideoOutput实例
sptr<CaptureOutput> videoOutput = camManagerObj->CreateVideoOutput(videoprofile, videoSurface);
// 设置VideoOutput的回调
((sptr<VideoOutput> &)videoOutput)->SetCallback(std::make_shared<TestVideoOutputCallback>(testName));
// 添加videoOutput到采集会话中
ret = captureSession->AddOutput(videoOutput);
// 提交会话配置
ret = captureSession->CommitConfig();
// 开始录制
ret = ((sptr<VideoOutput> &)videoOutput)->Start();
sleep(videoPauseDuration);
MEDIA_DEBUG_LOG("Resume video recording");
// 暂停录制
ret = ((sptr<VideoOutput> &)videoOutput)->Resume();
MEDIA_DEBUG_LOG("Wait for 5 seconds before stop");
sleep(videoCaptureDuration);
MEDIA_DEBUG_LOG("Stop video recording");
// 停止录制
ret = ((sptr<VideoOutput> &)videoOutput)->Stop();
MEDIA_DEBUG_LOG("Closing the session");
// 停止采集会话
ret = captureSession->Stop();
MEDIA_DEBUG_LOG("Releasing the session");
// 释放会话采集
captureSession->Release();
//Close video file
TestUtils::SaveVideoFile(nullptr,0,VideoSaveMode::CLOSE, g_videoFd);
cameraInput->Release();