0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

OpenHarmony視頻錄制流程介紹

OpenHarmony技術(shù)社區(qū) ? 來源:OST開源開發(fā)者 ? 2023-02-20 10:39 ? 次閱讀

媒體子系統(tǒng)為開發(fā)者提供了媒體相關(guān)的很多功能,本文針對其中的視頻錄制功能做個詳細(xì)的介紹。

首先,我將通過媒體子系統(tǒng)提供的視頻錄制 Test 代碼作為切入點,給大家梳理一下整個錄制的流程。

目錄

foundation/multimedia/camera_framework
├──frameworks
│├──js
││└──camera_napi#napi實現(xiàn)
││└──src
││├──input#Camera輸入
││├──output#Camera輸出
││└──session#會話管理
│└──native#native實現(xiàn)
│└──camera
│├──BUILD.gn
│├──src
││├──input#Camera輸入
││├──output#Camera輸出
││└──session#會話管理
├──interfaces#接口定義
│├──inner_api#內(nèi)部native實現(xiàn)
││└──native
││├──camera
│││└──include
│││├──input
│││├──output
│││└──session
│└──kits#napi接口
│└──js
│└──camera_napi
│├──BUILD.gn
│├──include
││├──input
││├──output
││└──session
│└──@ohos.multimedia.camera.d.ts
└──services#服務(wù)端
└──camera_service
├──binder
│├──base
│├──client#IPC的客戶端
││└──src
│└──server#IPC的服務(wù)端
│└──src
└──src

錄制的總體流程

如下圖:

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

Native接口使用

OpenHarmony 系統(tǒng)中,多媒體子系統(tǒng)通過 N-API 接口提供給上層 JS 調(diào)用,N-API 相當(dāng)于是 JS 和 Native 之間的橋梁。 在 OpenHarmony 源碼中,提供了 C++ 直接調(diào)用視頻錄制功能的例子,foundation/multimedia/camera_framework/interfaces/inner_api/native/test 目錄中。

本文章主要參考了 camera_video.cpp 文件中的視頻錄制流程。

首先根據(jù) camera_video.cpp 的 main 方法,了解下視頻錄制的主要流程代碼:

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

//創(chuàng)建CameraManager實例
sptrcamManagerObj=CameraManager::GetInstance();

//設(shè)置回調(diào)
camManagerObj->SetCallback(std::make_shared(testName));

//獲取支持的相機設(shè)備列表
std::vector>cameraObjList=camManagerObj->GetSupportedCameras();

//創(chuàng)建采集會話
sptrcaptureSession=camManagerObj->CreateCaptureSession();

//開始配置采集會話
captureSession->BeginConfig();

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

//開啟CameraInput
cameraInput->Open();

//設(shè)置CameraInput的Error回調(diào)
cameraInput->SetErrorCallback(std::make_shared(testName));

//添加CameraInput實例到采集會話中
ret=captureSession->AddInput(cameraInput);

sptrvideoSurface=nullptr;
std::shared_ptrrecorder=nullptr;

//創(chuàng)建Video的Surface
videoSurface=Surface::CreateSurfaceAsConsumer();

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

//注冊Surface的事件監(jiān)聽
videoSurface->RegisterConsumerListener((sptr&)videoListener);

//視頻的配置
VideoProfilevideoprofile=VideoProfile(static_cast(videoFormat),videosize,videoframerates);

//創(chuàng)建VideoOutput實例
sptrvideoOutput=camManagerObj->CreateVideoOutput(videoprofile,videoSurface);

//設(shè)置VideoOutput的回調(diào)
((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 模塊支持的能力來實現(xiàn),其中涉及幾個重要的類:CaptureSession、CameraInput、VideoOutput。

CaptureSession 是整個過程的控制者,CameraInput 和 VideoOutput 相當(dāng)于是設(shè)備的輸入和輸出。

調(diào)用流程

如下圖:

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

后續(xù)主要針對上面的調(diào)用流程,梳理具體的調(diào)用流程,方便我們對了解視頻錄制的整理架構(gòu)有一個更加深入的了解。

①創(chuàng)建 CameraManager 實例

通過 CameraManager::GetInstance() 獲取 CameraManager 的實例,后續(xù)的一些接口都是通過該實例進行調(diào)用的。

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_;
}

②獲取支持的相機設(shè)備列表

通過調(diào)用 CameraManager 的 GetSupportedCameras() 接口,獲取設(shè)備支持的 CameraDevice 列表。

跟蹤代碼可以發(fā)現(xiàn) serviceProxy_->GetCameras 最終會調(diào)用到 Camera 服務(wù)端的對應(yīng)接口。

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;
}
③創(chuàng)建采集會話

