def test_parse_drop_frame_time_code(self):
        time_code = SmpteTimeCode.parse("01:02:03;04", FPS_29_97)
        self.assertEqual(1, time_code.get_hours())
        self.assertEqual(2, time_code.get_minutes())
        self.assertEqual(3, time_code.get_seconds())
        self.assertEqual(4, time_code.get_frames())
        self.assertEqual(FPS_29_97, time_code.get_frame_rate())
        self.assertTrue(time_code.is_drop_frame())
        self.assertEqual(111582, time_code.to_frames())
        self.assertEqual(Fraction(111582, Fraction(30000, 1001)),
                         time_code.to_temporal_offset())
        self.assertEqual("01:02:03;04", str(time_code))

        time_code = SmpteTimeCode.parse("01;02;03;04", FPS_29_97)
        self.assertEqual(1, time_code.get_hours())
        self.assertEqual(2, time_code.get_minutes())
        self.assertEqual(3, time_code.get_seconds())
        self.assertEqual(4, time_code.get_frames())
        self.assertEqual(FPS_29_97, time_code.get_frame_rate())
        self.assertTrue(time_code.is_drop_frame())
        self.assertEqual(111582, time_code.to_frames())
        self.assertEqual(Fraction(111582, Fraction(30000, 1001)),
                         time_code.to_temporal_offset())
        self.assertEqual("01:02:03;04", str(time_code))

        time_code = SmpteTimeCode.parse("01:02:03;04", FPS_30)
        self.assertEqual(1, time_code.get_hours())
        self.assertEqual(2, time_code.get_minutes())
        self.assertEqual(3, time_code.get_seconds())
        self.assertEqual(4, time_code.get_frames())
        self.assertEqual(FPS_29_97, time_code.get_frame_rate())
        self.assertTrue(time_code.is_drop_frame())
        self.assertEqual(111582, time_code.to_frames())
        self.assertEqual(Fraction(111582, Fraction(30000, 1001)),
                         time_code.to_temporal_offset())
        self.assertEqual("01:02:03;04", str(time_code))

        time_code = SmpteTimeCode.parse("01:02:03.04", FPS_29_97)
        self.assertEqual(1, time_code.get_hours())
        self.assertEqual(2, time_code.get_minutes())
        self.assertEqual(3, time_code.get_seconds())
        self.assertEqual(4, time_code.get_frames())
        self.assertEqual(FPS_29_97, time_code.get_frame_rate())
        self.assertTrue(time_code.is_drop_frame())
        self.assertEqual(111582, time_code.to_frames())
        self.assertEqual(Fraction(111582, Fraction(30000, 1001)),
                         time_code.to_temporal_offset())
        self.assertEqual("01:02:03;04", str(time_code))

        time_code = SmpteTimeCode.parse("01.02.03.04", FPS_29_97)
        self.assertEqual(1, time_code.get_hours())
        self.assertEqual(2, time_code.get_minutes())
        self.assertEqual(3, time_code.get_seconds())
        self.assertEqual(4, time_code.get_frames())
        self.assertEqual(FPS_29_97, time_code.get_frame_rate())
        self.assertTrue(time_code.is_drop_frame())
        self.assertEqual(111582, time_code.to_frames())
        self.assertEqual(Fraction(111582, Fraction(30000, 1001)),
                         time_code.to_temporal_offset())
        self.assertEqual("01:02:03;04", str(time_code))
