Пример #1
0
    def test_frames(self):
        ttml_doc_str = """<?xml version="1.0" encoding="UTF-8"?>
    <tt xml:lang="en" xmlns="http://www.w3.org/ns/ttml" >
    <body begin="5s"/>
    </tt>
    """

        ttml_doc = et.ElementTree(et.fromstring(ttml_doc_str))

        config = imsc_config.IMSCWriterConfiguration.parse({
            "time_format": "frames",
            "fps": "30/1"
        })
        xml_from_model = imsc_writer.from_model(imsc_reader.to_model(ttml_doc),
                                                config)
        body_element = xml_from_model.find("tt:body", {"tt": xml_ns.TTML})
        self.assertEqual(body_element.get("begin"), "150f")

        config = imsc_config.IMSCWriterConfiguration.parse({"fps": "30/1"})
        xml_from_model = imsc_writer.from_model(imsc_reader.to_model(ttml_doc),
                                                config)
        body_element = xml_from_model.find("tt:body", {"tt": xml_ns.TTML})
        self.assertEqual(body_element.get("begin"), "150f")

        config = imsc_config.IMSCWriterConfiguration.parse(
            {"time_format": "frames"})
        with self.assertRaises(ValueError):
            imsc_writer.from_model(imsc_reader.to_model(ttml_doc), config)
Пример #2
0
    def test_basic_time_containment_001(self):
        tree = et.parse(
            'src/test/resources/ttml/imsc-tests/imsc1/ttml/timing/BasicTimeContainment001.ttml'
        )
        doc = imsc_reader.to_model(tree)

        body = doc.get_body()

        self.assertIsNone(body.get_begin())
        self.assertEqual(body.get_end(), Fraction(10))

        div = list(body)[0]

        self.assertIsNone(div.get_begin())
        self.assertEqual(div.get_end(), Fraction(10))

        p = list(div)[0]

        self.assertIsNone(p.get_begin())
        self.assertIsNone(p.get_end())

        span_children = [
            v for v in list(p) if len(list(v)[0].get_text().strip()) > 0
        ]

        self.assertIsNone(span_children[0].get_begin())
        self.assertEqual(span_children[0].get_end(), Fraction(5))

        self.assertIsNone(span_children[1].get_begin())
        self.assertEqual(span_children[1].get_end(), Fraction(10))
Пример #3
0
    def test_referential_styling(self):
        tree = et.parse('src/test/resources/ttml/referential_styling.ttml')
        doc = imsc_reader.to_model(tree)

        divs = list(doc.get_body())

        self.assertEqual(divs[0].get_style(styles.StyleProperties.Color),
                         styles.NamedColors.green.value)
        self.assertEqual(
            divs[0].get_style(styles.StyleProperties.BackgroundColor),
            styles.NamedColors.blue.value)

        self.assertEqual(divs[1].get_style(styles.StyleProperties.Color),
                         styles.NamedColors.black.value)
        self.assertEqual(
            divs[1].get_style(styles.StyleProperties.BackgroundColor),
            styles.NamedColors.blue.value)

        regions = list(doc.iter_regions())

        self.assertEqual(regions[0].get_style(styles.StyleProperties.Color),
                         styles.NamedColors.blue.value)
        self.assertEqual(
            regions[0].get_style(styles.StyleProperties.BackgroundColor),
            styles.NamedColors.yellow.value)

        self.assertEqual(regions[1].get_style(styles.StyleProperties.Color),
                         styles.NamedColors.red.value)
        self.assertEqual(
            regions[1].get_style(styles.StyleProperties.BackgroundColor),
            styles.NamedColors.yellow.value)
Пример #4
0
    def test_basic_timing_007(self):
        tree = et.parse(
            'src/test/resources/ttml/imsc-tests/imsc1/ttml/timing/BasicTiming007.ttml'
        )
        doc = imsc_reader.to_model(tree)

        body = doc.get_body()

        self.assertIsNone(body.get_begin())
        self.assertEqual(body.get_end(), Fraction(20))

        div = list(body)[0]

        self.assertIsNone(div.get_begin())
        self.assertEqual(div.get_end(), Fraction(20))

        p = list(div)[0]

        self.assertEqual(p.get_begin(), 5)
        self.assertEqual(p.get_end(), 20)

        span_children = [v for v in list(p) if isinstance(v, model.Span)]

        self.assertEqual(len(span_children), 1)

        self.assertEqual(span_children[0].get_begin(), None)
        self.assertEqual(span_children[0].get_end(), Fraction(10))
