0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

OpenHarmony视频录制流程介绍

OpenHarmony技术社区 来源:OST开源开发者 2023-02-20 10:39 次阅读

媒体子系统为开发者提供了媒体相关的很多功能,本文针对其中的视频录制功能做个详细的介绍。

首先,我将通过媒体子系统提供的视频录制 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

录制的总体流程

如下图:

f4ab7608-b069-11ed-bfe3-dac502259ad0.png

Native接口使用

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 方法,了解下视频录制的主要流程代码:

intmain(intargc,char**argv)
{
......

//创建CameraManager实例
sptrcamManagerObj=CameraManager::GetInstance();

//设置回调
camManagerObj->SetCallback(std::make_shared(testName));

//获取支持的相机设备列表
std::vector>cameraObjList=camManagerObj->GetSupportedCameras();

//创建采集会话
sptrcaptureSession=camManagerObj->CreateCaptureSession();

//开始配置采集会话
captureSession->BeginConfig();

//创建CameraInput
sptrcaptureInput=camManagerObj->CreateCameraInput(cameraObjList[0]);
sptrcameraInput=(sptr&)captureInput;

//开启CameraInput
cameraInput->Open();

//设置CameraInput的Error回调
cameraInput->SetErrorCallback(std::make_shared(testName));

//添加CameraInput实例到采集会话中
ret=captureSession->AddInput(cameraInput);

sptrvideoSurface=nullptr;
std::shared_ptrrecorder=nullptr;

//创建Video的Surface
videoSurface=Surface::CreateSurfaceAsConsumer();

sptrvideoListener=newSurfaceListener("Video",SurfaceType::VIDEO,g_videoFd,videoSurface);

//注册Surface的事件监听
videoSurface->RegisterConsumerListener((sptr&)videoListener);

//视频的配置
VideoProfilevideoprofile=VideoProfile(static_cast(videoFormat),videosize,videoframerates);

//创建VideoOutput实例
sptrvideoOutput=camManagerObj->CreateVideoOutput(videoprofile,videoSurface);

//设置VideoOutput的回调
((sptr&)videoOutput)->SetCallback(std::make_shared(testName));

//添加videoOutput到采集会话中
ret=captureSession->AddOutput(videoOutput);

//提交会话配置
ret=captureSession->CommitConfig();

//开始录制
ret=((sptr&)videoOutput)->Start();


sleep(videoPauseDuration);
MEDIA_DEBUG_LOG("Resumevideorecording");
//暂停录制
ret=((sptr&)videoOutput)->Resume();

MEDIA_DEBUG_LOG("Waitfor5secondsbeforestop");
sleep(videoCaptureDuration);
MEDIA_DEBUG_LOG("Stopvideorecording");
//停止录制
ret=((sptr&)videoOutput)->Stop();

MEDIA_DEBUG_LOG("Closingthesession");
//停止采集会话
ret=captureSession->Stop();

MEDIA_DEBUG_LOG("Releasingthesession");
//释放会话采集
captureSession->Release();

//Closevideofile
TestUtils::SaveVideoFile(nullptr,0,VideoSaveMode::CLOSE,g_videoFd);
cameraInput->Release();
camManagerObj->SetCallback(nullptr);
return0;
}

以上是视频录制的整体流程,其过程主要通过 Camera 模块支持的能力来实现,其中涉及几个重要的类:CaptureSession、CameraInput、VideoOutput。

CaptureSession 是整个过程的控制者,CameraInput 和 VideoOutput 相当于是设备的输入和输出。

调用流程

如下图:

f4bcbf1c-b069-11ed-bfe3-dac502259ad0.png

后续主要针对上面的调用流程,梳理具体的调用流程,方便我们对了解视频录制的整理架构有一个更加深入的了解。

①创建 CameraManager 实例

通过 CameraManager::GetInstance() 获取 CameraManager 的实例,后续的一些接口都是通过该实例进行调用的。

GetInstance 使用了单例模式,在 OpenHarmony 代码中这种方式很常见。

