def test_scc_line_from_str_with_paint_on_style(self): line_str = "01:03:27:29 9429 9429 94f2 94f2 c845 d92c 2054 c845 5245 ae80" scc_line = SccLine.from_str(line_str) self.assertEqual(10, len(scc_line.scc_words)) self.assertEqual( SmpteTimeCode(1, 3, 27, 29, FPS_30).to_temporal_offset(), scc_line.time_code.to_temporal_offset()) self.assertEqual("01:03:27:29 {RDC}{RDC}{1504}{1504}HEY, THERE.", scc_line.to_disassembly()) self.assertEqual(SccCaptionStyle.PaintOn, scc_line.get_style())
def test_scc_line_from_str_with_roll_up_style(self): line_str = "01:03:27:29 9425 9425 94ad 94ad 94c8 94c8 c845 d92c 2054 c845 5245 ae80" scc_line = SccLine.from_str(line_str) self.assertEqual(12, len(scc_line.scc_words)) self.assertEqual( SmpteTimeCode(1, 3, 27, 29, FPS_30).to_temporal_offset(), scc_line.time_code.to_temporal_offset()) self.assertEqual("01:03:27:29 {RU2}{RU2}{CR}{CR}{14R}{14R}HEY, THERE.", scc_line.to_disassembly()) self.assertEqual(SccCaptionStyle.RollUp, scc_line.get_style())
def test_scc_line_from_str_with_unknown_style(self): line_str = "01:03:27:29 " scc_line = SccLine.from_str(line_str) self.assertEqual(0, len(scc_line.scc_words)) self.assertEqual( SmpteTimeCode(1, 3, 27, 29, FPS_30).to_temporal_offset(), scc_line.time_code.to_temporal_offset()) self.assertEqual("01:03:27:29 ", scc_line.to_disassembly()) self.assertEqual(SccCaptionStyle.Unknown, scc_line.get_style()) line_str = "01:03:27:29 9024 c845 d92c 2054 c845 5245 ae80 9f9f" scc_line = SccLine.from_str(line_str) self.assertEqual(8, len(scc_line.scc_words)) self.assertEqual( SmpteTimeCode(1, 3, 27, 29, FPS_30).to_temporal_offset(), scc_line.time_code.to_temporal_offset()) self.assertEqual("01:03:27:29 {BBl}HEY, THERE.{??}", scc_line.to_disassembly()) self.assertEqual(SccCaptionStyle.Unknown, scc_line.get_style())
def test_scc_line_from_str_with_pop_on_style(self): line_str = "01:03:27:29 94ae 94ae 9420 9420 94f2 94f2 c845 d92c 2054 c845 5245 ae80 942c 942c 8080 8080 942f 942f" scc_line = SccLine.from_str(line_str) self.assertEqual(18, len(scc_line.scc_words)) self.assertEqual( SmpteTimeCode(1, 3, 27, 29, FPS_30).to_temporal_offset(), scc_line.time_code.to_temporal_offset()) self.assertEqual( "01:03:27:29 {ENM}{ENM}{RCL}{RCL}{1504}{1504}HEY, THERE.{EDM}{EDM}{}{}{EOC}{EOC}", scc_line.to_disassembly()) self.assertEqual(SccCaptionStyle.PopOn, scc_line.get_style())
def to_disassembly(scc_content: str) -> str: """Dumps a SCC document into the disassembly format""" disassembly = "" for line in scc_content.splitlines(): LOGGER.debug(line) scc_line = SccLine.from_str(line) if scc_line is None: continue line_to_disassembly = scc_line.to_disassembly() LOGGER.debug(line_to_disassembly) disassembly += line_to_disassembly + "\n" return disassembly
def to_model(scc_content: str, config: Optional[SccReaderConfiguration] = None, progress_callback=lambda _: None): """Converts a SCC document to the data model""" context = _SccContext(config) document = ContentDocument() # Safe area must be a 32x15 grid, that represents 80% of the root area root_cell_resolution = CellResolutionType( rows=SCC_ROOT_CELL_RESOLUTION_ROWS, columns=SCC_ROOT_CELL_RESOLUTION_COLUMNS) document.set_cell_resolution(root_cell_resolution) context.set_safe_area( int((root_cell_resolution.columns - SCC_SAFE_AREA_CELL_RESOLUTION_COLUMNS) / 2), int((root_cell_resolution.rows - SCC_SAFE_AREA_CELL_RESOLUTION_ROWS) / 2)) # The active area is equivalent to the safe area active_area = ActiveAreaType( left_offset=context.safe_area_x_offset / root_cell_resolution.columns, top_offset=context.safe_area_y_offset / root_cell_resolution.rows, width=(root_cell_resolution.columns - (context.safe_area_x_offset * 2)) / root_cell_resolution.columns, height=(root_cell_resolution.rows - (context.safe_area_y_offset * 2)) / root_cell_resolution.rows, ) document.set_active_area(active_area) body = Body() body.set_doc(document) document.set_body(body) # the default value of LineHeight ("normal") typically translates to 125% of the font size, which causes regions to overflow. body.set_style(StyleProperties.LineHeight, LengthType(value=100, units=LengthType.Units.pct)) # use a more readable font than the default Courier body.set_style(StyleProperties.FontFamily, ("Consolas", "Monaco", GenericFontFamilyType.monospace)) # add line padding body.set_style(StyleProperties.LinePadding, LengthType(value=0.25, units=LengthType.Units.c)) context.div = Div() context.div.set_doc(document) body.push_child(context.div) lines = scc_content.splitlines() nb_lines = len(lines) for (index, line) in enumerate(lines): LOGGER.debug(line) scc_line = SccLine.from_str(line) progress_callback((index + 1) / nb_lines) if scc_line is None: continue context.process_line(scc_line) context.flush() return document
def test_scc_line_from_invalid_str(self): self.assertIsNone(SccLine.from_str("")) self.assertIsNone(SccLine.from_str("Hello world!"))