Exemple #2
0
    def test_to_paragraph(self):
        caption_paragraph = SccCaptionParagraph()
        doc = ContentDocument()

        self.assertRaisesRegex(TypeError,
                               "Element id must be a valid xml:id string",
                               caption_paragraph.to_paragraph, doc)

        caption_paragraph.set_id("test-id")

        origin = caption_paragraph.get_origin()
        self.assertEqual(0, origin.x.value)
        self.assertEqual(0, origin.y.value)

        extent = caption_paragraph.get_extent()
        self.assertEqual(0, extent.width.value)
        self.assertEqual(0, extent.height.value)

        paragraph = caption_paragraph.to_paragraph(doc)

        self.assertEqual("test-id", paragraph.get_id())
        self.assertEqual(doc, paragraph.get_doc())
        self.assertIsNone(paragraph.get_begin())
        self.assertIsNone(paragraph.get_end())

        children = list(paragraph)
        self.assertEqual(0, len(children))

        caption_paragraph.set_begin(SmpteTimeCode.parse("00:01:02:03", FPS_30))
        caption_paragraph.set_end(SmpteTimeCode.parse("00:02:03:04", FPS_30))

        caption_paragraph.set_cursor_at(0)
        caption_paragraph.new_caption_text()
        caption_paragraph.append_text("Hello")
        caption_paragraph.set_cursor_at(1)
        caption_paragraph.new_caption_text()
        caption_paragraph.append_text("World")

        paragraph = caption_paragraph.to_paragraph(doc)

        self.assertEqual("test-id", paragraph.get_id())
        self.assertEqual(doc, paragraph.get_doc())
        self.assertEqual(Fraction(1863, 30), paragraph.get_begin())
        self.assertEqual(Fraction(3694, 30), paragraph.get_end())

        children = list(paragraph)
        self.assertEqual(3, len(children))

        self.assertIsInstance(children[0], Span)
        self.assertEqual("Hello", list(children[0])[0].get_text())

        self.assertIsInstance(children[1], Br)

        self.assertIsInstance(children[2], Span)
        self.assertEqual("World", list(children[2])[0].get_text())
Exemple #3
0
 def test_irt_requirement_0062_002_modified(self):
   '''Testing Time Code Out with value media 25 frames upper bound'''
   with open("src/test/resources/stl/irt/requirement-0062-002_modified.stl", "rb") as f:
     doc = ttconv.stl.reader.to_model(f)
     p = doc.get_body().first_child().first_child()
     self.assertEqual(p.get_end(),
                      SmpteTimeCode.parse("23:59:59:24",FPS_25).to_temporal_offset())