Пример #5
0
    def test_lwsp_default(self):
        tree = et.parse('src/test/resources/ttml/lwsp_default.ttml')

        doc = imsc_reader.to_model(tree)

        isd = ISD.from_model(doc, 0)

        p0 = list(isd.iter_regions())[0][0][0][0]

        spans = list(p0)

        self.assertEqual(len(spans), 3)

        self.assertEqual(spans[0][0].get_text(), "hello ")

        self.assertEqual(spans[1][0].get_text(), "my name")

        self.assertEqual(spans[2][0].get_text(), " is Mathilda")

        p1 = list(isd.iter_regions())[0][0][0][1]

        spans = list(p1)

        self.assertEqual(len(spans), 4)

        self.assertEqual(spans[0][0].get_text(), "bonjour")

        self.assertEqual(spans[1][0].get_text(), " mon nom")

        self.assertIsInstance(spans[2], model.Br)

        self.assertEqual(spans[3][0].get_text(), "est")
Пример #6
0
 def test_imsc_1_1_test_suite(self):
     for root, _subdirs, files in os.walk(
             "src/test/resources/ttml/imsc-tests/imsc1_1/ttml"):
         for filename in files:
             (name, ext) = os.path.splitext(filename)
             if ext == ".ttml":
                 with self.subTest(name):
                     tree = et.parse(os.path.join(root, filename))
                     self.assertIsNotNone(imsc_reader.to_model(tree))
Пример #7
0
    def test_frame_rate(self):
        tree = et.parse(
            'src/test/resources/ttml/imsc-tests/imsc1/ttml/timing/TimeExpressions001.ttml'
        )
        doc = imsc_reader.to_model(tree)

        # <p begin="0s" end="24f">24f = 1.001s</p>
        p = list(list(doc.get_body())[0])[3]

        self.assertEqual(p.get_end(), Fraction(4394201, 1000))
Пример #8
0
    def test_clock_time(self):
        ttml_doc_str = """<?xml version="1.0" encoding="UTF-8"?>
    <tt xml:lang="en" xmlns="http://www.w3.org/ns/ttml" >
    <body begin="2.3s"/>
    </tt>
    """

        ttml_doc = et.ElementTree(et.fromstring(ttml_doc_str))

        config = imsc_config.IMSCWriterConfiguration.parse(
            {"time_format": "clock_time"})
        xml_from_model = imsc_writer.from_model(imsc_reader.to_model(ttml_doc),
                                                config)
        body_element = xml_from_model.find("tt:body", {"tt": xml_ns.TTML})
        self.assertEqual(body_element.get("begin"), "00:00:02.300")

        xml_from_model = imsc_writer.from_model(imsc_reader.to_model(ttml_doc))
        body_element = xml_from_model.find("tt:body", {"tt": xml_ns.TTML})
        self.assertEqual(body_element.get("begin"), "00:00:02.300")
Пример #9
0
 def test_imsc_1_test_suite(self):
     for root, _subdirs, files in os.walk(
             "src/test/resources/ttml/imsc-tests/imsc1/ttml"):
         for filename in files:
             (name, ext) = os.path.splitext(filename)
             if ext == ".ttml":
                 with self.subTest(name):
                     tree = et.parse(os.path.join(root, filename))
                     doc = imsc_reader.to_model(tree)
                     srt_file = srt_writer.from_model(doc)
                     srt_reader.to_model(io.StringIO(srt_file))
Пример #10
0
    def test_initial(self):
        tree = et.parse(
            'src/test/resources/ttml/imsc-tests/imsc1_1/ttml/initial/initial002.ttml'
        )
        doc = imsc_reader.to_model(tree)

        self.assertEqual(doc.get_initial_value(styles.StyleProperties.Color),
                         styles.NamedColors.green.value)
        self.assertEqual(
            doc.get_initial_value(styles.StyleProperties.FontStyle),
            styles.FontStyleType.italic)