下面是比較重要的環(huán)節(jié),通過調(diào)用 CameraManager 的 CreateCaptureSession 接口創(chuàng)建采集會話。 CameraManager 創(chuàng)建采集會話,是通過 serviceProxy_->CreateCaptureSession 方式進行調(diào)用。

這里涉及到了 OpenHarmony 中的 IPC 的調(diào)用,serviceProxy_ 是遠(yuǎn)端服務(wù)在本地的代理,通過這個代理可以調(diào)用到具體的服務(wù)端,這里是 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 對象,并且將該對象傳遞給了參數(shù) session。

所以前面的 captureSession 對象就是這里 new 出來的 HCaptureSession,前面的 CameraManager 的 CreateCaptureSession() 方法中將 captureSession 封裝成 CaptureSession 對象返回給應(yīng)用層使用。

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;
}

④開始配置采集會話

調(diào)用 CaptureSession 的 BeginConfig 進行采集會話的配置工作。這個工作最終調(diào)用到被封裝的 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;
}

⑤創(chuàng)建 CameraInput

應(yīng)用層通過 camManagerObj->CreateCameraInput(cameraObjList[0]) 的方式進行 CameraInput 的創(chuàng)建,cameraObjList[0] 就是前面獲取支持設(shè)備的第一個。根據(jù) CameraDevice 創(chuàng)建對應(yīng)的 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

調(diào)用了 CameraInput 的 Open 方法,進行輸入設(shè)備的啟動打開。

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

⑦添加 CameraInput 實例到采集會話中

通過調(diào)用 captureSession 的 AddInput 方法,將創(chuàng)建的 CameraInput 對象添加到采集會話的輸入中,這樣采集會話就知道采集輸入的設(shè)備。

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());
}

最終調(diào)用到 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;
}
⑧創(chuàng)建 Video 的 Surface

通過 Surface::CreateSurfaceAsConsumer 創(chuàng)建 Surface。

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

通過調(diào)用 CameraManager 的 CreateVideoOutput 來創(chuàng)建 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 的調(diào)用最終調(diào)用到了 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 方法中主要創(chuàng)建了 HStreamRepeat,并且通過參數(shù)傳遞給前面的 CameraManager 使用,CameraManager 通過傳遞的 HStreamRepeat 對象,進行封裝,創(chuàng)建出 VideoOutput 對象。

⑩添加 videoOutput 到采集會話中,并且提交采集會話 該步驟類似添加 CameraInput 到采集會話的過程,可以參考前面的流程。 ?開始錄制

通過調(diào)用 VideoOutput 的 Start 進行錄制的操作。

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

該方法中會調(diào)用到 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,其中最后一個參數(shù) true,表示采集連續(xù)數(shù)據(jù)。 ?錄制結(jié)束,保存錄制文件

總結(jié)

本文主要對 OpenHarmony 3.2 Beta 多媒體子系統(tǒng)的視頻錄制進行介紹,首先梳理了整體的錄制流程,然后對錄制過程中的主要步驟進行了詳細(xì)地分析。

視頻錄制主要分為以下幾個步驟:

獲取 CameraManager 實例。

創(chuàng)建采集會話 CaptureSession。

創(chuàng)建 CameraInput 實例,并且將輸入設(shè)備添加到 CaptureSession 中。

創(chuàng)建 Video 錄制需要的 Surface。

創(chuàng)建 VideoOutput 實例,并且將輸出添加到 CaptureSession 中。

提交采集會話的配置。

調(diào)用 VideoOutput 的 Start 方法,進行視頻的錄制。

錄制結(jié)束,保存錄制的文件。