Exemple #4
0
 def test_irt_requirement_0061_001(self):
   '''Testing Time Code In with value media 25 frames lowerbounds'''  
   with open("src/test/resources/stl/irt/requirement-0061-001.stl", "rb") as f:
     doc = ttconv.stl.reader.to_model(f)
     p = doc.get_body().first_child().first_child()
     self.assertEqual(p.get_begin(),
                     SmpteTimeCode.parse("00:00:00:00",FPS_25).to_temporal_offset())
 def test_parse_non_drop_frame_time_code(self):
     time_code = SmpteTimeCode.parse("01:02:03:04", FPS_30)
     self.assertEqual(1, time_code.get_hours())
     self.assertEqual(2, time_code.get_minutes())
     self.assertEqual(3, time_code.get_seconds())
     self.assertEqual(4, time_code.get_frames())
     self.assertEqual(FPS_30, time_code.get_frame_rate())
     self.assertFalse(time_code.is_drop_frame())
     self.assertEqual(111694, time_code.to_frames())
     self.assertAlmostEqual(3723.133, time_code.to_seconds(), delta=0.001)
     self.assertEqual("01:02:03:04", str(time_code))
    def check_caption(self, paragraph: P, caption_id: str, begin: str,
                      end: Optional[str], *children):
        self.assertEqual(caption_id, paragraph.get_id())
        self.assertEqual(
            SmpteTimeCode.parse(begin, FPS_30).to_temporal_offset(),
            paragraph.get_begin())

        if end is not None:
            self.assertEqual(
                SmpteTimeCode.parse(end, FPS_30).to_temporal_offset(),
                paragraph.get_end())

        p_children = list(paragraph)
        self.assertEqual(len(children), len(p_children))

        for (index, child) in enumerate(p_children):
            expected_child = children[index]
            if isinstance(expected_child, str):
                texts = list(child)
                self.assertEqual(expected_child, texts[0].get_text())
            else:
                self.assertEqual(expected_child, Br)
    def test_add_frames(self):
        time_code = SmpteTimeCode.parse("01:02:03:04", FPS_30)
        time_code.add_frames(30)
        self.assertEqual(1, time_code.get_hours())
        self.assertEqual(2, time_code.get_minutes())
        self.assertEqual(4, time_code.get_seconds())
        self.assertEqual(4, time_code.get_frames())
        self.assertEqual(FPS_30, time_code.get_frame_rate())
        self.assertFalse(time_code.is_drop_frame())
        self.assertEqual(111724, time_code.to_frames())
        self.assertEqual(Fraction(111724, 30), time_code.to_temporal_offset())
        self.assertEqual("01:02:04:04", str(time_code))

        time_code = SmpteTimeCode.parse("00:00:59;29", FPS_29_97)
        time_code.add_frames()
        self.assertEqual(0, time_code.get_hours())
        self.assertEqual(1, time_code.get_minutes())
        self.assertEqual(0, time_code.get_seconds())
        self.assertEqual(2, time_code.get_frames())
        self.assertEqual(FPS_29_97, time_code.get_frame_rate())
        self.assertTrue(time_code.is_drop_frame())
        self.assertEqual(1_800, time_code.to_frames())
        self.assertEqual(Fraction(1800, Fraction(30000, 1001)),
                         time_code.to_temporal_offset())
        self.assertEqual("00:01:00;02", str(time_code))

        time_code = SmpteTimeCode.parse("00:19:59;29", FPS_29_97)
        time_code.add_frames()
        self.assertEqual(0, time_code.get_hours())
        self.assertEqual(20, time_code.get_minutes())
        self.assertEqual(0, time_code.get_seconds())
        self.assertEqual(0, time_code.get_frames())
        self.assertEqual(FPS_29_97, time_code.get_frame_rate())
        self.assertTrue(time_code.is_drop_frame())
        self.assertEqual(35_964, time_code.to_frames())
        self.assertEqual(Fraction(35964, Fraction(30000, 1001)),
                         time_code.to_temporal_offset())
        self.assertEqual("00:20:00;00", str(time_code))
Exemple #8
0
  def from_str(line: str) -> Optional[SccLine]:
    """Creates a SCC line instance from the specified string"""
    if not line:
      return None

    regex = re.compile(SCC_LINE_PATTERN)
    match = regex.match(line)

    if match is None:
      return None

    time_code = match.group(1)
    time_offset = SmpteTimeCode.parse(time_code, FPS_30)

    hex_words = line.split('\t')[1].split(' ')
    scc_words = [SccWord.from_str(hex_word) for hex_word in hex_words if hex_word]
    return SccLine(time_offset, scc_words)