sptr&CameraManager::GetInstance()
{
if(CameraManager::cameraManager_==nullptr){
MEDIA_INFO_LOG("Initializingcameramanagerforfirsttime!");
CameraManager::cameraManager_=new(std::nothrow)CameraManager();
if(CameraManager::cameraManager_==nullptr){
MEDIA_ERR_LOG("CameraManager::GetInstancefailedtonewCameraManager");
}
}
returnCameraManager::cameraManager_;
}

②获取支持的相机设备列表

通过调用 CameraManager 的 GetSupportedCameras() 接口,获取设备支持的 CameraDevice 列表。

跟踪代码可以发现 serviceProxy_->GetCameras 最终会调用到 Camera 服务端的对应接口。

std::vector>CameraManager::GetSupportedCameras()
{
CAMERA_SYNC_TRACE;

std::lock_guardlock(mutex_);
std::vectorcameraIds;
std::vector>cameraAbilityList;
int32_tretCode=-1;
sptrcameraObj=nullptr;
int32_tindex=0;

if(cameraObjList.size()>0){
cameraObjList.clear();
}
if(serviceProxy_==nullptr){
MEDIA_ERR_LOG("CameraManager::GetCamerasserviceProxy_isnull,returningemptylist!");
returncameraObjList;
}
std::vector>supportedCameras;
retCode=serviceProxy_->GetCameras(cameraIds,cameraAbilityList);
if(retCode==CAMERA_OK){
for(auto&it:cameraIds){
cameraObj=new(std::nothrow)CameraDevice(it,cameraAbilityList[index++]);
if(cameraObj==nullptr){
MEDIA_ERR_LOG("CameraManager::GetCamerasnewCameraDevicefailedforid={public}%s",it.c_str());
continue;
}
supportedCameras.emplace_back(cameraObj);
}
}else{
MEDIA_ERR_LOG("CameraManager::GetCamerasfailed!,retCode:%{public}d",retCode);
}

ChooseDeFaultCameras(supportedCameras);
returncameraObjList;
}
③创建采集会话

下面是比较重要的环节,通过调用 CameraManager 的 CreateCaptureSession 接口创建采集会话。 CameraManager 创建采集会话,是通过 serviceProxy_->CreateCaptureSession 方式进行调用。

这里涉及到了 OpenHarmony 中的 IPC 的调用,serviceProxy_ 是远端服务在本地的代理,通过这个代理可以调用到具体的服务端,这里是 HCameraService。

sptrCameraManager::CreateCaptureSession()
{
CAMERA_SYNC_TRACE;
sptrcaptureSession=nullptr;
sptrresult=nullptr;
int32_tretCode=CAMERA_OK;

if(serviceProxy_==nullptr){
MEDIA_ERR_LOG("CameraManager::CreateCaptureSessionserviceProxy_isnull");
returnnullptr;
}
retCode=serviceProxy_->CreateCaptureSession(captureSession);
if(retCode==CAMERA_OK&&captureSession!=nullptr){
result=new(std::nothrow)CaptureSession(captureSession);
if(result==nullptr){
MEDIA_ERR_LOG("FailedtonewCaptureSession");
}
}else{
MEDIA_ERR_LOG("Failedtogetcapturesessionobjectfromhcameraservice!,%{public}d",retCode);
}
returnresult;
}
代码最终来到 HCameraService::CreateCaptureSession 中,该方法中 new 了一个 HCaptureSession 对象,并且将该对象传递给了参数 session。

所以前面的 captureSession 对象就是这里 new 出来的 HCaptureSession,前面的 CameraManager 的 CreateCaptureSession() 方法中将 captureSession 封装成 CaptureSession 对象返回给应用层使用。

int32_tHCameraService::CreateCaptureSession(sptr&session)
{
CAMERA_SYNC_TRACE;
sptrcaptureSession;
if(streamOperatorCallback_==nullptr){
streamOperatorCallback_=new(std::nothrow)StreamOperatorCallback();
if(streamOperatorCallback_==nullptr){
MEDIA_ERR_LOG("HCameraService::CreateCaptureSessionstreamOperatorCallback_allocationfailed");
returnCAMERA_ALLOC_ERROR;
}
}

std::lock_guardlock(mutex_);
OHOS::AccessTokenIDcallerToken=IPCSkeleton::GetCallingTokenID();
captureSession=new(std::nothrow)HCaptureSession(cameraHostManager_,streamOperatorCallback_,callerToken);
if(captureSession==nullptr){
MEDIA_ERR_LOG("HCameraService::CreateCaptureSessionHCaptureSessionallocationfailed");
returnCAMERA_ALLOC_ERROR;
}
session=captureSession;
returnCAMERA_OK;
}