Пример #11
0
 def test_imsc_1_test_suite(self):
     for root, _subdirs, files in os.walk(
             "src/test/resources/ttml/imsc-tests/imsc1/ttml"):
         for filename in files:
             (name, ext) = os.path.splitext(filename)
             if ext == ".ttml":
                 with self.subTest(name), self.assertLogs() as logs:
                     logging.getLogger().info(
                         "*****dummy*****")  # dummy log
                     tree = et.parse(os.path.join(root, filename))
                     self.assertIsNotNone(imsc_reader.to_model(tree))
                     if len(logs.output) > 1:
                         self.fail(logs.output)
Пример #12
0
    def test_animation_001(self):
        file_to_parse = "src/test/resources/ttml/imsc-tests/imsc1/ttml/animation/Animation001.ttml"

        tree = et.parse(file_to_parse)

        # create the model
        test_model = imsc_reader.to_model(tree)

        # convert from a model to a ttml document
        tree_from_model = imsc_writer.from_model(test_model)

        # write the document out to a file
        self.write_pretty_xml(tree_from_model, 'build/out.ttml')
Пример #13
0
 def test_imsc_1_2_test_suite(self):
     for root, _subdirs, files in os.walk(
             "src/test/resources/ttml/imsc-tests/imsc1_2/ttml"):
         for filename in files:
             (name, ext) = os.path.splitext(filename)
             if ext == ".ttml":
                 with self.subTest(name):
                     path = os.path.join(root, filename)
                     tree = et.parse(path)
                     test_model = imsc_reader.to_model(tree)
                     srt_from_model = srt_writer.from_model(test_model)
                     self._check_output_srt(test_model, srt_from_model,
                                            path)
Пример #14
0
  def test_display_none_handling(self):
    xml_doc = et.parse("src/test/resources/ttml/imsc-tests/imsc1/ttml/timing/MediaParTiming002.ttml")
    doc = imsc_reader.to_model(xml_doc)
    isd = ISD.from_model(doc, 0)

    regions = list(isd.iter_regions())

    # single default region

    self.assertEqual(len(regions), 1)

    # no content

    self.assertEqual(len(regions[0]), 0)
Пример #15
0
    def test_empty_isds(self):
        tree = et.parse(
            'src/test/resources/ttml/imsc-tests/imsc1/ttml/timing/BasicTiming010.ttml'
        )
        doc = imsc_reader.to_model(tree)
        srt_from_model = srt_writer.from_model(doc)

        self.assertEqual(
            srt_from_model, """1
00:00:10,000 --> 00:00:24,400
This text must appear at 10 seconds and disappear at 24.4 seconds

2
00:00:25,000 --> 00:00:35,000
This text must appear at 25 seconds and disappear at 35 seconds
""")
Пример #16
0
    def test_reader_tt_element_not_root_element(self):

        xml_str = """<?xml version="1.0" encoding="UTF-8"?>
      <not_tt xml:lang="en"
          xmlns="http://www.w3.org/ns/ttml"
          xmlns:ttm="http://www.w3.org/ns/ttml#metadata" 
          xmlns:tts="http://www.w3.org/ns/ttml#styling"
          xmlns:ttp="http://www.w3.org/ns/ttml#parameter" 
          xmlns:ittp="http://www.w3.org/ns/ttml/profile/imsc1#parameter"
          ittp:activeArea="50% 50% 80% 80%"
          tts:extent="640px 480px"
          ttp:profile="http://www.w3.org/ns/ttml/profile/imsc1/text">
      </not_tt>"""

        tt_not_root = et.ElementTree(et.fromstring(xml_str))
        self.assertIsNone(imsc_reader.to_model(tt_not_root))
Пример #17
0
 def test_imsc_1_test_suite(self):
     if not os.path.exists('build/imsc1'):
         os.makedirs('build/imsc1')
     for root, _subdirs, files in os.walk(
             "src/test/resources/ttml/imsc-tests/imsc1/ttml"):
         for filename in files:
             (name, ext) = os.path.splitext(filename)
             if ext == ".ttml":
                 with self.subTest(name), self.assertLogs() as logs:
                     logging.getLogger().info(
                         "*****dummy*****")  # dummy log
                     tree = et.parse(os.path.join(root, filename))
                     test_model = imsc_reader.to_model(tree)
                     tree_from_model = imsc_writer.from_model(test_model)
                     self.write_pretty_xml(tree_from_model,
                                           f'build/imsc1/{name}.ttml')
                     if len(logs.output) > 1:
                         self.fail(logs.output)
