Przeglądaj źródła

working subtitles

Laserlicht 1 rok temu
rodzic
commit
54542c54b3

+ 46 - 2
client/widgets/VideoWidget.cpp

@@ -17,6 +17,8 @@
 #include "../media/IVideoPlayer.h"
 #include "../render/Canvas.h"
 
+#include "../../lib/filesystem/Filesystem.h"
+
 VideoWidgetBase::VideoWidgetBase(const Point & position, const VideoPath & video, bool playAudio)
 	: VideoWidgetBase(position, video, playAudio, 1.0)
 {
@@ -36,6 +38,20 @@ void VideoWidgetBase::playVideo(const VideoPath & fileToPlay)
 {
 	OBJECT_CONSTRUCTION;
 
+	using SubTitlePath = ResourcePathTempl<EResType::SUBTITLE>;
+	SubTitlePath subTitlePath = fileToPlay.toType<EResType::SUBTITLE>();
+	SubTitlePath subTitlePathVideoDir = subTitlePath.addPrefix("VIDEO/");
+	if(CResourceHandler::get()->existsResource(subTitlePath))
+	{
+		auto rawData = CResourceHandler::get()->load(subTitlePath)->readAll();
+		srtContent = std::string(reinterpret_cast<char *>(rawData.first.get()), rawData.second);
+	}
+	if(CResourceHandler::get()->existsResource(subTitlePathVideoDir))
+	{
+		auto rawData = CResourceHandler::get()->load(subTitlePathVideoDir)->readAll();
+		srtContent = std::string(reinterpret_cast<char *>(rawData.first.get()), rawData.second);
+	}
+
 	videoInstance = CCS->videoh->open(fileToPlay, scaleFactor);
 	if (videoInstance)
 	{
@@ -83,7 +99,7 @@ void VideoWidgetBase::startAudio()
 			{
 				this->audioHandle = -1;
 			}
-			);
+		);
 	}
 }
 
@@ -97,6 +113,34 @@ void VideoWidgetBase::stopAudio()
 	}
 }
 
+std::string VideoWidgetBase::getSubTitleLine(double timestamp)
+{
+	if(srtContent.empty())
+		return "";
+	
+    std::regex exp("^\\s*(\\d+:\\d+:\\d+,\\d+)[^\\S\\n]+-->[^\\S\\n]+(\\d+:\\d+:\\d+,\\d+)((?:\\n(?!\\d+:\\d+:\\d+,\\d+\\b|\\n+\\d+$).*)*)", std::regex::multiline);
+    std::smatch res;
+
+    std::string::const_iterator searchStart(srtContent.cbegin());
+    while (std::regex_search(searchStart, srtContent.cend(), res, exp))
+    {
+		std::vector<std::string> timestamp1Str;
+		boost::split(timestamp1Str, static_cast<std::string>(res[1]), boost::is_any_of(":,"));
+		std::vector<std::string> timestamp2Str;
+		boost::split(timestamp2Str, static_cast<std::string>(res[2]), boost::is_any_of(":,"));
+		double timestamp1 = std::stoi(timestamp1Str[0]) * 3600 + std::stoi(timestamp1Str[1]) * 60 + std::stoi(timestamp1Str[2]) + (std::stoi(timestamp1Str[3]) / 1000.0);
+		double timestamp2 = std::stoi(timestamp2Str[0]) * 3600 + std::stoi(timestamp2Str[1]) * 60 + std::stoi(timestamp2Str[2]) + (std::stoi(timestamp2Str[3]) / 1000.0);
+        std::string text = res[3];
+		text.erase(0, text.find_first_not_of("\r\n\t "));
+
+		if(timestamp > timestamp1 && timestamp < timestamp2)
+			return text;
+		
+        searchStart = res.suffix().first;
+    }
+	return "";
+}
+
 void VideoWidgetBase::activate()
 {
 	CIntObject::activate();
@@ -131,7 +175,7 @@ void VideoWidgetBase::tick(uint32_t msPassed)
 		}
 	}
 	if(subTitle && videoInstance)
-		subTitle->setText(std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count()) + "\n" + std::to_string(msPassed) + "\n" + std::to_string(videoInstance->timeStamp()));
+		subTitle->setText(getSubTitleLine(videoInstance->timeStamp()));
 }
 
 VideoWidget::VideoWidget(const Point & position, const VideoPath & prologue, const VideoPath & looped, bool playAudio)

+ 2 - 0
client/widgets/VideoWidget.h

@@ -25,10 +25,12 @@ class VideoWidgetBase : public CIntObject
 	int audioHandle = -1;
 	bool playAudio = false;
 	float scaleFactor = 1.0;
+	std::string srtContent = "";
 
 	void loadAudio(const VideoPath & file);
 	void startAudio();
 	void stopAudio();
+	std::string getSubTitleLine(double timestamp);
 
 protected:
 	VideoWidgetBase(const Point & position, const VideoPath & video, bool playAudio);

+ 1 - 0
lib/filesystem/ResourcePath.cpp

@@ -117,6 +117,7 @@ EResType EResTypeHelper::getTypeFromExtension(std::string extension)
 		{".BIK",   EResType::VIDEO},
 		{".OGV",   EResType::VIDEO},
 		{".WEBM",  EResType::VIDEO},
+		{".SRT",   EResType::SUBTITLE},
 		{".ZIP",   EResType::ARCHIVE_ZIP},
 		{".LOD",   EResType::ARCHIVE_LOD},
 		{".PAC",   EResType::ARCHIVE_LOD},

+ 2 - 0
lib/filesystem/ResourcePath.h

@@ -30,6 +30,7 @@ class JsonSerializeFormat;
  * Sound: .wav .82m
  * Video: .smk, .bik .ogv .webm
  * Music: .mp3, .ogg
+ * Subtitle: .srt
  * Archive: .lod, .snd, .vid .pac .zip
  * Palette: .pal
  * Savegame: .v*gm1
@@ -48,6 +49,7 @@ enum class EResType
 	VIDEO,
 	VIDEO_LOW_QUALITY,
 	SOUND,
+	SUBTITLE,
 	ARCHIVE_VID,
 	ARCHIVE_ZIP,
 	ARCHIVE_SND,