④开始配置采集会话

调用 CaptureSession 的 BeginConfig 进行采集会话的配置工作。这个工作最终调用到被封装的 HCaptureSession 中。

int32_tHCaptureSession::BeginConfig()
{
CAMERA_SYNC_TRACE;
if(curState_==CaptureSessionState::SESSION_CONFIG_INPROGRESS){
MEDIA_ERR_LOG("HCaptureSession::BeginConfigAlreadyinconfiginprogressstate!");
returnCAMERA_INVALID_STATE;
}
std::lock_guardlock(sessionLock_);
prevState_=curState_;
curState_=CaptureSessionState::SESSION_CONFIG_INPROGRESS;
tempCameraDevices_.clear();
tempStreams_.clear();
deletedStreamIds_.clear();
returnCAMERA_OK;
}

⑤创建 CameraInput

应用层通过 camManagerObj->CreateCameraInput(cameraObjList[0]) 的方式进行 CameraInput 的创建,cameraObjList[0] 就是前面获取支持设备的第一个。根据 CameraDevice 创建对应的 CameraInput 对象。

sptrCameraManager::CreateCameraInput(sptr&camera)
{
CAMERA_SYNC_TRACE;
sptrcameraInput=nullptr;
sptrdeviceObj=nullptr;

if(camera!=nullptr){
deviceObj=CreateCameraDevice(camera->GetID());
if(deviceObj!=nullptr){
cameraInput=new(std::nothrow)CameraInput(deviceObj,camera);
if(cameraInput==nullptr){
MEDIA_ERR_LOG("failedtonewCameraInputReturningnullinCreateCameraInput");
returncameraInput;
}
}else{
MEDIA_ERR_LOG("ReturningnullinCreateCameraInput");
}
}else{
MEDIA_ERR_LOG("CameraManager:Cameraobjectisnull");
}
returncameraInput;
}
⑥开启 CameraInput

调用了 CameraInput 的 Open 方法,进行输入设备的启动打开。

voidCameraInput::Open()
{
int32_tretCode=deviceObj_->Open();
if(retCode!=CAMERA_OK){
MEDIA_ERR_LOG("FailedtoopenCameraInput,retCode:%{public}d",retCode);
}
}

⑦添加 CameraInput 实例到采集会话中

通过调用 captureSession 的 AddInput 方法,将创建的 CameraInput 对象添加到采集会话的输入中,这样采集会话就知道采集输入的设备。

int32_tCaptureSession::AddInput(sptr&input)
{
CAMERA_SYNC_TRACE;
if(input==nullptr){
MEDIA_ERR_LOG("CaptureSession::AddInputinputisnull");
returnCAMERA_INVALID_ARG;
}
input->SetSession(this);
inputDevice_=input;
returncaptureSession_->AddInput(((sptr&)input)->GetCameraDevice());
}

最终调用到 HCaptureSession 的 AddInput 方法,该方法中核心的代码是 tempCameraDevices_.emplace_back(localCameraDevice),将需要添加的 CameraDevice 插入到 tempCameraDevices_ 容器中。

