def test_close_file_handler(self): handler, path = gf.tmp_file() self.assertTrue(gf.file_exists(path)) gf.close_file_handler(handler) self.assertTrue(gf.file_exists(path)) gf.delete_file(handler, path) self.assertFalse(gf.file_exists(path))
def test_exec_srt_path(self): home = os.path.expanduser("~") tts_path = os.path.join(home, ".bin/myespeak") ffmpeg_path = os.path.join(home, ".bin/myffmpeg") ffprobe_path = os.path.join(home, ".bin/myffprobe") if gf.file_exists(tts_path) and gf.file_exists(ffmpeg_path) and gf.file_exists(ffprobe_path): self.execute([ ("in", "../tools/res/audio.mp3"), ("in", "../tools/res/subtitles.txt"), ("", "task_language=eng|is_text_type=subtitles|os_task_file_format=srt"), ("out", "sonnet.srt"), ("", "-r=\"tts_path=%s|ffmpeg_path=%s|ffprobe_path=%s\"" % (tts_path, ffmpeg_path, ffprobe_path)) ], 0)
def test_convert_path(self): path = os.path.expanduser("~") path = os.path.join(path, ".bin/myffmpeg") if gf.file_exists(path): self.execute([("in", "../tools/res/audio.wav"), ("out", "audio.wav"), ("", "-r=\"ffmpeg_path=%s\"" % path)], 0)
def test_convert_path(self): path = os.path.expanduser("~") path = os.path.join(path, ".bin/myffmpeg") if gf.file_exists(path): self.execute( [("in", "../tools/res/audio.wav"), ("out", "audio.wav"), ("", '-r="ffmpeg_path=%s"' % path)], 0 )
def test_exec_srt_path(self): home = os.path.expanduser("~") tts_path = os.path.join(home, ".bin/myespeak") ffmpeg_path = os.path.join(home, ".bin/myffmpeg") ffprobe_path = os.path.join(home, ".bin/myffprobe") if gf.file_exists(tts_path) and gf.file_exists( ffmpeg_path) and gf.file_exists(ffprobe_path): self.execute([ ("in", "../tools/res/audio.mp3"), ("in", "../tools/res/subtitles.txt"), ("", "task_language=eng|is_text_type=subtitles|os_task_file_format=srt" ), ("out", "sonnet.srt"), ("", "-r=\"tts_path=%s|ffmpeg_path=%s|ffprobe_path=%s\"" % (tts_path, ffmpeg_path, ffprobe_path)) ], 0)
def exists(self): """ Return ``True`` if the container has its path set and it exists, ``False`` otherwise. :rtype: boolean """ return gf.file_exists(self.file_path) or gf.directory_exists(self.file_path)
def test_probe_path(self): path = os.path.expanduser("~") path = os.path.join(path, ".bin/myffprobe") if gf.file_exists(path): self.execute([ ("in", "../tools/res/audio.wav"), ("", "-r=\"ffprobe_path=%s\"" % path) ], 0)
def test_synt_path(self): path = os.path.expanduser("~") path = os.path.join(path, ".bin/myespeak") if gf.file_exists(path): self.execute([ ("", "plain"), ("in", "../tools/res/plain.txt"), ("", "eng"), ("out", "synthesized.wav"), ("", "-r=\"c_extensions=False|tts=espeak|tts_path=%s\"" % path) ], 0)
def check_container(self, container_path, container_format=None, config_string=None): """ Check whether the given container is well-formed. :param string container_path: the path of the container to be checked :param container_format: the format of the container :type container_format: :class:`~aeneas.container.ContainerFormat` :param string config_string: the configuration string generated by the wizard :rtype: :class:`~aeneas.validator.ValidatorResult` """ self.log([u"Checking container '%s'", container_path]) self.result = ValidatorResult() if self._are_safety_checks_disabled(u"check_container"): return self.result if not (gf.file_exists(container_path) or gf.directory_exists(container_path)): self._failed(u"Container '%s' not found." % container_path) return self.result container = Container(container_path, container_format) try: self.log(u"Checking container has config file") if config_string is not None: self.log(u"Container with config string from wizard") self.check_config_txt(config_string, is_config_string=True) elif container.has_config_xml: self.log(u"Container has XML config file") contents = container.read_entry(container.entry_config_xml) if contents is None: self._failed(u"Unable to read the contents of XML config file.") return self.result self.check_config_xml(contents) elif container.has_config_txt: self.log(u"Container has TXT config file") contents = container.read_entry(container.entry_config_txt) if contents is None: self._failed(u"Unable to read the contents of TXT config file.") return self.result self.check_config_txt(contents, is_config_string=False) else: self._failed(u"Container does not have a TXT or XML configuration file.") self.log(u"Checking we have a valid job in the container") if not self.result.passed: return self.result self.log(u"Analyze the contents of the container") analyzer = AnalyzeContainer(container) if config_string is not None: job = analyzer.analyze(config_string=config_string) else: job = analyzer.analyze() self._check_analyzed_job(job, container) except OSError: self._failed(u"Unable to read the contents of the container.") return self.result
def test_copytree(self): orig = gf.tmp_directory() tmp_path = os.path.join(orig, "foo.bar") with io.open(tmp_path, "w", encoding="utf-8") as tmp_file: tmp_file.write(u"Foo bar") dest = gf.tmp_directory() gf.copytree(orig, dest) self.assertTrue(gf.file_exists(os.path.join(dest, "foo.bar"))) gf.delete_directory(dest) gf.delete_directory(orig)
def execute(self, path): input_path = gf.absolute_path(path, __file__) output_path = gf.tmp_directory() executor = ExecuteJob(job=None) executor.load_job_from_container(input_path) self.assertIsNotNone(executor.job) executor.execute() result_path = executor.write_output_container(output_path) self.assertIsNotNone(result_path) self.assertTrue(gf.file_exists(result_path)) executor.clean() gf.delete_directory(output_path)
def synthesize(self, text_file, audio_file_path, quit_after=None, backwards=False): """ Synthesize the text contained in the given fragment list into a ``wav`` file. Return a tuple ``(anchors, total_time, num_chars)``. :param text_file: the text file to be synthesized :type text_file: :class:`~aeneas.textfile.TextFile` :param string audio_file_path: the path to the output audio file :param float quit_after: stop synthesizing as soon as reaching this many seconds :param bool backwards: if ``True``, synthesizing from the end of the text file :rtype: tuple :raises: TypeError: if ``text_file`` is ``None`` or not an instance of ``TextFile`` :raises: OSError: if ``audio_file_path`` cannot be written :raises: OSError: if ``tts=custom`` in the RuntimeConfiguration and ``tts_path`` cannot be read :raises: ValueError: if the TTS engine has not been set yet """ if text_file is None: self.log_exc(u"text_file is None", None, True, TypeError) if not isinstance(text_file, TextFile): self.log_exc(u"text_file is not an instance of TextFile", None, True, TypeError) if not gf.file_can_be_written(audio_file_path): self.log_exc( u"Audio file path '%s' cannot be written" % (audio_file_path), None, True, OSError) if self.tts_engine is None: self.log_exc(u"Cannot select the TTS engine", None, True, ValueError) # synthesize self.log(u"Synthesizing text...") result = self.tts_engine.synthesize_multiple( text_file=text_file, output_file_path=audio_file_path, quit_after=quit_after, backwards=backwards) self.log(u"Synthesizing text... done") # check that the output file has been written if not gf.file_exists(audio_file_path): self.log_exc( u"Audio file path '%s' cannot be read" % (audio_file_path), None, True, OSError) return result
def synthesize( self, text_file, audio_file_path, quit_after=None, backwards=False ): """ Synthesize the text contained in the given fragment list into a ``wav`` file. Return a tuple ``(anchors, total_time, num_chars)``. :param text_file: the text file to be synthesized :type text_file: :class:`~aeneas.textfile.TextFile` :param string audio_file_path: the path to the output audio file :param float quit_after: stop synthesizing as soon as reaching this many seconds :param bool backwards: if ``True``, synthesizing from the end of the text file :rtype: tuple :raises: TypeError: if ``text_file`` is ``None`` or not an instance of ``TextFile`` :raises: OSError: if ``audio_file_path`` cannot be written :raises: OSError: if ``tts=custom`` in the RuntimeConfiguration and ``tts_path`` cannot be read :raises: ValueError: if the TTS engine has not been set yet """ if text_file is None: self.log_exc(u"text_file is None", None, True, TypeError) if not isinstance(text_file, TextFile): self.log_exc(u"text_file is not an instance of TextFile", None, True, TypeError) if not gf.file_can_be_written(audio_file_path): self.log_exc(u"Audio file path '%s' cannot be written" % (audio_file_path), None, True, OSError) if self.tts_engine is None: self.log_exc(u"Cannot select the TTS engine", None, True, ValueError) # synthesize self.log(u"Synthesizing text...") result = self.tts_engine.synthesize_multiple( text_file=text_file, output_file_path=audio_file_path, quit_after=quit_after, backwards=backwards ) self.log(u"Synthesizing text... done") # check that the output file has been written if not gf.file_exists(audio_file_path): self.log_exc(u"Audio file path '%s' cannot be read" % (audio_file_path), None, True, OSError) return result
def convert( self, input_file_path, output_file_path, head_length=None, process_length=None ): """ Convert the audio file at ``input_file_path`` into ``output_file_path``, using the parameters set in the constructor or through the ``parameters`` property. You can skip the beginning of the audio file by specifying ``head_length`` seconds to skip (if it is ``None``, start at time zero), and you can specify to convert only ``process_length`` seconds (if it is ``None``, process the entire input file length). By specifying both ``head_length`` and ``process_length``, you can skip a portion at the beginning and at the end of the original input file. :param string input_file_path: the path of the audio file to convert :param string output_file_path: the path of the converted audio file :param float head_length: skip these many seconds from the beginning of the audio file :param float process_length: process these many seconds of the audio file :raises: :class:`~aeneas.ffmpegwrapper.FFMPEGPathError`: if the path to the ``ffmpeg`` executable cannot be called :raises: OSError: if ``input_file_path`` does not exist or ``output_file_path`` cannot be written """ # test if we can read the input file if not gf.file_can_be_read(input_file_path): self.log_exc(u"Input file '%s' cannot be read" % (input_file_path), None, True, OSError) # test if we can write the output file if not gf.file_can_be_written(output_file_path): self.log_exc(u"Output file '%s' cannot be written" % (output_file_path), None, True, OSError) # call ffmpeg arguments = [self.rconf[RuntimeConfiguration.FFMPEG_PATH]] arguments.extend(["-i", input_file_path]) if head_length is not None: arguments.extend(["-ss", head_length]) if process_length is not None: arguments.extend(["-t", process_length]) if self.rconf.sample_rate in self.FFMPEG_PARAMETERS_MAP: arguments.extend(self.FFMPEG_PARAMETERS_MAP[self.rconf.sample_rate]) else: arguments.extend(self.FFMPEG_PARAMETERS_DEFAULT) arguments.append(output_file_path) self.log([u"Calling with arguments '%s'", arguments]) try: proc = subprocess.Popen( arguments, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE ) proc.communicate() proc.stdout.close() proc.stdin.close() proc.stderr.close() except OSError as exc: self.log_exc(u"Unable to call the '%s' ffmpeg executable" % (self.rconf[RuntimeConfiguration.FFMPEG_PATH]), exc, True, FFMPEGPathError) self.log(u"Call completed") # check if the output file exists if not gf.file_exists(output_file_path): self.log_exc(u"Output file '%s' was not written" % (output_file_path), None, True, OSError) # returning the output file path self.log([u"Returning output file path '%s'", output_file_path]) return output_file_path
def convert(self, input_file_path, output_file_path, head_length=None, process_length=None): """ Convert the audio file at ``input_file_path`` into ``output_file_path``, using the parameters set in the constructor or through the ``parameters`` property. You can skip the beginning of the audio file by specifying ``head_length`` seconds to skip (if it is ``None``, start at time zero), and you can specify to convert only ``process_length`` seconds (if it is ``None``, process the entire input file length). By specifying both ``head_length`` and ``process_length``, you can skip a portion at the beginning and at the end of the original input file. :param string input_file_path: the path of the audio file to convert :param string output_file_path: the path of the converted audio file :param float head_length: skip these many seconds from the beginning of the audio file :param float process_length: process these many seconds of the audio file :raises: :class:`~aeneas.ffmpegwrapper.FFMPEGPathError`: if the path to the ``ffmpeg`` executable cannot be called :raises: OSError: if ``input_file_path`` does not exist or ``output_file_path`` cannot be written """ # test if we can read the input file if not gf.file_can_be_read(input_file_path): self.log_exc(u"Input file '%s' cannot be read" % (input_file_path), None, True, OSError) # test if we can write the output file if not gf.file_can_be_written(output_file_path): self.log_exc( u"Output file '%s' cannot be written" % (output_file_path), None, True, OSError) # call ffmpeg arguments = [self.rconf[RuntimeConfiguration.FFMPEG_PATH]] arguments.extend(["-i", input_file_path]) if head_length is not None: arguments.extend(["-ss", head_length]) if process_length is not None: arguments.extend(["-t", process_length]) if self.rconf[RuntimeConfiguration. FFMPEG_SAMPLE_RATE] in self.FFMPEG_PARAMETERS_MAP: arguments.extend(self.FFMPEG_PARAMETERS_MAP[self.rconf[ RuntimeConfiguration.FFMPEG_SAMPLE_RATE]]) else: arguments.extend(self.FFMPEG_PARAMETERS_DEFAULT) arguments.append(output_file_path) self.log([u"Calling with arguments '%s'", arguments]) try: proc = subprocess.Popen(arguments, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) proc.communicate() proc.stdout.close() proc.stdin.close() proc.stderr.close() except OSError as exc: self.log_exc( u"Unable to call the '%s' ffmpeg executable" % (self.rconf[RuntimeConfiguration.FFMPEG_PATH]), exc, True, FFMPEGPathError) self.log(u"Call completed") # check if the output file exists if not gf.file_exists(output_file_path): self.log_exc( u"Output file '%s' was not written" % (output_file_path), None, True, OSError) # returning the output file path self.log([u"Returning output file path '%s'", output_file_path]) return output_file_path
def test_tmp_file(self): tmp_handler, tmp_file = gf.tmp_file() self.assertTrue(gf.file_exists(tmp_file)) gf.delete_file(tmp_handler, tmp_file)
def test_read_audio_path(self): path = os.path.expanduser("~") path = os.path.join(path, ".bin/myffprobe") if gf.file_exists(path): self.execute([("in", "../tools/res/audio.wav"), ("", "-r=\"ffprobe_path=%s\"" % path)], 0)
def test_tmp_file_suffix(self): tmp_handler, tmp_file = gf.tmp_file(suffix=".txt") self.assertTrue(gf.file_exists(tmp_file)) gf.delete_file(tmp_handler, tmp_file)
def test_file_exists_true(self): handler, path = gf.tmp_file() self.assertTrue(gf.file_exists(path)) gf.delete_file(handler, path)
def test_file_exists_false(self): path = "/foo/bar/baz" self.assertFalse(gf.file_exists(path))
def test_delete_file_existing(self): handler, path = gf.tmp_file() self.assertTrue(gf.file_exists(path)) gf.delete_file(handler, path) self.assertFalse(gf.file_exists(path))
def test_delete_file_not_existing(self): handler = None path = "/foo/bar/baz" self.assertFalse(gf.file_exists(path)) gf.delete_file(handler, path) self.assertFalse(gf.file_exists(path))