file_status_e avi_reader_c::read(generic_packetizer_c *ptzr, bool) { if ((-1 != m_vptzr) && (PTZR(m_vptzr) == ptzr)) return read_video(); for (auto &demuxer : m_audio_demuxers) if ((-1 != demuxer.m_ptzr) && (PTZR(demuxer.m_ptzr) == ptzr)) return read_audio(demuxer); for (auto &subs_demuxer : m_subtitle_demuxers) if ((-1 != subs_demuxer.m_ptzr) && (PTZR(subs_demuxer.m_ptzr) == ptzr)) return read_subtitles(subs_demuxer); return flush_packetizers(); }
void MatroskaWrapper::GetSubtitles(agi::fs::path const& filename, AssFile *target) { MkvStdIO input(filename); char err[2048]; agi::scoped_holder<MatroskaFile*, decltype(&mkv_Close)> file(mkv_Open(&input, err, sizeof(err)), mkv_Close); if (!file) throw MatroskaException(err); // Get info unsigned tracks = mkv_GetNumTracks(file); std::vector<unsigned> tracksFound; std::vector<std::string> tracksNames; // Find tracks for (auto track : boost::irange(0u, tracks)) { auto trackInfo = mkv_GetTrackInfo(file, track); if (trackInfo->Type != 0x11 || trackInfo->CompEnabled) continue; // Known subtitle format std::string CodecID(trackInfo->CodecID); if (CodecID == "S_TEXT/SSA" || CodecID == "S_TEXT/ASS" || CodecID == "S_TEXT/UTF8") { tracksFound.push_back(track); tracksNames.emplace_back(agi::format("%d (%s %s)", track, CodecID, trackInfo->Language)); if (trackInfo->Name) { tracksNames.back() += ": "; tracksNames.back() += trackInfo->Name; } } } // No tracks found if (tracksFound.empty()) throw MatroskaException("File has no recognised subtitle tracks."); unsigned trackToRead; // Only one track found if (tracksFound.size() == 1) trackToRead = tracksFound[0]; // Pick a track else { int choice = wxGetSingleChoiceIndex(_("Choose which track to read:"), _("Multiple subtitle tracks found"), to_wx(tracksNames)); if (choice == -1) throw agi::UserCancelException("canceled"); trackToRead = tracksFound[choice]; } // Picked track mkv_SetTrackMask(file, ~(1 << trackToRead)); auto trackInfo = mkv_GetTrackInfo(file, trackToRead); std::string CodecID(trackInfo->CodecID); bool srt = CodecID == "S_TEXT/UTF8"; bool ssa = CodecID == "S_TEXT/SSA"; AssParser parser(target, !ssa); // Read private data if it's ASS/SSA if (!srt) { // Read raw data std::string priv((const char *)trackInfo->CodecPrivate, trackInfo->CodecPrivateSize); // Load into file boost::char_separator<char> sep("\r\n"); for (auto const& cur : boost::tokenizer<boost::char_separator<char>>(priv, sep)) parser.AddLine(cur); } // Load default if it's SRT else { target->LoadDefault(false, OPT_GET("Subtitle Format/SRT/Default Style Catalog")->GetString()); parser.AddLine("[Events]"); } // Read timecode scale auto segInfo = mkv_GetFileInfo(file); int64_t timecodeScale = mkv_TruncFloat(trackInfo->TimecodeScale) * segInfo->TimecodeScale; // Progress bar auto totalTime = double(segInfo->Duration) / timecodeScale; DialogProgress progress(nullptr, _("Parsing Matroska"), _("Reading subtitles from Matroska file.")); progress.Run([&](agi::ProgressSink *ps) { read_subtitles(ps, file, &input, srt, totalTime, &parser); }); }