吴忠躺衫网络科技有限公司

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

    文章

    8691

    瀏覽量

    151911
  • 視頻
    +關注

    關注

    6

    文章

    1956

    瀏覽量

    73137
  • 媒體
    +關注

    關注

    1

    文章

    65

    瀏覽量

    14465
  • C++
    C++
    +關注

    關注

    22

    文章

    2114

    瀏覽量

    73854
  • OpenHarmony
    +關注

    關注

    25

    文章

    3744

    瀏覽量

    16577

原文標題: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 ?2443次閱讀

    下載什么錄制視頻軟件好用?

    無奈,沒關系,今天為大家介紹一款很好用的簡單APP,它的功能很齊全,但是占地內存卻很小,你可不要小瞧了它,它絕對是你需要的那一款好用的錄像工具。錄制時的畫質也可以選擇,視頻模式,聲音都可以選擇你想
    發表于 07-05 17:24 ?471次閱讀

    如何有效錄制游戲視頻?6款最佳PC和Mac游戲錄制工具推薦給你

    伴隨著電競行業和游戲主播的日益興起,越來越多精通游戲技巧的玩家開始在分享平臺上發布自己的視頻片段進而收獲粉絲的關注。為了記錄下游戲中的實時操作畫面,你需要擁有一個簡單易操作卻又有著專業素質的游戲錄制
    的頭像 發表于 02-22 16:48 ?2101次閱讀

    如何在Windows 10上輕松快速地錄制視頻

    如果你有關于如何在windows 10上錄制視頻的相關問題,那么這篇文章將為你帶來答案。你可以使用大量的工具來錄制高質量的視頻。這些屏幕錄制
    的頭像 發表于 03-02 16:56 ?2835次閱讀

    2021年最實用的5款視頻錄制軟件

    如今的互聯網上充斥著大量的電腦視頻錄制工具,這些工具可以輕松地記錄電腦屏幕上的畫面與進程。如今,離線和在線視頻錄制軟件都很豐富,但離線工具被認為是更好的選擇,因為它們速度快,通常還有很
    的頭像 發表于 03-02 16:56 ?3217次閱讀

    在Mac上錄制視頻的4種簡單又高效的方法

    當你使用Mac觀看教程、玩游戲、進行視頻通話等時,你可能想在Mac上進行視頻錄制。這里有不同的方法來錄制屏幕和音頻,甚至是攝像頭下的自己,在這篇文章中,我們將
    的頭像 發表于 03-02 18:06 ?6874次閱讀

    怎樣錄制視頻會議,如何用HDT101錄制視頻會議

    視頻會議已經成為各企事業單位黨政機關采用的主要會議模式,同時,視頻會議的錄制,也成為必不可缺少的環節。采用功能適用、操作簡易、價格實惠的視頻會議錄播機,已經形成趨勢。本文推薦的春源麗影
    發表于 10-05 10:10 ?1735次閱讀
    怎樣<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 ?1555次閱讀
    <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 ?538次閱讀

    OpenHarmony 3.2 Beta多媒體系列:視頻錄制

    一、簡介 媒體子系統為開發者提供了媒體相關的很多功能,本文針對其中的視頻錄制功能做個詳細的介紹。首先,我將通過媒體子系統提供的視頻錄制Tes
    的頭像 發表于 02-15 15:55 ?546次閱讀

    10分鐘快速掌握OpenHarmony社區貢獻新流程

    (以下簡稱OpenHarmony)社區優化了Issue和PR處理流程,新支持了一系列交互命令和狀態標簽,用于明確處理階段和當前處理責任人。社區CI Bot工具還提供了待辦事項提醒能力,并能自動處理超期
    的頭像 發表于 06-20 21:10 ?729次閱讀
    bet365备用器| 宣城市| 百家乐五子棋| 真人百家乐官网策略| 百家乐的玩法视频| 百家乐官网游戏如何玩| 大发888赢钱| 百家乐官网视| 汪清县| 现金网注册| 百家乐赌场策略| 天天百家乐官网的玩法技巧和规则 | 皇冠网络刷qb软件| 太阳百家乐开户| 百家乐技巧运气| 缅甸百家乐官网龙虎斗| 皇冠线上开户| 玩百家乐的好处| 百家乐全透明牌靴| 沙龙百家乐官网娱乐平台| 现金百家乐| 威尼斯人娱乐城老| 至尊百家乐贺一航| 菲律宾百家乐官网娱乐| 百家乐官网的路怎样看| 龙都棋牌下载| 汇丰百家乐的玩法技巧和规则| 百家乐实战案例| 百家乐官网赌场凯时娱乐| 万年县| 明升论坛| 大发888 894| 百家乐玩揽法大全| 华侨人百家乐官网的玩法技巧和规则| 百家乐官网天下第一和| 清新县| 太阳城娱乐城官方网| 太阳城公司| 百家乐娱乐分析软件v4.0| 百家乐翻天youtube| 百家乐官网平玩法几副牌|