了解更多开源请访问:??????????????????????????????????????????????????,简介媒体子系统为开发者提供了一套接口,方便开发者使用系统媒体资源,主要包括音视频开发、摄像头开发、流媒体开发等模块。每个模块向上层应用提供相应的接口。本文将详细介绍音视频开发中的音视频播放框架。2.目录foundation/multimedia/media_standard├──frameworks#Frameworkcode│├──js││├──player│├──native│├──player#nativeimplementation│└──videodisplaymanager#Displaymanagement│├──include│└──src├──interfaces│├──inner_api#internalinterface││└──native│└──kits#externalJSinterface├──sa_profile#service配置文件└──services├──engine#enginecode│└──gstreamer├──etc#service配置文件├──include#headerfile└──services├──sa_media#mediaservice│├──client#mediaclient│├──ipc#mediaipc调用│└──server#mediaserver├──factory#enginefactory└──player#playerservice├──client#playerclient├──ipc#playeripccall└──server#playerserver3.播放整体流程4.原生接口使用OpenHarmony系统,音视频播放通过N-API接口提供给上层JS调用,N-API等价到JS和NativeOpenHarmony源码中,在foundation/multimedia/player_framework/test/nativedemo/player目录下提供了C++直接调用的音视频播放示例voidPlayerDemo::RunCase(conststring&path){player_=OHOS::Media::PlayerFactory::CreatePlayer();if(player_==nullptr){cout<<"player_为空"<cb=std::make_shared();cb->SetBufferingOut(SelectBufferingOut());int32_tret=player_->SetPlayerCallback(cb);if(ret!=0){cout<<"SetPlayerCallback失败"<producerSurface=nullptr;producerSurface=GetVideoSurface();if(producerSurface!=nullptr){ret=player_->SetVideoSurface(producerSurface);if(ret!=0){cout<<"SetVideoSurface失败"<PrepareAsync();if(ret!=0){cout<<"PrepareAsync失败"<second;if(func()!=0){cout<<"操作错误"<Reset();}继续;}elseif(cmd.find("quit")!=std::string::npos||cmd=="q"){break;}else{DoCmd(cmd);继续;}}}voidPlayerDemo::RegisterTable(){(void)playerTable_.emplace("prepare",std::bind(&Player::Prepare,player_));(void)playerTable_.emplace("prepareasync",std::bind(&Player::PrepareAsync,player_));(void)playerTable_.emplace("",std::bind(&Player::Play,player_));//输入->播放(void)playerTable_.emplace("play",std::bind(&Player::Play,player_));(void)playerTable_.emplace("暂停",std::bind(&Player::Pause,player_));(void)playerTable_.emplace("stop",std::bind(&Player::Stop,player_));(void)playerTable_.emplace("reset",std::bind(&Player::Reset,player_));(void)playerTable_.emplace("release",std::bind(&Player::Release,player_));(void)playerTable_.emplace("isplaying",std::bind(&PlayerDemo::GetPlaying,this));(void)playerTable_.emplace("isloop",std::bind(&PlayerDemo::GetLooping,this));(void)playerTable_.emplace("speed",std::bind(&PlayerDemo::GetPlaybackSpeed,this));}上面DoNext方法中的核心代码是func()的调用。这个func就是之前在Map中注册的字符串对应的方法。在RegisterTable方法中,空字符串""和"play"绑定到Player::Play方法。,默认不输入command参数时为回放操作。5、调用流程本段主要分析媒体播放的框架层代码,因此流程中涉及到IPC调用相关的客户端和服务端。代码暂时分析为调用gstreamer引擎。首先,Sample通过PlayerFactory创建播放器实例(PlayerImpl对象),并在创建过程中调用Init函数。int32_tPlayerImpl::Init(){playerService_=MediaServiceFactory::GetInstance().CreatePlayerService();CHECK_AND_RETURN_RET_LOG(playerService_!=nullptr,MSERR_UNKNOWN,"创建玩家服务失败");returnMSERR_OK;}MediaServiceFactory::GetInstance()返回的是MediaClient对象,所以CreateplayerService函数实际上调用的是MediaClient对应的方法。std::shared_ptrMediaClient::CreatePlayerService(){std::lock_guardlock(mutex_);if(!IsAlived()){MEDIA_LOGE("媒体服务不存在。");返回空指针;}sptrobject=mediaProxy_->GetSubSystemAbility(IStandardMediaService::MediaSystemAbility::MEDIA_PLAYER,listenerStub_->AsObject());CHECK_AND_RETURN_RET_LOG(object!=nullptr,nullptr,"playerproxyobjectisnullptr.");sptrplayerProxy=iface_cast(object);CHECK_AND_RETURN_RET_LOG(playerProxy!=nullptr,nullptr,"playerproxyisnullptr.");std::shared_ptrplayer=PlayerClient::Create(playerProxy);CHECK_AND_RETURN_RET_LOG(player!=nullptr,nullptr,"创建玩家客户端失败。");playerClientList_.push_back(玩家);returnplayer;}这个方法中主要通过PlayerClient::Create(playerProxy)方法创建创建一个PlayerClient实例,并逐层上传实例,最后传递给PlayerImpl的playerService_变量。后续对播放器的操作,通过调用PlayerClient实例实现PlayerImpl。int32_tPlayerImpl::Play(){CHECK_AND_RETURN_RET_LOG(playerService_!=nullptr,MSERR_INVALID_OPERATION,"播放器服务不存在..");MEDIA_LOGW("KPI-TRACE:PlayerImpl播放");returnplayerService_->Play();}int32_tPlayerImpl::Prepare(){CHECK_AND_RETURN_RET_LOG(playerService_!=nullptr,MSERR_INVALID_OPERATION,"玩家服务不存在..");MEDIA_LOGW("KPI-TRACE:PlayerImpl准备");returnplayerService_->Prepare();}int32_tPlayerImpl::PrepareAsync(){CHECK_AND_RETURN_RETplayerService_!=nullptr,MSERR_INVALID_OPERATION,"播放器服务不存在..");MEDIA_LOGW("KPI-TRACE:PlayerImplPrepareAsyncin");returnplayerService_->PrepareAsync();}对于PlayerImpl,playerService指向的PlayerClient是具体的实现。PlayerClient的实现是通过IPC的远程调用来实现的。具体的,IPC中的代理端向远程服务发起远程调用请求。我们以播放Play为例:int32_tPlayerClient::Play(){std::lock_guardlock(mutex_);CHECK_AND_RETURN_RET_LOG(playerProxy_!=nullptr,MSERR_NO_MEMORY,"玩家服务不存在..");返回playerProxy_->Play();}int32_tPlayerServiceProxy::Play(){MessageParcel数据;MessageParcel回复;MessageOption选项;if(!data.WriteInterfaceToken(PlayerServiceProxy::GetDescriptor())){MEDIA_LOGE("无法写入描述符");返回MSERR_UNKNOWN;}interror=Remote()->SendRequest(PLAY,data,reply,option);if(error!=MSERR_OK){MEDIA_LOGE("播放失败,错误:%{public}d",error);返回错误;}returnreply.ReadInt32();}proxy端发送调用请求后,相应的Stub端会在PlayerServiceStub::OnRemoteRequest中收到请求,根据请求的参数执行相应的函数调用。播放操作对应调用Stub的Play方法。int32_tPlayerServiceStub::Play(){MediaTraceTrace("binder::Play");CHECK_AND_RETURN_RET_LOG(playerServer_!=nullptr,MSERR_NO_MEMORY,"playerserverisnullptr");返回playerServer_->Play();_调用播放函数。playerServer_是在初始化Stub时通过PlayerServer::Create()获得的。那就是播放器服务器。std::shared_ptrPlayerServer::Create(){std::shared_ptrserver=std::make_shared();CHECK_AND_RETURN_RET_LOG(server!=nullptr,nullptr,"无法连接到新的PlayerServer");(void)server->Init();returnserver;}最后我们的Play调用了PlayerServer的Play()。媒体播放的整个过程涉及到很多状态,所以在Play中经过一些状态解释后调用OnPlay方法。该方法发起播放任务。int32_tPlayerServer::Play(){std::lock_guardlock(mutex_);如果(lastOpStatus_==PLAYER_PREPARED||lastOpStatus_==PLAYER_PLAYBACK_COMPLETE||lastOpStatus_==PLAYER_PAUSED){returnOnPlay();}else{MEDIA_LOGE("无法播放,当前状态为%{public}s",GetStatusDescription(lastOpStatus_).c_str());返回MSERR_INVALID_OPERATION;}}int32_tPlayerServer::OnPlay(){autoplayingTask=std::make_shared>([this](){MediaTrace::TraceBegin("PlayerServer::Play",FAKE_POINTER(this));autocurrState=std::static_pointer_cast(GetCurrState());(void)currState->Play();});intret=taskMgr_.LaunchTask(playingTask,PlayerServerTaskType::STATE_CHANGE);CHECK_AND_RETURN_RET_LOG(ret==MSERR_OK,ret,"播放失败");lastOpStatus_=PLAYER_STARTED;returnMSERR_OK;}在播放任务中调用了PlayerServer::PreparedState::Play()int32_tPlayerServer::PreparedState::Play(){returnserver_.HandlePlay();}在Play中直接调用PlayerServer的HandlePlay方法,HandlePlay方法通过playerEngine_调用到gstreamer引擎,gstreamer为最终播放实现int32_tPlayerServer::HandlePlay(){int32_tret=playerEngine_->Play();CHECK_AND_RETURN_RET_LOG(ret==MSERR_OK,MSERR_INVALID_OPERATION,"引擎播放失败!");returnMSERR_OK;}介绍中先梳理了整体的播放流程,然后详细分析了播放的主要步骤。媒体播放主要分为以下几个层次:(1)提供给应用程序调用的Native接口,实际上是通过OHOS::Media::PlayerFactory::CreatePlayer()的调用返回PlayerImpl实例。(2)PlayerClient,这部分通过IPC代理调用向远程服务发起调用请求。(3)PlayerServer,这部分是播放服务的实现端,提供给客户端调用。(4)Gstreamer,这部分提供给PlayerServer调用,真正实现媒体播放的功能。了解更多开源知识,请访问:开源基础软件社区https://ost.51cto.com。