Files
graphic_ui/frameworks/components/ui_video.cpp
T
2021-03-11 18:38:06 +08:00

719 lines
22 KiB
C++
Executable File

/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "components/ui_video.h"
#include "securec.h"
#ifndef VERSION_LITE
namespace OHOS {
UIVideo::UIVideo()
{
SetTouchable(true);
SetOnTouchListener(this);
}
UIVideo::~UIVideo()
{
if (videoPlayer_ != nullptr) {
videoPlayer_->Stop();
videoPlayer_->Reset();
videoPlayer_->Release();
}
if (sliderAnimator_ != nullptr) {
AnimatorManager::GetInstance()->Remove(sliderAnimator_);
delete sliderAnimator_;
sliderAnimator_ = nullptr;
}
if (surfaceView_ != nullptr) {
delete surfaceView_;
surfaceView_ = nullptr;
}
DeleteController();
}
bool UIVideo::SetSrc(const char* source)
{
if (source == nullptr) {
return false;
}
InitVideo();
src_ = source;
std::string uri(source);
std::map<std::string, std::string> header;
Source videoSource(uri, header);
if (videoPlayer_ != nullptr) {
int32_t ret = videoPlayer_->SetSource(videoSource);
if (ret == 0) {
return true;
}
}
return false;
}
bool UIVideo::Prepare()
{
if (src_ == nullptr) {
return false;
}
if (videoPlayer_ == nullptr) {
return false;
}
int32_t ret = videoPlayer_->Prepare();
if (ret != 0) {
return false;
}
SetVolume(DEFAULT_VOLUME, DEFAULT_VOLUME);
videoPlayer_->GetDuration(duration_);
if (totalTimeLabel_ != nullptr) {
char timer[10] = {0}; // 10:timer length
if (!GetTimerFromMSecond(duration_, timer, sizeof(timer))) {
return false;
}
totalTimeLabel_->SetText(&timer[0]);
}
if (titleLabel_ != nullptr) {
const char* fileName = nullptr;
fileName = strrchr(src_, '/');
if (fileName != nullptr) {
titleLabel_->SetText(fileName + 1);
}
}
if (sliderAnimatorCallback_) {
sliderAnimatorCallback_->SetDuration(duration_);
}
SetSurfaceInfo();
playerListener_ = std::make_shared<PlayerListener>();
playerListener_->SetVideoPlayer(this);
videoPlayer_->SetPlayerCallback(playerListener_);
return true;
}
bool UIVideo::Play()
{
if (videoPlayer_ != nullptr) {
int32_t ret = videoPlayer_->Play();
if (ret == 0) {
if (sliderAnimator_ != nullptr) {
sliderAnimator_->Start();
}
if (pauseButton_ != nullptr) {
pauseButton_->SetVisible(false);
}
if (playButton_ != nullptr) {
playButton_->SetState(true);
}
if (surfaceView_ != nullptr) {
surfaceView_->SetVisible(true);
}
if (videoPlayerListener_ != nullptr) {
videoPlayerListener_->OnPlaybackPlay();
}
return true;
}
}
return false;
}
bool UIVideo::IsPlaying()
{
if (videoPlayer_ != nullptr) {
return videoPlayer_->IsPlaying();
}
return false;
}
bool UIVideo::Pause()
{
if (videoPlayer_ != nullptr) {
int32_t ret = videoPlayer_->Pause();
if (ret == 0) {
if (sliderAnimator_ != nullptr) {
sliderAnimator_->Pause();
}
if (playButton_ != nullptr) {
playButton_->SetState(false);
}
if (pauseButton_ != nullptr) {
pauseButton_->SetVisible(true);
}
if (videoPlayerListener_ != nullptr) {
videoPlayerListener_->OnPlaybackPause();
}
return true;
}
}
return false;
}
bool UIVideo::Stop()
{
if (videoPlayer_ != nullptr) {
int32_t ret = videoPlayer_->Stop();
if (ret == 0) {
if (sliderAnimator_ != nullptr) {
sliderAnimator_->Stop();
}
if (playSlider_ != nullptr) {
playSlider_->SetValue(0);
}
if (currentTimeLabel_ != nullptr) {
currentTimeLabel_->SetText("00:00:00");
}
if (totalTimeLabel_ != nullptr) {
totalTimeLabel_->SetText("00:00:00");
}
if (playButton_ != nullptr) {
playButton_->SetState(false);
}
if (pauseButton_ != nullptr) {
pauseButton_->SetVisible(true);
}
if (surfaceView_ != nullptr) {
surfaceView_->SetVisible(false);
}
if (videoPlayerListener_ != nullptr) {
videoPlayerListener_->OnPlaybackStop();
}
return true;
}
}
return false;
}
bool UIVideo::Rewind(int64_t mSeconds)
{
if (videoPlayer_ != nullptr) {
int32_t ret = videoPlayer_->Rewind(mSeconds, PLAYER_SEEK_PREVIOUS_SYNC);
if (ret == 0) {
return true;
}
}
return false;
}
bool UIVideo::SetVolume(float leftVolume, float rightVolume)
{
if (videoPlayer_ != nullptr) {
int32_t ret = videoPlayer_->SetVolume(leftVolume * MAX_VOLUME, rightVolume * MAX_VOLUME);
if (ret == 0) {
leftVolumeValue_ = leftVolume;
rightVolumeValue_ = rightVolume;
if (volumeButton_ != nullptr) {
if ((leftVolumeValue_ == 0) && (rightVolumeValue_ == 0)) {
volumeButton_->SetState(true);
} else {
volumeButton_->SetState(false);
}
}
return true;
}
}
return false;
}
bool UIVideo::IsSingleLooping()
{
if (videoPlayer_ != nullptr) {
return videoPlayer_->IsSingleLooping();
}
return false;
}
bool UIVideo::GetCurrentTime(int64_t& time)
{
if (videoPlayer_ != nullptr) {
int32_t ret = videoPlayer_->GetCurrentTime(time);
if (ret == 0) {
return true;
}
}
return false;
}
bool UIVideo::GetDuration(int64_t& durationMs)
{
if (videoPlayer_ != nullptr) {
int32_t ret = videoPlayer_->GetDuration(durationMs);
if (ret == 0) {
return true;
}
}
return false;
}
void UIVideo::SetVideoPlayerListener(VideoPlayerListener* listener)
{
videoPlayerListener_ = listener;
if (playerListener_ != nullptr) {
playerListener_->SetVideoPlayerListerner(videoPlayerListener_);
}
}
bool UIVideo::Reset()
{
if (videoPlayer_ != nullptr) {
if (sliderAnimator_ != nullptr) {
sliderAnimator_->Stop();
}
if (playSlider_ != nullptr) {
playSlider_->SetValue(0);
}
if (currentTimeLabel_ != nullptr) {
currentTimeLabel_->SetText("00:00");
}
if (totalTimeLabel_ != nullptr) {
totalTimeLabel_->SetText("00:00");
}
if (pauseButton_ != nullptr) {
pauseButton_->SetVisible(true);
}
if (playButton_ != nullptr) {
playButton_->SetState(false);
}
int32_t ret = videoPlayer_->Reset();
if (ret == 0) {
videoPlayer_->Release();
return true;
}
}
return false;
}
bool UIVideo::EnableSingleLooping(bool loop)
{
if (videoPlayer_ != nullptr) {
int32_t ret = videoPlayer_->EnableSingleLooping(loop);
if (ret == 0) {
return true;
}
}
return false;
}
void UIVideo::ShowController(bool show)
{
if (controllerGroup_ != nullptr) {
if (controllerGroup_->IsVisible() != show) {
controllerGroup_->SetVisible(show);
Invalidate();
}
}
}
void UIVideo::InitVideo()
{
if (videoPlayer_ == nullptr) {
videoPlayer_ = std::make_shared<Player>();
}
InitControllerLabel();
InitControllerButton();
InitControllerSlider();
if (surfaceView_ == nullptr) {
surfaceView_ = new UISurfaceView();
if (surfaceView_ == nullptr) {
GRAPHIC_LOGE("new UISurfaceView fail");
return;
}
surfaceView_->SetPosition(0, 0);
surfaceView_->SetWidth(DEFAULT_VIEW_WIDTH);
surfaceView_->SetHeight(DEFAULT_VIEW_HEIGHT);
Add(surfaceView_);
}
if (controllerGroup_ == nullptr) {
controllerGroup_ = new UIViewGroup();
if (controllerGroup_ == nullptr) {
GRAPHIC_LOGE("new UIViewGroup fail");
return;
}
controllerGroup_->SetPosition(0, 0, DEFAULT_VIEW_WIDTH, DEFAULT_VIEW_HEIGHT);
controllerGroup_->SetStyle(STYLE_BACKGROUND_OPA, 0);
controllerGroup_->Add(titleLabel_);
controllerGroup_->Add(totalTimeLabel_);
controllerGroup_->Add(currentTimeLabel_);
controllerGroup_->Add(playSlider_);
controllerGroup_->Add(volumeButton_);
controllerGroup_->Add(playButton_);
controllerGroup_->Add(pauseButton_);
Add(controllerGroup_);
}
if (sliderAnimatorCallback_ == nullptr) {
sliderAnimatorCallback_ = new SliderAnimatorCallback(this, playSlider_, currentTimeLabel_);
if (sliderAnimatorCallback_ == nullptr) {
GRAPHIC_LOGE("new SliderAnimatorCallback fail");
return;
}
sliderAnimatorCallback_->SetPlayButton(playButton_);
}
if (sliderAnimator_ == nullptr) {
sliderAnimator_ = new Animator(sliderAnimatorCallback_, this, 0, true);
if (sliderAnimator_ == nullptr) {
GRAPHIC_LOGE("new Animator fail");
return;
}
AnimatorManager::GetInstance()->Add(sliderAnimator_);
sliderAnimatorCallback_->SetSliderAnimator(sliderAnimator_);
}
}
void UIVideo::InitControllerLabel()
{
if (titleLabel_ == nullptr) {
titleLabel_ = new UILabel();
if (titleLabel_ == nullptr) {
GRAPHIC_LOGE("new UILabel fail");
return;
}
titleLabel_->SetPosition(322, 28, 316, 29); // 322:pos x, 28:pos y, 316:width, 29:height
titleLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER,
UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER);
titleLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 20); // 20:font size
titleLabel_->SetText("title title");
titleLabel_->SetTextColor(Color::White());
}
if (totalTimeLabel_ == nullptr) {
totalTimeLabel_ = new UILabel();
if (totalTimeLabel_ == nullptr) {
GRAPHIC_LOGE("new UILabel fail");
return;
}
// 580:pos x, 56:pos y offset
totalTimeLabel_->SetPosition(580, DEFAULT_VIEW_HEIGHT - 56, TIME_LABEL_WIDTH, TIME_LABEL_HEIGHT);
totalTimeLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_RIGHT,
UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER);
totalTimeLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE);
totalTimeLabel_->SetTextColor(Color::White());
totalTimeLabel_->SetText("00:00:00");
}
if (currentTimeLabel_ == nullptr) {
currentTimeLabel_ = new UILabel();
if (currentTimeLabel_ == nullptr) {
GRAPHIC_LOGE("new UILabel fail");
return;
}
// 80:pos x, 56:pos y offset
currentTimeLabel_->SetPosition(80, DEFAULT_VIEW_HEIGHT - 56, TIME_LABEL_WIDTH, TIME_LABEL_HEIGHT);
currentTimeLabel_->SetAlign(UITextLanguageAlignment::TEXT_ALIGNMENT_LEFT,
UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER);
currentTimeLabel_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Red().full);
currentTimeLabel_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE);
currentTimeLabel_->SetText("00:00:00");
currentTimeLabel_->SetTextColor(Color::White());
}
}
void UIVideo::InitControllerButton()
{
if (playButton_ == nullptr) {
playButton_ = new UIToggleButton();
if (playButton_ == nullptr) {
GRAPHIC_LOGE("new UIToggleButton fail");
return;
}
// 24:pox x, 88:pos y offset
playButton_->SetPosition(24, DEFAULT_VIEW_HEIGHT - 88, TOGGLE_BUTTON_WIDTH, TOGGLE_BUTTON_HEIGHT);
playButton_->SetImages(MEDIA_IMAGE_PAUSE, MEDIA_IMAGE_PLAY);
playButton_->SetState(true);
playButton_->SetOnClickListener(this);
}
if (pauseButton_ == nullptr) {
pauseButton_ = new UIToggleButton();
if (pauseButton_ == nullptr) {
GRAPHIC_LOGE("new UIToggleButton fail");
return;
}
// 448:pox x, 208:pos y 2:double width 2:double height
pauseButton_->SetPosition(448, 208, 2 * TOGGLE_BUTTON_WIDTH, 2 * TOGGLE_BUTTON_HEIGHT);
pauseButton_->SetImages(MEDIA_IMAGE_PLAY_CENTER, MEDIA_IMAGE_PLAY_CENTER);
pauseButton_->SetVisible(false);
pauseButton_->SetOnClickListener(this);
}
if (volumeButton_ == nullptr) {
volumeButton_ = new UIToggleButton();
if (volumeButton_ == nullptr) {
GRAPHIC_LOGE("new UIToggleButton fail");
return;
}
// 56:pox x offset, 88:pos y offset
volumeButton_->SetPosition(DEFAULT_VIEW_WIDTH - 56, DEFAULT_VIEW_HEIGHT - 88, TOGGLE_BUTTON_WIDTH,
TOGGLE_BUTTON_HEIGHT);
volumeButton_->SetImages(MEDIA_IMAGE_MUTE, MEDIA_IMAGE_VOLUME);
volumeButton_->SetOnClickListener(this);
}
}
void UIVideo::OnVideoComplete()
{
if (videoPlayer_ != nullptr) {
videoPlayer_->Stop();
completeFlag_ = true;
if (sliderAnimator_ != nullptr) {
sliderAnimator_->Stop();
}
if (playSlider_ != nullptr) {
playSlider_->SetValue(playSlider_->GetRangeMax());
}
if (playButton_ != nullptr) {
playButton_->SetState(false);
}
if (pauseButton_ != nullptr) {
pauseButton_->SetVisible(true);
}
if (controllerGroup_ != nullptr) {
controllerGroup_->SetVisible(true);
}
Invalidate();
}
}
void UIVideo::InitControllerSlider()
{
if (playSlider_ == nullptr) {
playSlider_ = new UISlider();
if (playSlider_ == nullptr) {
GRAPHIC_LOGE("new UISlider fail");
return;
}
// 80:pos x, 74:width offset, 5:multiply, 6:divide, 4:height
playSlider_->SetPosition(80, DEFAULT_VIEW_HEIGHT - 74, DEFAULT_VIEW_WIDTH * 5 / 6, 4);
playSlider_->SetValidHeight(4); // 4:height
playSlider_->SetValidWidth(DEFAULT_VIEW_WIDTH * 5 / 6); // 5:multiply, 6:divide
playSlider_->SetRange(100, 0); // 100:range max
playSlider_->SetValue(0);
playSlider_->SetKnobWidth(KNOB_WIDTH);
playSlider_->SetSliderRadius(5, 5, KNOB_WIDTH / 2); // 5:background radius, 5:foreground radius, 2:half
playSlider_->SetKnobStyle(STYLE_BACKGROUND_COLOR, Color::White().full);
playSlider_->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, 0x1A888888); // 0x1A888888:slider background color
playSlider_->SetBackgroundStyle(STYLE_BACKGROUND_OPA, 90); // 90:background opa
playSlider_->SetDirection(UISlider::Direction::DIR_LEFT_TO_RIGHT);
playSlider_->SetSliderEventListener(this);
}
}
void UIVideo::DeleteController()
{
if (controllerGroup_ != nullptr) {
controllerGroup_->RemoveAll();
delete controllerGroup_;
controllerGroup_ = nullptr;
}
if (playButton_ != nullptr) {
delete playButton_;
playButton_ = nullptr;
}
if (pauseButton_ != nullptr) {
delete pauseButton_;
pauseButton_ = nullptr;
}
if (volumeButton_ != nullptr) {
delete volumeButton_;
volumeButton_ = nullptr;
}
if (playSlider_ != nullptr) {
delete playSlider_;
playSlider_ = nullptr;
}
if (sliderAnimatorCallback_ != nullptr) {
delete sliderAnimatorCallback_;
sliderAnimatorCallback_ = nullptr;
}
if (titleLabel_ != nullptr) {
delete titleLabel_;
titleLabel_ = nullptr;
}
if (totalTimeLabel_ != nullptr) {
delete totalTimeLabel_;
totalTimeLabel_ = nullptr;
}
if (currentTimeLabel_ != nullptr) {
delete currentTimeLabel_;
currentTimeLabel_ = nullptr;
}
}
bool UIVideo::OnClick(UIView& view, const ClickEvent& event)
{
if (videoPlayer_ == nullptr) {
return true;
}
if (&view == playButton_) {
if (completeFlag_) {
completeFlag_ = false;
if (pauseButton_ != nullptr) {
pauseButton_->SetVisible(true);
}
if (controllerGroup_ != nullptr) {
controllerGroup_->SetVisible(true);
}
return true;
}
if ((sliderAnimatorCallback_ != nullptr) && (pauseButton_ != nullptr) && (playButton_ != nullptr)) {
sliderAnimatorCallback_->ResetTickTime();
if (playButton_->GetState()) {
Play();
pauseButton_->SetVisible(false);
} else {
Pause();
pauseButton_->SetVisible(true);
}
pauseButton_->Invalidate();
}
} else if (&view == pauseButton_) {
if ((pauseButton_ != nullptr) && pauseButton_->IsVisible()) {
pauseButton_->SetVisible(false);
Play();
}
} else if (&view == volumeButton_) {
if ((volumeButton_ != nullptr) && volumeButton_->GetState()) {
videoPlayer_->SetVolume(0, 0);
} else {
SetVolume(leftVolumeValue_, rightVolumeValue_);
}
}
return true;
}
bool UIVideo::OnPress(UIView& view, const PressEvent& event)
{
if (sliderAnimatorCallback_ != nullptr) {
sliderAnimatorCallback_->ResetTickTime();
if (controllerGroup_ != nullptr) {
controllerGroup_->SetVisible(true);
}
Invalidate();
}
return true;
}
void UIVideo::OnChange(int32_t progress)
{
if (videoPlayer_ != nullptr) {
if (sliderAnimatorCallback_ != nullptr) {
sliderAnimatorCallback_->ResetTickTime();
}
int64_t currentValue = progress * duration_ / 100; // 100:percent
if (currentTimeLabel_ != nullptr) {
char timer[10] = {0}; // 10:timer length
if (!GetTimerFromMSecond(currentValue, timer, sizeof(timer))) {
return;
}
currentTimeLabel_->SetText(&timer[0]);
}
videoPlayer_->Rewind(currentValue, PLAYER_SEEK_PREVIOUS_SYNC);
}
}
void UIVideo::SetSurfaceInfo()
{
if (videoPlayer_ == nullptr) {
return;
}
int32_t width = 0;
int32_t height = 0;
videoPlayer_->GetVideoWidth(width);
videoPlayer_->GetVideoHeight(height);
if ((width <= 0) || (height <= 0)) {
videoPlayer_->Reset();
return;
}
int16_t viewWidth = GetWidth();
int16_t viewHeight = GetHeight();
if ((viewWidth <= 0) || (viewHeight <= 0)) {
videoPlayer_->Reset();
return;
}
float ratioX = static_cast<float>(width) / viewWidth;
float ratioY = static_cast<float>(height) / viewHeight;
uint16_t surfaceViewWidth;
uint16_t surfaceViewHeight;
uint16_t surfaceViewPositionX = 0;
uint16_t surfaceViewPositionY = 0;
if (ratioX > ratioY) {
surfaceViewWidth = viewWidth;
surfaceViewHeight = height / ratioX;
surfaceViewPositionY = (viewHeight - surfaceViewHeight) / 2; // 2:half
} else {
surfaceViewWidth = width / ratioY;
surfaceViewHeight = viewHeight;
surfaceViewPositionX = (viewWidth - surfaceViewWidth) / 2; // 2:half
}
if (surfaceView_ != nullptr) {
surfaceView_->SetPosition(surfaceViewPositionX, surfaceViewPositionY);
surfaceView_->SetWidth(surfaceViewWidth - 1);
surfaceView_->SetHeight(surfaceViewHeight);
videoPlayer_->SetVideoSurface(surfaceView_->GetSurface());
}
}
bool UIVideo::GetTimerFromMSecond(int64_t currentTime, char* timer, int32_t len)
{
int64_t currentSecond = currentTime / 1000; // 1000:millisecond
int32_t second = currentSecond % 60; // 60:second
int32_t minute = (currentSecond / 60) % 60; // 60:minute 60:second
int32_t hour = (currentSecond / 60) / 60; // 60:minute 60:second
int32_t ret = 0;
ret = sprintf_s(timer, len, "%02d:%02d:%02d", hour, minute, second);
if (ret < 0) {
return false;
}
return true;
}
void UIVideo::SliderAnimatorCallback::Callback(UIView* view)
{
if (video_ != nullptr) {
int64_t currentTime = 0;
video_->GetCurrentTime(currentTime);
if (timeLabel_ != nullptr) {
char timer[10] = {0}; // 10:timer length
if (!video_->GetTimerFromMSecond(currentTime, timer, sizeof(timer))) {
return;
}
timeLabel_->SetText(&timer[0]);
timeLabel_->Invalidate();
}
if (slider_ != nullptr) {
int64_t curPosition = currentTime * slider_->GetRangeMax() / duration_;
slider_->SetValue(curPosition);
slider_->Invalidate();
}
uint32_t runTime = 0;
if (sliderAnimator_ != nullptr) {
runTime = sliderAnimator_->GetRunTime();
}
if ((runTime > tickCount_) && (runTime - tickCount_ >= HIDE_MILLI_SECOND)) {
video_->ShowController(false);
tickCount_ = runTime;
}
}
}
} // namespace OHOS
#endif // VERSION_LITE