Exemple #9
0
    def __init__(self,
                 gsi_block: bytes,
                 disable_fill_line_gap: bool = False,
                 disable_line_padding: bool = False,
                 start_tc: typing.Optional[str] = None,
                 font_stack: typing.Tuple[typing.Union[
                     str, styles.GenericFontFamilyType]] = None,
                 max_row_count: typing.Optional[typing.Union[int,
                                                             str]] = None):

        self.gsi = _GSIBlock._make(
            struct.unpack(
                '3s8sc2s2s32s32s32s32s32s32s16s6s6s2s5s5s3s2s2s1s8s8s1s1s3s32s32s32s75x576s',
                gsi_block))

        self.doc = model.ContentDocument()

        self.doc.set_cell_resolution(
            model.CellResolutionType(
                columns=round(100 * DEFAULT_TELETEXT_COLS /
                              (100 - 2 * DEFAULT_HORIZONTAL_SAFE_MARGIN_PCT)),
                rows=round(100 * DEFAULT_TELETEXT_ROWS /
                           (100 - 2 * DEFAULT_VERTICAL_SAFE_MARGIN_PCT))))

        self.doc.set_active_area(
            model.ActiveAreaType(
                left_offset=DEFAULT_HORIZONTAL_SAFE_MARGIN_PCT / 100,
                top_offset=DEFAULT_VERTICAL_SAFE_MARGIN_PCT / 100,
                width=1 - 2 * DEFAULT_HORIZONTAL_SAFE_MARGIN_PCT / 100,
                height=1 - 2 * DEFAULT_VERTICAL_SAFE_MARGIN_PCT / 100))

        self.body = model.Body(self.doc)

        if not disable_fill_line_gap:
            self.body.set_style(styles.StyleProperties.FillLineGap, True)

        if not disable_line_padding:
            self.body.set_style(
                styles.StyleProperties.LinePadding,
                styles.LengthType(LINE_PADDING_LENGTH_C,
                                  styles.LengthType.Units.c))

        if font_stack is not None:
            self.body.set_style(styles.StyleProperties.FontFamily, font_stack)
        else:
            self.body.set_style(styles.StyleProperties.FontFamily,
                                DEFAULT_FONT_STACK)

        self.doc.set_body(self.body)

        self.sgn_to_div_map = {}

        self.last_sn = None

        self.is_in_extension = False

        self.tti_tf = None

        self.fps = _DFC_FRACTION_MAP.get(self.gsi.DFC)
        if self.fps is None:
            LOGGER.error("Unknown GSI DFC value %s, defaulting to 25 fps",
                         self.gsi.DFC)
            self.fps = Fraction(25)
        else:
            LOGGER.debug("GSI DFC: %s", self.gsi.DFC)

        self.cct = self.gsi.CCT
        LOGGER.debug("GSI CCT: %s", self.gsi.CCT)

        try:
            self.tti_count = int(self.gsi.TNB)
            LOGGER.debug("GSI TNB: %s", self.gsi.TNB)
        except ValueError:
            LOGGER.error("Invalid TNB field value: %s", self.gsi.TNB)
            self.tti_count = sys.maxsize

        self.language = _LC_BCP47_MAP.get(self.gsi.LC)
        if self.language is None:
            LOGGER.warning(
                "Unknown LC value: %s, defaulting to 'unspecified''",
                self.gsi.LC)
            self.language = ""
        else:
            LOGGER.debug("GSI LC: %s", self.gsi.LC)

        self.doc.set_lang(self.language)

        if start_tc is None:
            self.start_offset = 0
        elif start_tc == "TCP":
            try:
                self.start_offset = SmpteTimeCode(
                    int(self.gsi.TCP[0:2]), int(self.gsi.TCP[2:4]),
                    int(self.gsi.TCP[4:6]), int(self.gsi.TCP[6:8]),
                    self.get_fps()).to_temporal_offset()
                LOGGER.debug("GSI TCP: %s", self.gsi.TCP)
            except ValueError:
                LOGGER.error("Invalid TCP value: %s", self.gsi.tcp)
                self.start_offset = 0
        else:
            try:
                self.start_offset = SmpteTimeCode.parse(
                    start_tc, self.get_fps()).to_temporal_offset()
            except ValueError:
                LOGGER.error("Invalid start_tc value")
                raise

        if max_row_count is None or self.is_teletext():
            self.max_row_count = DEFAULT_TELETEXT_ROWS
        elif isinstance(max_row_count, str) and max_row_count == "MNR":
            try:
                self.max_row_count = int(self.gsi.MNR)
                LOGGER.debug("GSI MNR: %s", self.gsi.MNR)
            except ValueError:
                LOGGER.error("Invalid MNR value: %s", self.gsi.MNR)
                self.start_offset = DEFAULT_TELETEXT_ROWS
        else:
            self.max_row_count = max_row_count

        # p_element for use across cumulative subtitles
        self.cur_p_element = None