點擊藍字 ╳ 關注我們
巴延興
深圳開鴻數字產業發展有限公司
資深OS框架開發工程師
一、簡介
二、目錄
├── frameworks #框架代碼
│ ├── js
│ │ ├── player
│ ├── native
│ │ ├── player #native實現
│ └── videodisplaymanager #顯示管理
│ ├── include
│ └── src
├── interfaces
│ ├── inner_api #內部接口
│ │ └── native
│ └── kits #外部JS接口
├── sa_profile #服務配置文件
└── services
├── engine #engine代碼
│ └── gstreamer
├── etc #服務配置文件
├── include #頭文件
└── services
├── sa_media #media服務
│ ├── client #media客戶端
│ ├── ipc #media ipc調用
│ └── server #media服務端
├── factory #engine工廠
└── player #player服務
├── client #player客戶端
├── ipc #player ipc調用
└──server#player服務端
三、播放的總體流程
四、Native接口使用
void PlayerDemo::RunCase(const string &path)
{
player_ = OHOS::CreatePlayer();
if (player_ == nullptr) {
cout << "player_ is null" << endl;
return;
}
RegisterTable();
std::shared_ptr cb = std::make_shared();
cb->SetBufferingOut(SelectBufferingOut());
int32_t ret = player_->SetPlayerCallback(cb);
if (ret != 0) {
cout << "SetPlayerCallback fail" << endl;
}
if (SelectSource(path) != 0) {
cout << "SetSource fail" << endl;
return;
}
sptr producerSurface = nullptr;
producerSurface = GetVideoSurface();
if (producerSurface != nullptr) {
ret = player_->SetVideoSurface(producerSurface);
if (ret != 0) {
cout << "SetVideoSurface fail" << endl;
}
}
SetVideoScaleType();
if (SelectRendererMode() != 0) {
cout << "set renderer info fail" << endl;
}
ret = player_->PrepareAsync();
if (ret != 0) {
cout << "PrepareAsync fail" << endl;
return;
}
cout << "Enter your step:" << endl;
DoNext();
}
void PlayerDemo::DoNext()
{
std::string cmd;
while (std::cin, cmd)) {
auto iter = playerTable_.find(cmd);
if (iter != playerTable_.end()) {
auto func = iter->second;
if (func() != 0) {
cout << "Operation error" << endl;
}
if (cmd.find("stop") != std::npos && dataSrc_ != nullptr) {
dataSrc_->Reset();
}
continue;
} else if (cmd.find("quit") != std::npos || cmd == "q") {
break;
} else {
DoCmd(cmd);
continue;
}
}
}
void PlayerDemo::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_)); // ENTER -> play
(void)playerTable_.emplace("play", std::bind(&Player::Play, player_));
(void)playerTable_.emplace("pause", 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));
}
五、調用流程
左右滑動查看更多
int32_t PlayerImpl::Init()
{
playerService_ = MediaServiceFactory::GetInstance().CreatePlayerService();
CHECK_AND_RETURN_RET_LOG(playerService_ != nullptr, MSERR_UNKNOWN, "failed to create player service");
return MSERR_OK;
}
std::shared_ptr MediaClient::CreatePlayerService()
{
std::lock_guard lock(mutex_);
if (!IsAlived()) {
MEDIA_LOGE("media service does not exist.");
return nullptr;
}
sptr object = mediaProxy_->GetSubSystemAbility(
IStandardMediaService::MEDIA_PLAYER, listenerStub_->AsObject());
CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "player proxy object is nullptr.");
sptr playerProxy = iface_cast(object);
CHECK_AND_RETURN_RET_LOG(playerProxy != nullptr, nullptr, "player proxy is nullptr.");
std::shared_ptr player = PlayerClient::Create(playerProxy);
CHECK_AND_RETURN_RET_LOG(player != nullptr, nullptr, "failed to create player client.");
playerClientList_.push_back(player);
return player;
}
int32_t PlayerImpl::Play()
{
CHECK_AND_RETURN_RET_LOG(playerService_ != nullptr, MSERR_INVALID_OPERATION, "player service does not exist..");
MEDIA_LOGW("KPI-TRACE: PlayerImpl Play in");
return playerService_->Play();
}
int32_t PlayerImpl::Prepare()
{
CHECK_AND_RETURN_RET_LOG(playerService_ != nullptr, MSERR_INVALID_OPERATION, "player service does not exist..");
MEDIA_LOGW("KPI-TRACE: PlayerImpl Prepare in");
return playerService_->Prepare();
}
int32_t PlayerImpl::PrepareAsync()
{
CHECK_AND_RETURN_RET_LOG(playerService_ != nullptr, MSERR_INVALID_OPERATION, "player service does not exist..");
MEDIA_LOGW("KPI-TRACE: PlayerImpl PrepareAsync in");
return playerService_->PrepareAsync();
}
int32_t PlayerClient::Play()
{
std::lock_guard lock(mutex_);
CHECK_AND_RETURN_RET_LOG(playerProxy_ != nullptr, MSERR_NO_MEMORY, "player service does not exist..");
return playerProxy_->Play();
}
int32_t PlayerServiceProxy::Play()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(PlayerServiceProxy::GetDescriptor())) {
MEDIA_LOGE("Failed to write descriptor");
return MSERR_UNKNOWN;
}
int error = Remote()->SendRequest(PLAY, data, reply, option);
if (error != MSERR_OK) {
MEDIA_LOGE("Play failed, error: %{public}d", error);
return error;
}
return reply.ReadInt32();
}
int32_t PlayerServiceStub::Play()
{
MediaTrace Trace("binder::Play");
CHECK_AND_RETURN_RET_LOG(playerServer_ != nullptr, MSERR_NO_MEMORY, "player server is nullptr");
return playerServer_->Play();
}
std::shared_ptr PlayerServer::Create()
{
std::shared_ptr server = std::make_shared();
CHECK_AND_RETURN_RET_LOG(server != nullptr, nullptr, "failed to new PlayerServer");
(void)server->Init();
return server;
}
int32_t PlayerServer::Play()
{
std::lock_guard lock(mutex_);
if (lastOpStatus_ == PLAYER_PREPARED || lastOpStatus_ == PLAYER_PLAYBACK_COMPLETE ||
lastOpStatus_ == PLAYER_PAUSED) {
return OnPlay();
} else {
MEDIA_LOGE("Can not Play, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
return MSERR_INVALID_OPERATION;
}
}
int32_t PlayerServer::OnPlay()
{
auto playingTask = std::make_shared>([this]() {
MediaTrace::TraceBegin("PlayerServer::Play", FAKE_POINTER(this));
auto currState = std::static_pointer_cast (GetCurrState());
(void)currState->Play();
});
int ret = taskMgr_.LaunchTask(playingTask, PlayerServerTaskType::STATE_CHANGE);
CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "Play failed");
lastOpStatus_ = PLAYER_STARTED;
return MSERR_OK;
}
int32_t PlayerServer::Play()
{
return server_.HandlePlay();
}
int32_t PlayerServer::HandlePlay()
{
int32_t ret = playerEngine_->Play();
CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine Play Failed!");
return MSERR_OK;
}
六、總結
(1)提供給應用調用的Native接口,這個實際上通過OHOS::CreatePlayer()調用返回PlayerImpl實例。
(2)PlayerClient,這部分通過IPC的proxy調用,向遠程服務發起調用請求。
(3)PlayerServer,這部分是播放服務的實現端,提供給Client端調用。
(4)Gstreamer,這部分是提供給PlayerServer調用,真正實現媒體播放的功能。
原文標題:OpenHarmony 3.2 Beta多媒體系列——音視頻播放框架
文章出處:【微信公眾號:OpenAtom OpenHarmony】歡迎添加關注!文章轉載請注明出處。
-
鴻蒙
+關注
關注
57文章
2313瀏覽量
42748 -
OpenHarmony
+關注
關注
25文章
3661瀏覽量
16159
原文標題:OpenHarmony 3.2 Beta多媒體系列——音視頻播放框架
文章出處:【微信號:gh_e4f28cfa3159,微信公眾號:OpenAtom OpenHarmony】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論