int32_tHCaptureSession::AddInput(sptrcameraDevice)
{
CAMERA_SYNC_TRACE;
sptrlocalCameraDevice=nullptr;

if(cameraDevice==nullptr){
MEDIA_ERR_LOG("HCaptureSession::AddInputcameraDeviceisnull");
returnCAMERA_INVALID_ARG;
}
if(curState_!=CaptureSessionState::SESSION_CONFIG_INPROGRESS){
MEDIA_ERR_LOG("HCaptureSession::AddInputNeedtocallBeginConfigbeforeaddinginput");
returnCAMERA_INVALID_STATE;
}
if(!tempCameraDevices_.empty()||(cameraDevice_!=nullptr&&!cameraDevice_->IsReleaseCameraDevice())){
MEDIA_ERR_LOG("HCaptureSession::AddInputOnlyoneinputissupported");
returnCAMERA_INVALID_SESSION_CFG;
}
localCameraDevice=static_cast(cameraDevice.GetRefPtr());
if(cameraDevice_==localCameraDevice){
cameraDevice_->SetReleaseCameraDevice(false);
}else{
tempCameraDevices_.emplace_back(localCameraDevice);
CAMERA_SYSEVENT_STATISTIC(CreateMsg("CaptureSession::AddInput"));
}

sptrstreamOperator;
int32_trc=localCameraDevice->GetStreamOperator(streamOperatorCallback_,streamOperator);
if(rc!=CAMERA_OK){
MEDIA_ERR_LOG("HCaptureSession::GetCameraDeviceGetStreamOperatorreturned%{public}d",rc);
localCameraDevice->Close();
returnrc;
}
returnCAMERA_OK;
}
⑧创建 Video 的 Surface

通过 Surface::CreateSurfaceAsConsumer 创建 Surface。

sptrSurface::CreateSurfaceAsConsumer(std::stringname,boolisShared)
{
sptrsurf=newConsumerSurface(name,isShared);
GSErrorret=surf->Init();
if(ret!=GSERROR_OK){
BLOGE("Failure,Reason:consumersurfinitfailed");
returnnullptr;
}
returnsurf;
}
⑨创建 VideoOutput 实例

通过调用 CameraManager 的 CreateVideoOutput 来创建 VideoOutput 实例。

sptrCameraManager::CreateVideoOutput(VideoProfile&profile,sptr&surface)
{
CAMERA_SYNC_TRACE;
sptrstreamRepeat=nullptr;
sptrresult=nullptr;
int32_tretCode=CAMERA_OK;
camera_format_tmetaFormat;

metaFormat=GetCameraMetadataFormat(profile.GetCameraFormat());
retCode=serviceProxy_->CreateVideoOutput(surface->GetProducer(),metaFormat,
profile.GetSize().width,profile.GetSize().height,streamRepeat);
if(retCode==CAMERA_OK){
result=new(std::nothrow)VideoOutput(streamRepeat);
if(result==nullptr){
MEDIA_ERR_LOG("FailedtonewVideoOutput");
}else{
std::vectorvideoFrameRates=profile.GetFrameRates();
if(videoFrameRates.size()>=2){//vaildframeraterangelengthis2
result->SetFrameRateRange(videoFrameRates[0],videoFrameRates[1]);
}
POWERMGR_SYSEVENT_CAMERA_CONFIG(VIDEO,
profile.GetSize().width,
profile.GetSize().height);
}
}else{
MEDIA_ERR_LOG("VideoOutpout:Failedtogetstreamrepeatobjectfromhcameraservice!%{public}d",retCode);
}
returnresult;
}

该方法中通过 IPC 的调用最终调用到了 HCameraService 的:

CreateVideoOutput(surface->GetProducer(),format,streamRepeat)

int32_tHCameraService::CreateVideoOutput(constsptr&producer,int32_tformat,
int32_twidth,int32_theight,
sptr&videoOutput)
{
CAMERA_SYNC_TRACE;
sptrstreamRepeatVideo;

if((producer==nullptr)||(width==0)||(height==0)){
MEDIA_ERR_LOG("HCameraService::CreateVideoOutputproducerisnull");
returnCAMERA_INVALID_ARG;
}
streamRepeatVideo=new(std::nothrow)HStreamRepeat(producer,format,width,height,true);
if(streamRepeatVideo==nullptr){
MEDIA_ERR_LOG("HCameraService::CreateVideoOutputHStreamRepeatallocationfailed");
returnCAMERA_ALLOC_ERROR;
}
POWERMGR_SYSEVENT_CAMERA_CONFIG(VIDEO,producer->GetDefaultWidth(),
producer->GetDefaultHeight());
videoOutput=streamRepeatVideo;
returnCAMERA_OK;
}

HCameraService 的 CreateVideoOutput 方法中主要创建了 HStreamRepeat,并且通过参数传递给前面的 CameraManager 使用,CameraManager 通过传递的 HStreamRepeat 对象,进行封装,创建出 VideoOutput 对象。