Пример #18
0
    def test_lwsp_preserve(self):
        tree = et.parse('src/test/resources/ttml/lwsp_preserve.ttml')

        doc = imsc_reader.to_model(tree)

        isd = ISD.from_model(doc, 0)

        p0 = list(isd.iter_regions())[0][0][0][0]

        spans = list(p0)

        self.assertEqual(len(spans), 3)

        self.assertEqual(spans[0][0].get_text(), "hello ")

        self.assertEqual(spans[1][0].get_text(), " my \nname ")

        self.assertEqual(spans[2][0].get_text(), "is Mathilda")
Пример #19
0
    def test_fps(self):
        ttml_doc_str = """<?xml version="1.0" encoding="UTF-8"?>
    <tt xml:lang="en" xmlns="http://www.w3.org/ns/ttml" >
    <body begin="5s"/>
    </tt>
    """

        ttml_doc = et.ElementTree(et.fromstring(ttml_doc_str))

        config = imsc_config.IMSCWriterConfiguration(
            time_format=imsc_config.TimeExpressionEnum.frames,
            fps=Fraction(30, 1))
        xml_from_model = imsc_writer.from_model(imsc_reader.to_model(ttml_doc),
                                                config)

        body_element = xml_from_model.find("tt:body", {"tt": xml_ns.TTML})

        self.assertEqual(body_element.get("begin"), "150f")
Пример #20
0
    def test_imsc_1_test_suite(self):
        manifest = []
        base_path = "build/imsc1"

        for root, _subdirs, files in os.walk(
                "src/test/resources/ttml/imsc-tests/imsc1/ttml"):
            for filename in files:
                (name, ext) = os.path.splitext(filename)
                if ext == ".ttml":
                    with self.subTest(name), self.assertLogs() as logs:
                        logging.getLogger().info(
                            "*****dummy*****")  # dummy log
                        tree = et.parse(os.path.join(root, filename))
                        test_model = imsc_reader.to_model(tree)
                        tree_from_model = imsc_writer.from_model(test_model)

                        test_dir_relative_path = os.path.basename(root)

                        test_relative_path = os.path.join(
                            test_dir_relative_path, filename)

                        os.makedirs(os.path.join(base_path, "ttml",
                                                 test_dir_relative_path),
                                    exist_ok=True)

                        with open(
                                os.path.join(base_path, "ttml",
                                             test_relative_path), "wb") as f:
                            f.write(
                                et.tostring(tree_from_model.getroot(),
                                            'utf-8'))

                        manifest.append({
                            "path":
                            str(test_relative_path).replace('\\', '/')
                        })

                        if len(logs.output) > 1:
                            self.fail(logs.output)

        with open(os.path.join(base_path, "tests.json"), "w",
                  encoding="utf8") as fp:
            json.dump(manifest, fp)
