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); }