⑩添加 videoOutput 到采集会话中,并且提交采集会话 该步骤类似添加 CameraInput 到采集会话的过程,可以参考前面的流程。 ⑪开始录制

通过调用 VideoOutput 的 Start 进行录制的操作。

int32_tVideoOutput::Start()
{
returnstatic_cast(GetStream().GetRefPtr())->Start();
}

该方法中会调用到 HStreamRepeat 的 Start 方法。

int32_tHStreamRepeat::Start()
{
CAMERA_SYNC_TRACE;

if(streamOperator_==nullptr){
returnCAMERA_INVALID_STATE;
}
if(curCaptureID_!=0){
MEDIA_ERR_LOG("HStreamRepeat::Start,AlreadystartedwithcaptureID:%{public}d",curCaptureID_);
returnCAMERA_INVALID_STATE;
}
int32_tret=AllocateCaptureId(curCaptureID_);
if(ret!=CAMERA_OK){
MEDIA_ERR_LOG("HStreamRepeat::StartFailedtoallocateacaptureId");
returnret;
}
std::vectorability;
OHOS::ConvertMetadataToVec(cameraAbility_,ability);
CaptureInfocaptureInfo;
captureInfo.streamIds_={streamId_};
captureInfo.captureSetting_=ability;
captureInfo.enableShutterCallback_=false;
MEDIA_INFO_LOG("HStreamRepeat::StartStartingwithcaptureID:%{public}d",curCaptureID_);
CamRetCoderc=(CamRetCode)(streamOperator_->Capture(curCaptureID_,captureInfo,true));
if(rc!=HDI::NO_ERROR){
ReleaseCaptureId(curCaptureID_);
curCaptureID_=0;
MEDIA_ERR_LOG("HStreamRepeat::StartFailedwitherrorCode:%{public}d",rc);
ret=HdiToServiceError(rc);
}
returnret;
}
核心的代码是 streamOperator_->Capture,其中最后一个参数 true,表示采集连续数据。 ⑫录制结束,保存录制文件

总结

本文主要对 OpenHarmony 3.2 Beta 多媒体子系统的视频录制进行介绍,首先梳理了整体的录制流程,然后对录制过程中的主要步骤进行了详细地分析。

视频录制主要分为以下几个步骤:

获取 CameraManager 实例。

创建采集会话 CaptureSession。

创建 CameraInput 实例,并且将输入设备添加到 CaptureSession 中。

创建 Video 录制需要的 Surface。

创建 VideoOutput 实例,并且将输出添加到 CaptureSession 中。

提交采集会话的配置。

调用 VideoOutput 的 Start 方法,进行视频的录制。

录制结束,保存录制的文件。

作者:巴延兴

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    7639

    浏览量

    148495
  • 视频
    +关注

    关注

    6

    文章

    1891

    浏览量

    71903
  • 媒体
    +关注

    关注

    1

    文章

    61

    浏览量

    14260
  • C++
    C++
    +关注

    关注

    21

    文章

    2066

    浏览量

    72900
  • OpenHarmony
    +关注

    关注

    23

    文章

    3297

    浏览量

    15159

原文标题:OpenHarmony视频录制流程