Пример #21
0
    def test_position(self):
        ttml_doc_str = """<?xml version="1.0" encoding="UTF-8"?>
<tt xml:lang="en-US" xmlns="http://www.w3.org/ns/ttml" xmlns:tts="http://www.w3.org/ns/ttml#styling" xmlns:ttp="http://www.w3.org/ns/ttml#parameter" xmlns:ttm="http://www.w3.org/ns/ttml#metadata" ttp:frameRate="24" ttp:frameRateMultiplier="1000 1001" ttp:profile="http://www.w3.org/ns/ttml/profile/imsc1/text" ttp:timeBase="media">
  <head>
    <styling>
      <style xml:id="style.center" tts:fontFamily="Arial" tts:fontSize="100%" tts:fontStyle="normal" tts:fontWeight="normal" tts:backgroundColor="transparent" tts:color="white" tts:textAlign="center"/>
    </styling>
    <layout>
      <region xml:id="region.after" tts:displayAlign="after" tts:backgroundColor="transparent" tts:origin="10% 10%" tts:extent="80% 80%"/>
      <region xml:id="region.before" tts:displayAlign="before" tts:backgroundColor="transparent" tts:origin="10% 10%" tts:extent="80% 80%"/>
    </layout>
  </head>
  <body>
    <div>
      <p style="style.center" region="region.after" begin="00:00:03:12" end="00:00:12:00">Only one or two short samples are needed<br/>to make sure the conversion basically works</p>
      <p style="style.center" region="region.before" begin="00:00:14:09" end="00:00:25:17">Cool, got it, will do it by end of next week.</p>
    </div>
  </body>
</tt>"""

        expected_vtt = """WEBVTT

1
00:00:03.501 --> 00:00:12.000 line:90%,end
Only one or two short samples are needed
to make sure the conversion basically works

2
00:00:14.375 --> 00:00:25.709 line:10%,start
Cool, got it, will do it by end of next week.
"""

        model = imsc_reader.to_model(
            et.ElementTree(et.fromstring(ttml_doc_str)))
        config = VTTWriterConfiguration()
        config.line_position = True
        vtt_from_model = vtt_writer.from_model(model, config)
        self.assertEqual(expected_vtt, vtt_from_model)

        config = VTTWriterConfiguration.parse(
            json.loads('{"line_position":true}'))
        vtt_from_model = vtt_writer.from_model(model, config)
        self.assertEqual(expected_vtt, vtt_from_model)
Пример #22
0
    def test_basic_time_containment_002(self):
        tree = et.parse(
            'src/test/resources/ttml/imsc-tests/imsc1/ttml/timing/BasicTimeContainment002.ttml'
        )
        doc = imsc_reader.to_model(tree)

        body = doc.get_body()

        self.assertIsNone(body.get_begin())
        self.assertEqual(body.get_end(), Fraction(20))

        div = list(body)[0]

        self.assertIsNone(div.get_begin())
        self.assertEqual(div.get_end(), Fraction(20))

        p_children = [v for v in list(div) if isinstance(v, model.P)]

        self.assertIsNone(p_children[0].get_begin())
        self.assertEqual(p_children[0].get_end(), Fraction(10))

        self.assertEqual(p_children[1].get_begin(), Fraction(10))
        self.assertEqual(p_children[1].get_end(), Fraction(20))
Пример #23
0
 def test_body_only(self):
     tree = et.parse('src/test/resources/ttml/body_only.ttml')
     imsc_reader.to_model(tree)
