Exemple #1
0
static void read_subtitles(agi::ProgressSink *ps, MatroskaFile *file, MkvStdIO *input, bool srt, double totalTime, AssParser *parser) {
	std::vector<std::pair<int, std::string>> subList;

	// Load blocks
	ulonglong startTime, endTime, filePos;
	unsigned int rt, frameSize, frameFlags;

	while (mkv_ReadFrame(file, 0, &rt, &startTime, &endTime, &filePos, &frameSize, &frameFlags) == 0) {
		if (ps->IsCancelled()) return;
		if (frameSize == 0) continue;

		const auto readBuf = input->file.read(filePos, frameSize);
		const auto readBufEnd = readBuf + frameSize;

		// Get start and end times
		longlong timecodeScaleLow = 1000000;
		AssTime subStart = startTime / timecodeScaleLow;
		AssTime subEnd = endTime / timecodeScaleLow;

		using str_range = boost::iterator_range<const char *>;

		// Process SSA/ASS
		if (!srt) {
			auto first = std::find(readBuf, readBufEnd, ',');
			if (first == readBufEnd) continue;
			auto second = std::find(first + 1, readBufEnd, ',');
			if (second == readBufEnd) continue;

			subList.emplace_back(
				boost::lexical_cast<int>(str_range(readBuf, first)),
				str(boost::format("Dialogue: %d,%s,%s,%s")
					% boost::lexical_cast<int>(str_range(first + 1, second))
					% subStart.GetAssFormated()
					% subEnd.GetAssFormated()
					% str_range(second + 1, readBufEnd)));
		}
		// Process SRT
		else {
			auto line = str(boost::format("Dialogue: 0,%s,%s,Default,,0,0,0,,%s")
				% subStart.GetAssFormated()
				% subEnd.GetAssFormated()
				% str_range(readBuf, readBufEnd));
			boost::replace_all(line, "\r\n", "\\N");
			boost::replace_all(line, "\r", "\\N");
			boost::replace_all(line, "\n", "\\N");

			subList.emplace_back(subList.size(), std::move(line));
		}

		ps->SetProgress(startTime / timecodeScaleLow, totalTime);
	}

	// Insert into file
	sort(begin(subList), end(subList));
	for (auto order_value_pair : subList)
		parser->AddLine(order_value_pair.second);
}