文章出处:【微信号:gh_834c4b3d87fe,微信公众号:OpenHarmony技术社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    游戏录制软件玩***宝2.0发布,高清特效打造完美游戏视频

    成了重中之重,今天给大家介绍一款专门针对游戏玩家而言的一款录制视频软件——玩***宝。玩***宝:下载地址官网下载地址:http://www.weplay.cn/download/baobao.html
    发表于 09-25 16:53

    [分享]真实课堂录制!Java入门速成视频教程[转载自太平洋]

    真实课堂录制!Java入门速成视频教程[转载自太平洋] 这一套Java视频教程是完全真实课堂录制,实际学习时间为十一天,由从基础到入门,再到全面掌握,是一个全新的Java入门速成
    发表于 03-02 15:20

    CC3200MOD 录制视频问题

    请问,是否可以把rtp接收到的视频流和音频数据,解码并保存到SFLASH上,成为完整的视频文件(格式avi/MP4等)?录制视频大概5秒左右,大小1.4m左右。
    发表于 06-23 00:48

    OpenHarmony 3.2 Beta多媒体系列——视频录制

    一、简介媒体子系统为开发者提供了媒体相关的很多功能,本文针对其中的视频录制功能做个详细的介绍。首先,我将通过媒体子系统提供的视频录制Test
    发表于 02-09 15:47

    数码相机MPEG-4视频录制

    数码相机MPEG-4视频录制         
    发表于 12-18 17:04 604次阅读

    数码相机MPEG-4视频录制

    数码相机MPEG-4视频录制              数码
    发表于 12-18 17:07 723次阅读

    MP4视频录制格式主要有哪些

    MP4视频录制格式主要有哪些  视频录制格式是指MP4通过AV接口与电视相连录制电视节目
    发表于 12-21 15:57 2082次阅读

    下载什么录制视频软件好用?

    也很无奈,没关系,今天为大家介绍一款很好用的简单APP,它的功能很齐全,但是占地内存却很小,你可不要小瞧了它,它绝对是你需要的那一款好用的录像工具。录制时的画质也可以选择,视频模式,声音都可以选择你想
    发表于 07-05 17:24 322次阅读

    2021年最实用的5款视频录制软件

    如今的互联网上充斥着大量的电脑视频录制工具,这些工具可以轻松地记录电脑屏幕上的画面与进程。如今,离线和在线视频录制软件都很丰富,但离线工具被认为是更好的选择,因为它们速度快,通常还有很
    的头像 发表于 03-02 16:56 2950次阅读

    在Mac上录制视频的4种简单又高效的方法

    当你使用Mac观看教程、玩游戏、进行视频通话等时,你可能想在Mac上进行视频录制。这里有不同的方法来录制屏幕和音频,甚至是摄像头下的自己,在这篇文章中,我们将
    的头像 发表于 03-02 18:06 6506次阅读

    怎么录制教学视频?这两招解决你的录屏需求

    、画面参数,也不能录制系统声音,想要录制视频声音的时候只能外放,不是很方便。这里再介绍一款我自己在用的录屏软件,录制PS课程的时候,会使用它
    发表于 06-21 14:31 1828次阅读
    怎么<b class='flag-5'>录制</b>教学<b class='flag-5'>视频</b>?这两招解决你的录屏需求

    怎样录制视频会议,如何用HDT101录制视频会议

    视频会议已经成为各企事业单位党政机关采用的主要会议模式,同时,视频会议的录制,也成为必不可缺少的环节。采用功能适用、操作简易、价格实惠的视频会议录播机,已经形成趋势。本文推荐的春源丽影
    发表于 10-05 10:10 1376次阅读
    怎样<b class='flag-5'>录制</b><b class='flag-5'>视频</b>会议,如何用HDT101<b class='flag-5'>录制</b><b class='flag-5'>视频</b>会议

    OpenHarmony Dev-Board-SIG专场:华秋视频营销矩阵—硬声短视频APP助力OpenHarmony硬件创新

    OpenHarmony Dev-Board-SIG专场:华秋视频营销矩阵—硬声短视频APP助力OpenHarmony硬件创新
    的头像 发表于 12-28 15:21 1353次阅读
    <b class='flag-5'>OpenHarmony</b> Dev-Board-SIG专场:华秋<b class='flag-5'>视频</b>营销矩阵—硬声短<b class='flag-5'>视频</b>APP助力<b class='flag-5'>OpenHarmony</b>硬件创新

    OpenHarmony 3.2 Beta多媒体系列——视频录制

    巴延兴 深圳开鸿数字产业发展有限公司 资深OS框架开发工程师 一、简介 媒体子系 统为开发者提供了媒体相关的很多功能,本文针对其中的视频录制功能做个详细的介绍。 首先,我将通过媒体子系统提供的
    的头像 发表于 02-10 11:20 334次阅读

    OpenHarmony 3.2 Beta多媒体系列:视频录制

    一、简介 媒体子系统为开发者提供了媒体相关的很多功能,本文针对其中的视频录制功能做个详细的介绍。首先,我将通过媒体子系统提供的视频录制Tes
    的头像 发表于 02-15 15:55 314次阅读