void mpeg_ts_reader_c::process_chapter_entries() { if (m_chapter_timecodes.empty() || m_ti.m_no_chapters) return; std::stable_sort(m_chapter_timecodes.begin(), m_chapter_timecodes.end()); mm_mem_io_c out{nullptr, 0, 1000}; out.set_file_name(m_ti.m_fname); out.write_bom("UTF-8"); size_t idx = 0; for (auto &timecode : m_chapter_timecodes) { ++idx; auto ms = timecode.to_ms(); out.puts(boost::format("CHAPTER%|1$02d|=%|2$02d|:%|3$02d|:%|4$02d|.%|5$03d|\n" "CHAPTER%|1$02d|NAME=Chapter %1%\n") % idx % ( ms / 60 / 60 / 1000) % ((ms / 60 / 1000) % 60) % ((ms / 1000) % 60) % ( ms % 1000)); } mm_text_io_c text_out(&out, false); try { m_chapters = parse_chapters(&text_out, 0, -1, 0, m_ti.m_chapter_language, "", true); align_chapter_edition_uids(m_chapters.get()); } catch (mtx::chapter_parser_x &ex) { } }
bool parser_c::parse(mm_io_c *file) { try { file->setFilePointer(0); int64_t file_size = file->get_size(); if ((4 * 5 > file_size) || (10 * 1024 * 1024 < file_size)) throw mtx::mpls::exception(boost::format("File too small or too big: %1%") % file_size); auto content = file->read(4 * 5); m_bc = std::make_shared<bit_reader_c>(content->get_buffer(), 4 * 5); parse_header(); file->setFilePointer(0); content = file->read(file_size); m_bc = std::make_shared<bit_reader_c>(content->get_buffer(), file_size); parse_playlist(); parse_chapters(); m_bc.reset(); m_ok = true; } catch (mtx::mpls::exception &ex) { mxdebug_if(m_debug, boost::format("MPLS exception: %1%\n") % ex.what()); } catch (mtx::mm_io::exception &ex) { mxdebug_if(m_debug, boost::format("I/O exception: %1%\n") % ex.what()); } if (m_debug) dump(); file->setFilePointer(0); return m_ok; }
void ogm_reader_c::handle_stream_comments() { std::shared_ptr<std::vector<std::string> > comments; std::string title; bool charset_warning_printed = false; charset_converter_cptr cch = charset_converter_c::init(m_ti.m_chapter_charset); size_t i; for (i = 0; i < sdemuxers.size(); i++) { ogm_demuxer_cptr &dmx = sdemuxers[i]; if ((OGM_STREAM_TYPE_A_FLAC == dmx->stype) || (2 > dmx->packet_data.size())) continue; comments = extract_vorbis_comments(dmx->packet_data[1]); if (comments->empty()) continue; std::vector<std::string> chapter_strings; size_t j; for (j = 0; comments->size() > j; j++) { mxverb(2, boost::format("ogm_reader: commment for #%1% for %2%: %3%\n") % j % i % (*comments)[j]); std::vector<std::string> comment = split((*comments)[j], "=", 2); if (comment.size() != 2) continue; if (comment[0] == "LANGUAGE") { int index; index = map_to_iso639_2_code(comment[1].c_str()); if (-1 != index) dmx->language = iso639_languages[index].iso639_2_code; else { std::string lang = comment[1]; int pos1 = lang.find("["); while (0 <= pos1) { int pos2 = lang.find("]", pos1); if (-1 == pos2) pos2 = lang.length() - 1; lang.erase(pos1, pos2 - pos1 + 1); pos1 = lang.find("["); } pos1 = lang.find("("); while (0 <= pos1) { int pos2 = lang.find(")", pos1); if (-1 == pos2) pos2 = lang.length() - 1; lang.erase(pos1, pos2 - pos1 + 1); pos1 = lang.find("("); } index = map_to_iso639_2_code(lang.c_str()); if (-1 != index) dmx->language = iso639_languages[index].iso639_2_code; } } else if (comment[0] == "TITLE") title = comment[1]; else if (balg::starts_with(comment[0], "CHAPTER")) chapter_strings.push_back((*comments)[j]); } bool segment_title_set = false; if (title != "") { title = cch->utf8(title); if (!g_segment_title_set && g_segment_title.empty() && (OGM_STREAM_TYPE_V_MSCOMP == dmx->stype)) { g_segment_title = title; g_segment_title_set = true; segment_title_set = true; } dmx->title = title.c_str(); title = ""; } bool chapters_set = false; if (!chapter_strings.empty() && !m_ti.m_no_chapters) { try { std::shared_ptr<mm_mem_io_c> out(new mm_mem_io_c(nullptr, 0, 1000)); out->write_bom("UTF-8"); for (j = 0; j < chapter_strings.size(); j++) out->puts(cch->utf8(chapter_strings[j]) + std::string("\n")); out->set_file_name(m_ti.m_fname); std::shared_ptr<mm_text_io_c> text_out(new mm_text_io_c(out.get(), false)); m_chapters = parse_chapters(text_out.get(), 0, -1, 0, m_ti.m_chapter_language); chapters_set = true; align_chapter_edition_uids(m_chapters.get()); } catch (...) { } } if ( (segment_title_set || chapters_set) && !charset_warning_printed && (m_ti.m_chapter_charset.empty())) { mxwarn_fn(m_ti.m_fname, Y("This Ogg/OGM file contains chapter or title information. Unfortunately the charset used to store this information in " "the file cannot be identified unambiguously. The program assumes that your system's current charset is appropriate. This can " "be overridden with the '--chapter-charset <charset>' switch.\n")); charset_warning_printed = true; } } }