Пример #24
0
def convert(args):
    '''Process input and output through the reader, converter, and writer'''

    inputfile = args.input
    outputfile = args.output

    # Note - Loading config data from a file takes priority over
    # data passed in as a json string
    json_config_data = None

    if args.config is not None:
        json_config_data = json.loads(args.config)
    if args.config_file is not None:
        with open(args.config_file) as json_file:
            json_config_data = json.load(json_file)

    general_config = read_config_from_json(GeneralConfiguration,
                                           json_config_data)

    if general_config is not None:

        if general_config.progress_bar is not None:
            progress.display_progress_bar = general_config.progress_bar

        if general_config.log_level is not None:
            LOGGER.setLevel(general_config.log_level)

    LOGGER.info("Input file is %s", inputfile)
    LOGGER.info("Output file is %s", outputfile)

    _input_filename, input_file_extension = os.path.splitext(inputfile)
    _output_filename, output_file_extension = os.path.splitext(outputfile)

    reader_type = FileTypes.get_file_type(args.itype, input_file_extension)
    writer_type = FileTypes.get_file_type(args.otype, output_file_extension)

    if reader_type is FileTypes.TTML:
        #
        # Parse the xml input file into an ElementTree
        #
        tree = et.parse(inputfile)

        #
        # Pass the parsed xml to the reader
        #
        model = imsc_reader.to_model(tree, progress_callback_read)

    elif reader_type is FileTypes.SCC:
        file_as_str = Path(inputfile).read_text()

        #
        # Read the config
        #
        reader_config = read_config_from_json(SccReaderConfiguration,
                                              json_config_data)

        #
        # Pass the parsed xml to the reader
        #
        model = scc_reader.to_model(file_as_str, reader_config,
                                    progress_callback_read)

    elif reader_type is FileTypes.STL:
        #
        # Read the config
        #
        reader_config = read_config_from_json(STLReaderConfiguration,
                                              json_config_data)

        #
        # Open the file and pass it to the reader
        #
        with open(inputfile, "rb") as f:
            model = stl_reader.to_model(f, reader_config,
                                        progress_callback_read)

    elif reader_type is FileTypes.SRT:

        #
        # Open the file and pass it to the reader
        #
        with open(inputfile, "r", encoding="utf-8") as f:
            model = srt_reader.to_model(f, None, progress_callback_read)

    else:
        if args.itype is not None:
            exit_str = f'Input type {args.itype} is not supported'
        else:
            exit_str = f'Input file {args.input} is not supported'

        LOGGER.error(exit_str)
        sys.exit(exit_str)

    if writer_type is FileTypes.TTML:
        #
        # Read the config
        #
        writer_config = read_config_from_json(IMSCWriterConfiguration,
                                              json_config_data)

        #
        # Construct and configure the writer
        #
        tree_from_model = imsc_writer.from_model(model, writer_config,
                                                 progress_callback_write)

        #
        # Write out the converted file
        #
        tree_from_model.write(outputfile, encoding="utf-8")

    elif writer_type is FileTypes.SRT:
        #
        # Read the config
        #
        writer_config = read_config_from_json(ISDConfiguration,
                                              json_config_data)

        #
        # Construct and configure the writer
        #
        srt_document = srt_writer.from_model(model, writer_config,
                                             progress_callback_write)

        #
        # Write out the converted file
        #
        with open(outputfile, "w", encoding="utf-8") as srt_file:
            srt_file.write(srt_document)

    elif writer_type is FileTypes.VTT:
        #
        # Read the config
        #
        writer_config = read_config_from_json(VTTWriterConfiguration,
                                              json_config_data)

        #
        # Construct and configure the writer
        #
        vtt_document = vtt_writer.from_model(model, writer_config,
                                             progress_callback_write)

        #
        # Write out the converted file
        #
        with open(outputfile, "w", encoding="utf-8") as vtt_file:
            vtt_file.write(vtt_document)

    else:
        if args.otype is not None:
            exit_str = f'Output type {args.otype} is not supported'
        else:
            exit_str = f'Output file is {args.output} is not supported'

        LOGGER.error(exit_str)
        sys.exit(exit_str)
Пример #25
0
def convert(args):
    '''Process input and output through the reader, converter, and writer'''

    inputfile = args.input
    outputfile = args.output

    LOGGER.info("Input file is %s", inputfile)
    LOGGER.info("Output file is %s", outputfile)

    _input_filename, input_file_extension = os.path.splitext(inputfile)
    _output_filename, output_file_extension = os.path.splitext(outputfile)

    reader_type = FileTypes.get_file_type(args.itype, input_file_extension)
    writer_type = FileTypes.get_file_type(args.otype, output_file_extension)

    if reader_type is FileTypes.TTML:
        #
        # Parse the xml input file into an ElementTree
        #
        tree = et.parse(inputfile)

        #
        # Pass the parsed xml to the reader
        #
        model = imsc_reader.to_model(tree)

    elif reader_type is FileTypes.SCC:
        file_as_str = Path(inputfile).read_text()

        #
        # Pass the parsed xml to the reader
        #
        model = scc_reader.to_model(file_as_str)
    else:
        if args.itype is not None:
            exit_str = f'Input type {args.itype} is not supported'
        else:
            exit_str = f'Input file is {args.input} is not supported'

        LOGGER.error(exit_str)
        sys.exit(exit_str)

    if writer_type is FileTypes.TTML:
        #
        # Construct and configure the writer
        #
        tree_from_model = imsc_writer.from_model(model)

        #
        # Write out the converted file
        #
        tree_from_model.write(outputfile)

    elif writer_type is FileTypes.SRT:
        #
        # Construct and configure the writer
        #
        srt_document = srt_writer.from_model(model)

        #
        # Write out the converted file
        #
        with open(outputfile, "w") as srt_file:
            srt_file.write(srt_document)

    else:
        if args.otype is not None:
            exit_str = f'Output type {args.otype} is not supported'
        else:
            exit_str = f'Output file is {args.output} is not supported'

        LOGGER.error(exit_str)
        sys.exit(exit_str)