作者:巴延興

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 接口
    +關(guān)注

    關(guān)注

    33

    文章

    8605

    瀏覽量

    151197
  • 視頻
    +關(guān)注

    關(guān)注

    6

    文章

    1946

    瀏覽量

    72919
  • 媒體
    +關(guān)注

    關(guān)注

    1

    文章

    64

    瀏覽量

    14427
  • C++
    C++
    +關(guān)注

    關(guān)注

    22

    文章

    2108

    瀏覽量

    73657
  • OpenHarmony
    +關(guān)注

    關(guān)注

    25

    文章

    3722

    瀏覽量

    16323

原文標(biāo)題:OpenHarmony視頻錄制流程

文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術(shù)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    游戲錄制軟件玩***寶2.0發(fā)布,高清特效打造完美游戲視頻

    成了重中之重,今天給大家介紹一款專門針對游戲玩家而言的一款錄制視頻軟件——玩***寶。玩***寶:下載地址官網(wǎng)下載地址:http://www.weplay.cn/download/baobao.html
    發(fā)表于 09-25 16:53

    CC3200MOD 錄制視頻問題

    請問,是否可以把rtp接收到的視頻流和音頻數(shù)據(jù),解碼并保存到SFLASH上,成為完整的視頻文件(格式avi/MP4等)?錄制視頻大概5秒左右,大小1.4m左右。
    發(fā)表于 06-23 00:48

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

    一、簡介媒體子系統(tǒng)為開發(fā)者提供了媒體相關(guān)的很多功能,本文針對其中的視頻錄制功能做個詳細(xì)的介紹。首先,我將通過媒體子系統(tǒng)提供的視頻錄制Test
    發(fā)表于 02-09 15:47

    MP4視頻錄制格式主要有哪些

    MP4視頻錄制格式主要有哪些  視頻錄制格式是指MP4通過AV接口與電視相連錄制電視節(jié)目
    發(fā)表于 12-21 15:57 ?2367次閱讀

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

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

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

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

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

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

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

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

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

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

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

    視頻會議已經(jīng)成為各企事業(yè)單位黨政機關(guān)采用的主要會議模式,同時,視頻會議的錄制,也成為必不可缺少的環(huán)節(jié)。采用功能適用、操作簡易、價格實惠的視頻會議錄播機,已經(jīng)形成趨勢。本文推薦的春源麗影
    發(fā)表于 10-05 10:10 ?1693次閱讀
    怎樣<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硬件創(chuàng)新

    OpenHarmony Dev-Board-SIG專場:華秋視頻營銷矩陣—硬聲短視頻APP助力OpenHarmony硬件創(chuàng)新
    的頭像 發(fā)表于 12-28 15:21 ?1527次閱讀
    <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>硬件創(chuàng)新

    迷你視頻錄制和流媒體機器人開源分享

    電子發(fā)燒友網(wǎng)站提供《迷你視頻錄制和流媒體機器人開源分享.zip》資料免費下載
    發(fā)表于 11-10 11:38 ?3次下載
    迷你<b class='flag-5'>視頻</b><b class='flag-5'>錄制</b>和流媒體機器人開源分享

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

    巴延興 深圳開鴻數(shù)字產(chǎn)業(yè)發(fā)展有限公司 資深OS框架開發(fā)工程師 一、簡介 媒體子系 統(tǒng)為開發(fā)者提供了媒體相關(guān)的很多功能,本文針對其中的視頻錄制功能做個詳細(xì)的介紹。 首先,我將通過媒體子系統(tǒng)提供的
    的頭像 發(fā)表于 02-10 11:20 ?512次閱讀

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

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

    10分鐘快速掌握OpenHarmony社區(qū)貢獻(xiàn)新流程

    (以下簡稱OpenHarmony)社區(qū)優(yōu)化了Issue和PR處理流程,新支持了一系列交互命令和狀態(tài)標(biāo)簽,用于明確處理階段和當(dāng)前處理責(zé)任人。社區(qū)CI Bot工具還提供了待辦事項提醒能力,并能自動處理超期
    的頭像 發(fā)表于 06-20 21:10 ?683次閱讀