2
0

VideoWidget.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. * TextControls.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "VideoWidget.h"
  12. #include "TextControls.h"
  13. #include "../CGameInfo.h"
  14. #include "../gui/CGuiHandler.h"
  15. #include "../media/ISoundPlayer.h"
  16. #include "../media/IVideoPlayer.h"
  17. #include "../render/Canvas.h"
  18. #include "../../lib/filesystem/Filesystem.h"
  19. VideoWidgetBase::VideoWidgetBase(const Point & position, const VideoPath & video, bool playAudio)
  20. : VideoWidgetBase(position, video, playAudio, 1.0)
  21. {
  22. }
  23. VideoWidgetBase::VideoWidgetBase(const Point & position, const VideoPath & video, bool playAudio, float scaleFactor)
  24. : playAudio(playAudio), scaleFactor(scaleFactor)
  25. {
  26. addUsedEvents(TIME);
  27. pos += position;
  28. playVideo(video);
  29. }
  30. VideoWidgetBase::~VideoWidgetBase() = default;
  31. void VideoWidgetBase::playVideo(const VideoPath & fileToPlay)
  32. {
  33. OBJECT_CONSTRUCTION;
  34. JsonPath subTitlePath = fileToPlay.toType<EResType::JSON>();
  35. JsonPath subTitlePathVideoDir = subTitlePath.addPrefix("VIDEO/");
  36. if(CResourceHandler::get()->existsResource(subTitlePath))
  37. subTitleData = JsonNode(subTitlePath);
  38. else if(CResourceHandler::get()->existsResource(subTitlePathVideoDir))
  39. subTitleData = JsonNode(subTitlePathVideoDir);
  40. videoInstance = CCS->videoh->open(fileToPlay, scaleFactor);
  41. if (videoInstance)
  42. {
  43. pos.w = videoInstance->size().x;
  44. pos.h = videoInstance->size().y;
  45. if(!subTitleData.isNull())
  46. subTitle = std::make_unique<CMultiLineLabel>(Rect(0, (pos.h / 5) * 4, pos.w, pos.h / 5), EFonts::FONT_HIGH_SCORE, ETextAlignment::CENTER, Colors::WHITE);
  47. }
  48. if (playAudio)
  49. {
  50. loadAudio(fileToPlay);
  51. if (isActive())
  52. startAudio();
  53. }
  54. }
  55. void VideoWidgetBase::show(Canvas & to)
  56. {
  57. if(videoInstance)
  58. videoInstance->show(pos.topLeft(), to);
  59. if(subTitle)
  60. subTitle->showAll(to);
  61. }
  62. void VideoWidgetBase::loadAudio(const VideoPath & fileToPlay)
  63. {
  64. if (!playAudio)
  65. return;
  66. audioData = CCS->videoh->getAudio(fileToPlay);
  67. }
  68. void VideoWidgetBase::startAudio()
  69. {
  70. if(audioData.first == nullptr)
  71. return;
  72. audioHandle = CCS->soundh->playSound(audioData);
  73. if(audioHandle != -1)
  74. {
  75. CCS->soundh->setCallback(
  76. audioHandle,
  77. [this]()
  78. {
  79. this->audioHandle = -1;
  80. }
  81. );
  82. }
  83. }
  84. void VideoWidgetBase::stopAudio()
  85. {
  86. if(audioHandle != -1)
  87. {
  88. CCS->soundh->resetCallback(audioHandle);
  89. CCS->soundh->stopSound(audioHandle);
  90. audioHandle = -1;
  91. }
  92. }
  93. std::string VideoWidgetBase::getSubTitleLine(double timestamp)
  94. {
  95. if(subTitleData.isNull())
  96. return {};
  97. for(auto & segment : subTitleData.Vector())
  98. if(timestamp > segment["timeStart"].Float() && timestamp < segment["timeEnd"].Float())
  99. return segment["text"].String();
  100. return {};
  101. }
  102. void VideoWidgetBase::activate()
  103. {
  104. CIntObject::activate();
  105. if(audioHandle != -1)
  106. CCS->soundh->resumeSound(audioHandle);
  107. else
  108. startAudio();
  109. if(videoInstance)
  110. videoInstance->activate();
  111. }
  112. void VideoWidgetBase::deactivate()
  113. {
  114. CIntObject::deactivate();
  115. CCS->soundh->pauseSound(audioHandle);
  116. if(videoInstance)
  117. videoInstance->deactivate();
  118. }
  119. void VideoWidgetBase::showAll(Canvas & to)
  120. {
  121. if(videoInstance)
  122. videoInstance->show(pos.topLeft(), to);
  123. if(subTitle)
  124. subTitle->showAll(to);
  125. }
  126. void VideoWidgetBase::tick(uint32_t msPassed)
  127. {
  128. if(videoInstance)
  129. {
  130. videoInstance->tick(msPassed);
  131. if(videoInstance->videoEnded())
  132. {
  133. videoInstance.reset();
  134. stopAudio();
  135. onPlaybackFinished();
  136. }
  137. }
  138. if(subTitle && videoInstance)
  139. subTitle->setText(getSubTitleLine(videoInstance->timeStamp()));
  140. }
  141. VideoWidget::VideoWidget(const Point & position, const VideoPath & prologue, const VideoPath & looped, bool playAudio)
  142. : VideoWidgetBase(position, prologue, playAudio)
  143. , loopedVideo(looped)
  144. {
  145. }
  146. VideoWidget::VideoWidget(const Point & position, const VideoPath & looped, bool playAudio)
  147. : VideoWidgetBase(position, looped, playAudio)
  148. , loopedVideo(looped)
  149. {
  150. }
  151. void VideoWidget::onPlaybackFinished()
  152. {
  153. playVideo(loopedVideo);
  154. }
  155. VideoWidgetOnce::VideoWidgetOnce(const Point & position, const VideoPath & video, bool playAudio, const std::function<void()> & callback)
  156. : VideoWidgetBase(position, video, playAudio)
  157. , callback(callback)
  158. {
  159. }
  160. VideoWidgetOnce::VideoWidgetOnce(const Point & position, const VideoPath & video, bool playAudio, float scaleFactor, const std::function<void()> & callback)
  161. : VideoWidgetBase(position, video, playAudio, scaleFactor)
  162. , callback(callback)
  163. {
  164. }
  165. void VideoWidgetOnce::onPlaybackFinished()
  166. {
  167. callback();
  168. }