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

    文章

    8436

    浏览量

    150692
  • 视频
    +关注

    关注

    6

    文章

    1929

    浏览量

    72763
  • 媒体
    +关注

    关注

    1

    文章

    62

    浏览量

    14380
  • C++
    C++
    +关注

    关注

    21

    文章

    2096

    浏览量

    73447
  • OpenHarmony
    +关注

    关注

    25

    文章

    3629

    浏览量

    16031

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

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

收藏 人收藏

    评论

    相关推荐

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

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

    CC3200MOD 录制视频问题

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

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

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

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

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

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

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

    如何有效录制游戏视频?6款最佳PC和Mac游戏录制工具推荐给你

    伴随着电竞行业和游戏主播的日益兴起,越来越多精通游戏技巧的玩家开始在分享平台上发布自己的视频片段进而收获粉丝的关注。为了记录下游戏中的实时操作画面,你需要拥有一个简单易操作却又有着专业素质的游戏录制
    的头像 发表于 02-22 16:48 2024次阅读

    如何在Windows 10上轻松快速地录制视频

    如果你有关于如何在windows 10上录制视频的相关问题,那么这篇文章将为你带来答案。你可以使用大量的工具来录制高质量的视频。这些屏幕录制
    的头像 发表于 03-02 16:56 2741次阅读

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

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

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

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

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

    视频会议已经成为各企事业单位党政机关采用的主要会议模式,同时,视频会议的录制,也成为必不可缺少的环节。采用功能适用、操作简易、价格实惠的视频会议录播机,已经形成趋势。本文推荐的春源丽影
    发表于 10-05 10:10 1639次阅读
    怎样<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 1487次阅读
    <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>硬件创新

    迷你视频录制和流媒体机器人开源分享

    电子发烧友网站提供《迷你视频录制和流媒体机器人开源分享.zip》资料免费下载
    发表于 11-10 11:38 3次下载
    迷你<b class='flag-5'>视频</b><b class='flag-5'>录制</b>和流媒体机器人开源分享

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

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

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

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

    10分钟快速掌握OpenHarmony社区贡献新流程

    (以下简称OpenHarmony)社区优化了Issue和PR处理流程,新支持了一系列交互命令和状态标签,用于明确处理阶段和当前处理责任人。社区CI Bot工具还提供了待办事项提醒能力,并能自动处理超期
    的头像 发表于 06-20 21:10 634次阅读