def test_tc_config_string(self): taskconf = TaskConfiguration() taskconf["language"] = Language.ITA taskconf["description"] = u"Test description" taskconf["custom_id"] = u"customid" taskconf["i_a_head"] = u"20" taskconf["i_a_process"] = u"100" taskconf["o_format"] = SyncMapFormat.SMIL taskconf["o_name"] = u"output.smil" taskconf["o_smil_audio_ref"] = u"../audio/audio001.mp3" taskconf["o_smil_page_ref"] = u"../text/page001.xhtml" expected = u"is_audio_file_head_length=20|is_audio_file_process_length=100|os_task_file_format=smil|os_task_file_name=output.smil|os_task_file_smil_audio_ref=../audio/audio001.mp3|os_task_file_smil_page_ref=../text/page001.xhtml|task_custom_id=customid|task_description=Test description|task_language=ita" self.assertEqual(taskconf.config_string(), expected)
def test_config_string_missing_keys(self): taskconf = TaskConfiguration() taskconf.language = Language.IT taskconf.description = "Test description" taskconf.custom_id = "customid" taskconf.is_audio_file_head_length = "20" taskconf.is_audio_file_process_length = "100" taskconf.os_file_format = SyncMapFormat.TXT taskconf.os_file_name = "output.txt" expected = "task_description=Test description|task_language=it|task_custom_id=customid|is_audio_file_head_length=20|is_audio_file_process_length=100|os_task_file_format=txt|os_task_file_name=output.txt" self.assertEqual(taskconf.config_string(), expected)
def test_task_sync_map_leaves(self): task = Task() task.configuration = TaskConfiguration() task.configuration["language"] = Language.ENG task.configuration["o_format"] = SyncMapFormat.TXT task.sync_map = self.dummy_sync_map() self.assertEqual(len(task.sync_map_leaves()), 3)
def createSyncedLyricsFile(lyrics, file): global lyricsSynced, errors f = open("tempSync.txt", "w+") f.write(lyrics) f.close() config = TaskConfiguration() config[gc.PPN_TASK_LANGUAGE] = Language.FRA config[gc.PPN_TASK_IS_TEXT_FILE_FORMAT] = TextFileFormat.PLAIN config[gc.PPN_TASK_OS_FILE_FORMAT] = SyncMapFormat.AUDH task = Task() task.configuration = config try: task.audio_file_path_absolute = file task.text_file_path_absolute = "tempSync.txt" ExecuteTask(task).execute() syncedLyricsFile = open(file[:-4] + ".lrc", "w+") for fragment in task.sync_map_leaves(): syncedLyricsFile.write( str('[' + gf.time_to_hhmmssmmm(fragment.interval.begin, '.')[3:-1] + ']' + fragment.text + '\n')) syncedLyricsFile.close() print(" Sync Added", sep=' ', end='', flush=True) lyricsSynced += 1 except Exception as e : errors += 1 print(" Sync error", sep=' ', end='',flush=True)
def align_files_in_place(data: InputDataFiles): try: # prepare config aeneas_config = TaskConfiguration() aeneas_config[gc.PPN_TASK_IS_TEXT_FILE_FORMAT] = data.text_file_format aeneas_config[gc.PPN_TASK_LANGUAGE] = data.language # create task task = Task() task.configuration = aeneas_config task.audio_file_path_absolute = Path(data.audio_filename) task.text_file_path_absolute = Path(data.transcript_filename) # process Task ExecuteTask(task).execute() with open(data.alignment_filename, "w") as f: f.write( orjson.dumps([(str(fragment.begin), str(fragment.end), fragment.text) for fragment in task.sync_map_leaves() if fragment.is_regular]).decode()) except Exception as e: raise HTTPException(status_code=500, detail="Error during processing: " + str(e)) from e
def align_audio( language: LanguageEnum = Form(...), text_file_format: TextFileFormatEnum = Form(...), transcript: UploadFile = File(...), audio: UploadFile = File(...), ): try: # prepare config aeneas_config = TaskConfiguration() aeneas_config[gc.PPN_TASK_IS_TEXT_FILE_FORMAT] = text_file_format aeneas_config[gc.PPN_TASK_LANGUAGE] = language # get named temporary files tmp_audio = convert_to_tempfile(audio) tmp_transcript = convert_to_tempfile(transcript) # create task task = Task() task.configuration = aeneas_config task.audio_file_path_absolute = Path(tmp_audio.name) task.text_file_path_absolute = Path(tmp_transcript.name) # process Task ExecuteTask(task).execute() tmp_audio.close() tmp_transcript.close() return [(str(fragment.begin), str(fragment.end), fragment.text) for fragment in task.sync_map_leaves() if fragment.is_regular] except Exception as e: raise HTTPException(status_code=500, detail="Error during processing: " + str(e)) from e
def setter(self, attribute, value, expected): taskconf = TaskConfiguration() taskconf[attribute] = value read_value = taskconf[attribute] if expected is None: self.assertIsNone(read_value) else: self.assertEqual(read_value, expected)
def tc_from_string(self, config_string, properties): taskconf = TaskConfiguration(config_string) for prop, value in properties: read_value = taskconf[prop] if value is None: self.assertIsNone(read_value) else: self.assertEqual(read_value, value)
def test_output_sync_map(self): task = Task() task.configuration = TaskConfiguration() task.configuration["language"] = Language.ENG task.configuration["o_format"] = SyncMapFormat.TXT task.sync_map = self.dummy_sync_map() handler, output_file_path = gf.tmp_file(suffix=".txt") task.sync_map_file_path_absolute = output_file_path path = task.output_sync_map_file() self.assertIsNotNone(path) self.assertEqual(path, output_file_path) gf.delete_file(handler, output_file_path)
def test_output_sync_map(self): task = Task() task.configuration = TaskConfiguration() task.configuration.language = Language.EN task.configuration.os_file_format = SyncMapFormat.TXT task.sync_map = self.dummy_sync_map() handler, output_file_path = tempfile.mkstemp(suffix=".txt") task.sync_map_file_path_absolute = output_file_path path = task.output_sync_map_file() self.assertNotEqual(path, None) self.assertEqual(path, output_file_path) delete_file(handler, output_file_path)
def align_audio_and_text(self, file_path): config = TaskConfiguration() config[gc.PPN_TASK_LANGUAGE] = Language.PAN config[gc.PPN_TASK_IS_TEXT_FILE_FORMAT] = TextFileFormat.PLAIN config[gc.PPN_TASK_OS_FILE_FORMAT] = SyncMapFormat.JSON task = Task() task.configuration = config task.audio_file_path_absolute = self.audio_file_path task.text_file_path_absolute = self.txt_file_path task.sync_map_file_path_absolute = file_path ExecuteTask(task).execute() task.output_sync_map_file()
def set_text_file(self, path, fmt, expected, id_regex=None, class_regex=None, id_sort=None): task = Task() task.configuration = TaskConfiguration() task.configuration["language"] = Language.ENG task.configuration["i_t_format"] = fmt if class_regex is not None: task.configuration["i_t_unparsed_class_regex"] = class_regex if id_regex is not None: task.configuration["i_t_unparsed_id_regex"] = id_regex if id_sort is not None: task.configuration["i_t_unparsed_id_sort"] = id_sort task.text_file_path_absolute = gf.absolute_path(path, __file__) self.assertIsNotNone(task.text_file) self.assertEqual(len(task.text_file), expected)
def set_text_file(self, path, fmt, expected, id_regex=None, class_regex=None, id_sort=None): task = Task() task.configuration = TaskConfiguration() task.configuration.language = Language.EN task.configuration.is_text_file_format = fmt if id_regex is not None: task.configuration.is_text_unparsed_id_regex = id_regex if class_regex is not None: task.configuration.is_text_unparsed_class_regex = class_regex if id_sort is not None: task.configuration.is_text_unparsed_id_sort = id_sort task.text_file_path_absolute = get_abs_path(path) self.assertNotEqual(task.text_file, None) self.assertEqual(len(task.text_file), expected)
def test_setter_06(self): value = SyncMapFormat.SMIL taskconf = TaskConfiguration() taskconf.os_file_format = value self.assertEqual(taskconf.os_file_format, value)
def test_setter_07(self): value = "output.smil" taskconf = TaskConfiguration() taskconf.os_file_name = value self.assertEqual(taskconf.os_file_name, value)
def test_setter_04(self): value = "20" taskconf = TaskConfiguration() taskconf.is_audio_file_head_length = value self.assertEqual(taskconf.is_audio_file_head_length, value)
def test_setter_05(self): value = "100" taskconf = TaskConfiguration() taskconf.is_audio_file_process_length = value self.assertEqual(taskconf.is_audio_file_process_length, value)
def test_setter_02(self): value = "Test description" taskconf = TaskConfiguration() taskconf.description = value self.assertEqual(taskconf.description, value)
def test_setter_03(self): value = "customid" taskconf = TaskConfiguration() taskconf.custom_id = value self.assertEqual(taskconf.custom_id, value)
def test_config_string_full(self): taskconf = TaskConfiguration() taskconf.language = Language.IT taskconf.description = "Test description" taskconf.custom_id = "customid" taskconf.is_audio_file_head_length = "20" taskconf.is_audio_file_process_length = "100" taskconf.os_file_format = SyncMapFormat.SMIL taskconf.os_file_name = "output.smil" taskconf.os_file_smil_audio_ref = "../audio/audio001.mp3" taskconf.os_file_smil_page_ref = "../text/page001.xhtml" expected = "task_description=Test description|task_language=it|task_custom_id=customid|is_audio_file_head_length=20|is_audio_file_process_length=100|os_task_file_format=smil|os_task_file_name=output.smil|os_task_file_smil_audio_ref=../audio/audio001.mp3|os_task_file_smil_page_ref=../text/page001.xhtml" self.assertEqual(taskconf.config_string(), expected)
def test_task_set_configuration(self): task = Task() taskconf = TaskConfiguration() task.configuration = taskconf self.assertNotEqual(task.configuration, None)
def test_setter_08(self): value = "../audio/audio001.mp3" taskconf = TaskConfiguration() taskconf.os_file_smil_audio_ref = value self.assertEqual(taskconf.os_file_smil_audio_ref, value)
class ExecuteTaskCLI(AbstractCLIProgram): """ Execute a Task, that is, a pair of audio/text files and a configuration string. """ AUDIO_FILE = gf.relative_path("res/audio.mp3", __file__) CTW_ESPEAK = gf.relative_path("../extra/ctw_espeak.py", __file__) CTW_SPEECT = gf.relative_path("../extra/ctw_speect/ctw_speect.py", __file__) DEMOS = { u"--example-aftercurrent": { u"description": u"input: plain text (plain), output: AUD, aba beforenext 0.200", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=aud|task_adjust_boundary_algorithm=aftercurrent|task_adjust_boundary_aftercurrent_value=0.200", u"syncmap": "output/sonnet.aftercurrent0200.aud", u"options": u"", u"show": False }, u"--example-beforenext": { u"description": u"input: plain text (plain), output: AUD, aba beforenext 0.200", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=aud|task_adjust_boundary_algorithm=beforenext|task_adjust_boundary_beforenext_value=0.200", u"syncmap": "output/sonnet.beforenext0200.aud", u"options": u"", u"show": False }, u"--example-cewsubprocess": { u"description": u"input: plain text, output: TSV, run via cewsubprocess", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=tsv", u"syncmap": "output/sonnet.cewsubprocess.tsv", u"options": u"-r=\"cew_subprocess_enabled=True\"", u"show": False }, u"--example-ctw-espeak": { u"description": u"input: plain text, output: TSV, tts engine: ctw espeak", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=tsv", u"syncmap": "output/sonnet.ctw_espeak.tsv", u"options": u"-r=\"tts=custom|tts_path=%s\"" % CTW_ESPEAK, u"show": False }, u"--example-ctw-speect": { u"description": u"input: plain text, output: TSV, tts engine: ctw speect", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=tsv", u"syncmap": "output/sonnet.ctw_speect.tsv", u"options": u"-r=\"tts=custom|tts_path=%s\"" % CTW_SPEECT, u"show": False }, u"--example-eaf": { u"description": u"input: plain text, output: EAF", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=eaf", u"syncmap": "output/sonnet.eaf", u"options": u"", u"show": True }, u"--example-faster-rate": { u"description": u"input: plain text (plain), output: SRT, print faster than 12.0 chars/s", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=srt|task_adjust_boundary_algorithm=rate|task_adjust_boundary_rate_value=12.000", u"syncmap": "output/sonnet.faster.srt", u"options": u"--faster-rate", u"show": False }, u"--example-festival": { u"description": u"input: plain text, output: TSV, tts engine: Festival", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng-USA|is_text_type=plain|os_task_file_format=tsv", u"syncmap": "output/sonnet.festival.tsv", u"options": u"-r=\"tts=festival\"", u"show": False }, u"--example-flatten-12": { u"description": u"input: mplain text (multilevel), output: JSON, levels to output: 1 and 2", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/mplain.txt", __file__), u"config": u"task_language=eng|is_text_type=mplain|os_task_file_format=json|os_task_file_levels=12", u"syncmap": "output/sonnet.flatten12.json", u"options": u"", u"show": False }, u"--example-flatten-2": { u"description": u"input: mplain text (multilevel), output: JSON, levels to output: 2", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/mplain.txt", __file__), u"config": u"task_language=eng|is_text_type=mplain|os_task_file_format=json|os_task_file_levels=2", u"syncmap": "output/sonnet.flatten2.json", u"options": u"", u"show": False }, u"--example-flatten-3": { u"description": u"input: mplain text (multilevel), output: JSON, levels to output: 3", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/mplain.txt", __file__), u"config": u"task_language=eng|is_text_type=mplain|os_task_file_format=json|os_task_file_levels=3", u"syncmap": "output/sonnet.flatten3.json", u"options": u"", u"show": False }, u"--example-head-tail": { u"description": u"input: plain text, output: TSV, explicit head and tail", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=tsv|is_audio_file_head_length=0.400|is_audio_file_tail_length=0.500|os_task_file_head_tail_format=stretch", u"syncmap": "output/sonnet.headtail.tsv", u"options": u"", u"show": False }, u"--example-json": { u"description": u"input: plain text, output: JSON", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=json", u"syncmap": "output/sonnet.json", u"options": u"", u"show": True }, u"--example-mplain-json": { u"description": u"input: multilevel plain text (mplain), output: JSON", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/mplain.txt", __file__), u"config": u"task_language=eng|is_text_type=mplain|os_task_file_format=json", u"syncmap": "output/sonnet.mplain.json", u"options": u"", u"show": False }, u"--example-mplain-smil": { u"description": u"input: multilevel plain text (mplain), output: SMIL", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/mplain.txt", __file__), u"config": u"task_language=eng|is_text_type=mplain|os_task_file_format=smil|os_task_file_smil_audio_ref=p001.mp3|os_task_file_smil_page_ref=p001.xhtml", u"syncmap": "output/sonnet.mplain.smil", u"options": u"", u"show": True }, u"--example-multilevel-tts": { u"description": u"input: multilevel plain text (mplain), different TTS engines, output: JSON", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/mplain.txt", __file__), u"config": u"task_language=eng-USA|is_text_type=mplain|os_task_file_format=json", u"syncmap": "output/sonnet.mplain.json", u"options": u"-r=\"tts_l1=festival|tts_l2=festival|tts_l3=espeak\"", u"show": False }, u"--example-munparsed-json": { u"description": u"input: multilevel unparsed text (munparsed), output: JSON", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/munparsed2.xhtml", __file__), u"config": u"task_language=eng|is_text_type=munparsed|is_text_munparsed_l1_id_regex=p[0-9]+|is_text_munparsed_l2_id_regex=s[0-9]+|is_text_munparsed_l3_id_regex=w[0-9]+|os_task_file_format=json", u"syncmap": "output/sonnet.munparsed.json", u"options": u"", u"show": False }, u"--example-munparsed-smil": { u"description": u"input: multilevel unparsed text (munparsed), output: SMIL", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/munparsed.xhtml", __file__), u"config": u"task_language=eng|is_text_type=munparsed|is_text_munparsed_l1_id_regex=p[0-9]+|is_text_munparsed_l2_id_regex=p[0-9]+s[0-9]+|is_text_munparsed_l3_id_regex=p[0-9]+s[0-9]+w[0-9]+|os_task_file_format=smil|os_task_file_smil_audio_ref=p001.mp3|os_task_file_smil_page_ref=p001.xhtml", u"syncmap": "output/sonnet.munparsed.smil", u"options": u"", u"show": True }, u"--example-mws": { u"description": u"input: plain text, output: JSON, resolution: 0.500 s", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=json", u"syncmap": "output/sonnet.mws.json", u"options": u"-r=\"mfcc_window_length=1.500|mfcc_window_shift=0.500\"", u"show": False }, u"--example-no-zero": { u"description": u"input: multilevel plain text (mplain), output: JSON, no zero duration", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/mplain.txt", __file__), u"config": u"task_language=eng|is_text_type=mplain|os_task_file_format=json|task_adjust_boundary_no_zero=True", u"syncmap": "output/sonnet.nozero.json", u"options": u"--zero", u"show": False }, u"--example-offset": { u"description": u"input: plain text (plain), output: AUD, aba offset 0.200", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=aud|task_adjust_boundary_algorithm=offset|task_adjust_boundary_offset_value=0.200", u"syncmap": "output/sonnet.offset0200.aud", u"options": u"", u"show": False }, u"--example-percent": { u"description": u"input: plain text (plain), output: AUD, aba percent 50", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=aud|task_adjust_boundary_algorithm=percent|task_adjust_boundary_percent_value=50", u"syncmap": "output/sonnet.percent50.aud", u"options": u"", u"show": False }, u"--example-py": { u"description": u"input: plain text, output: JSON, pure python", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=json", u"syncmap": "output/sonnet.cext.json", u"options": u"-r=\"c_extensions=False\"", u"show": False }, u"--example-rate": { u"description": u"input: plain text (plain), output: SRT, max rate 14.0 chars/s, print rates", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=srt|task_adjust_boundary_algorithm=rate|task_adjust_boundary_rate_value=14.000", u"syncmap": "output/sonnet.rates.srt", u"options": u"--rate", u"show": False }, u"--example-remove-nonspeech": { u"description": u"input: plain text (plain), output: SRT, remove nonspeech >=0.500 s", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=srt|task_adjust_boundary_nonspeech_min=0.500|task_adjust_boundary_nonspeech_string=REMOVE", u"syncmap": "output/sonnet.remove.nonspeech.srt", u"options": u"", u"show": False }, u"--example-remove-nonspeech-rateaggressive": { u"description": u"input: plain text (plain), output: SRT, remove nonspeech >=0.500 s, max rate 14.0 chars/s, print rates", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=srt|task_adjust_boundary_nonspeech_min=0.500|task_adjust_boundary_nonspeech_string=REMOVE|task_adjust_boundary_algorithm=rateaggressive|task_adjust_boundary_rate_value=14.000", u"syncmap": "output/sonnet.remove.nonspeech.rateaggressive.srt", u"options": u"--rate", u"show": False }, u"--example-replace-nonspeech": { u"description": u"input: plain text (plain), output: AUD, replace nonspeech >=0.500 s with (sil)", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=aud|task_adjust_boundary_nonspeech_min=0.500|task_adjust_boundary_nonspeech_string=(sil)", u"syncmap": "output/sonnet.sil.aud", u"options": u"", u"show": False }, u"--example-sd": { u"description": u"input: plain text, output: TSV, head/tail detection", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=tsv|is_audio_file_detect_head_max=10.000|is_audio_file_detect_tail_max=10.000", u"syncmap": "output/sonnet.sd.tsv", u"options": u"", u"show": False }, u"--example-srt": { u"description": u"input: subtitles text, output: SRT", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/subtitles.txt", __file__), u"config": u"task_language=eng|is_text_type=subtitles|os_task_file_format=srt", u"syncmap": "output/sonnet.srt", u"options": u"", u"show": True }, u"--example-smil": { u"description": u"input: unparsed text, output: SMIL", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/page.xhtml", __file__), u"config": u"task_language=eng|is_text_type=unparsed|is_text_unparsed_id_regex=f[0-9]+|is_text_unparsed_id_sort=numeric|os_task_file_format=smil|os_task_file_smil_audio_ref=p001.mp3|os_task_file_smil_page_ref=p001.xhtml", u"syncmap": "output/sonnet.smil", u"options": u"", u"show": True }, u"--example-textgrid": { u"description": u"input: parsed text, output: TextGrid", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/parsed.txt", __file__), u"config": u"task_language=eng|is_text_type=parsed|os_task_file_format=textgrid", u"syncmap": "output/sonnet.textgrid", u"options": u"", u"show": True }, u"--example-tsv": { u"description": u"input: parsed text, output: TSV", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/parsed.txt", __file__), u"config": u"task_language=eng|is_text_type=parsed|os_task_file_format=tsv", u"syncmap": "output/sonnet.tsv", u"options": u"", u"show": True }, u"--example-words": { u"description": u"input: single word granularity plain text, output: AUD", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/words.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=aud", u"syncmap": "output/sonnet.words.aud", u"options": u"", u"show": True }, u"--example-words-multilevel": { u"description": u"input: mplain text (multilevel), output: AUD, levels to output: 3", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/mplain.txt", __file__), u"config": u"task_language=eng|is_text_type=mplain|os_task_file_format=aud|os_task_file_levels=3", u"syncmap": "output/sonnet.words.multilevel.aud", u"options": u"", u"show": False }, u"--example-words-festival-cache": { u"description": u"input: single word granularity plain text, output: AUD, tts engine: Festival, TTS cache on", u"audio": AUDIO_FILE, u"text": gf.relative_path("res/words.txt", __file__), u"config": u"task_language=eng-USA|is_text_type=plain|os_task_file_format=aud", u"syncmap": "output/sonnet.words.aud", u"options": u"-r=\"tts=festival|tts_cache=True\"", u"show": False }, u"--example-youtube": { u"description": u"input: audio from YouTube, output: TXT", u"audio": "https://www.youtube.com/watch?v=rU4a7AA8wM0", u"text": gf.relative_path("res/plain.txt", __file__), u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=txt", u"syncmap": "output/sonnet.txt", u"options": u"-y", u"show": True } } PARAMETERS = TaskConfiguration.parameters(sort=True, as_strings=True) VALUES = { "aws": AWSTTSWrapper.CODE_TO_HUMAN_LIST, "espeak": ESPEAKTTSWrapper.CODE_TO_HUMAN_LIST, "espeak-ng": ESPEAKNGTTSWrapper.CODE_TO_HUMAN_LIST, "festival": FESTIVALTTSWrapper.CODE_TO_HUMAN_LIST, "macos": MacOSTTSWrapper.CODE_TO_HUMAN_LIST, "nuance": NuanceTTSWrapper.CODE_TO_HUMAN_LIST, "task_language": Language.CODE_TO_HUMAN_LIST, "is_text_type": TextFileFormat.ALLOWED_VALUES, "is_text_unparsed_id_sort": IDSortingAlgorithm.ALLOWED_VALUES, "os_task_file_format": SyncMapFormat.ALLOWED_VALUES, "os_task_file_head_tail_format": SyncMapHeadTailFormat.ALLOWED_VALUES, "task_adjust_boundary_algorithm": AdjustBoundaryAlgorithm.ALLOWED_VALUES, } NAME = gf.file_name_without_extension(__file__) HELP = { "description": u"Execute a Task.", "synopsis": [ (u"--list-parameters", False), (u"--list-values[=PARAM]", False), (u"AUDIO_FILE TEXT_FILE CONFIG_STRING OUTPUT_FILE", True), (u"YOUTUBE_URL TEXT_FILE CONFIG_STRING OUTPUT_FILE -y", True), ], "examples": [u"--examples", u"--examples-all"], "options": [ u"--faster-rate : print fragments with rate > task_adjust_boundary_rate_value", u"--keep-audio : do not delete the audio file downloaded from YouTube (-y only)", u"--largest-audio : download largest audio stream (-y only)", u"--list-parameters : list all parameters", u"--list-values : list all parameters for which values can be listed", u"--list-values=PARAM : list all allowed values for parameter PARAM", u"--output-html : output HTML file for fine tuning", u"--presets-word : apply presets for word-level alignment (MFCC masking)", u"--rate : print rate of each fragment", u"--skip-validator : do not validate the given config string", u"--zero : print fragments with zero duration", u"-y, --youtube : download audio from YouTube video", ] } def perform_command(self): """ Perform command and return the appropriate exit code. :rtype: int """ if len(self.actual_arguments) < 1: return self.print_help() if self.has_option([u"-e", u"--examples"]): return self.print_examples(False) if self.has_option(u"--examples-all"): return self.print_examples(True) if self.has_option([u"--list-parameters"]): return self.print_parameters() parameter = self.has_option_with_value(u"--list-values") if parameter is not None: return self.print_values(parameter) elif self.has_option(u"--list-values"): return self.print_values(u"?") # NOTE list() is needed for Python3, where keys() is not a list! demo = self.has_option(list(self.DEMOS.keys())) demo_parameters = u"" download_from_youtube = self.has_option([u"-y", u"--youtube"]) largest_audio = self.has_option(u"--largest-audio") keep_audio = self.has_option(u"--keep-audio") output_html = self.has_option(u"--output-html") validate = not self.has_option(u"--skip-validator") print_faster_rate = self.has_option(u"--faster-rate") print_rates = self.has_option(u"--rate") print_zero = self.has_option(u"--zero") presets_word = self.has_option(u"--presets-word") if demo: validate = False for key in self.DEMOS: if self.has_option(key): demo_parameters = self.DEMOS[key] audio_file_path = demo_parameters[u"audio"] text_file_path = demo_parameters[u"text"] config_string = demo_parameters[u"config"] sync_map_file_path = demo_parameters[u"syncmap"] # TODO allow injecting rconf options directly from DEMOS options field if key == u"--example-cewsubprocess": self.rconf[ RuntimeConfiguration.CEW_SUBPROCESS_ENABLED] = True elif key == u"--example-ctw-espeak": self.rconf[RuntimeConfiguration.TTS] = "custom" self.rconf[ RuntimeConfiguration.TTS_PATH] = self.CTW_ESPEAK elif key == u"--example-ctw-speect": self.rconf[RuntimeConfiguration.TTS] = "custom" self.rconf[ RuntimeConfiguration.TTS_PATH] = self.CTW_SPEECT elif key == u"--example-festival": self.rconf[RuntimeConfiguration.TTS] = "festival" elif key == u"--example-mws": self.rconf[ RuntimeConfiguration.MFCC_WINDOW_LENGTH] = "1.500" self.rconf[ RuntimeConfiguration.MFCC_WINDOW_SHIFT] = "0.500" elif key == u"--example-multilevel-tts": self.rconf[RuntimeConfiguration.TTS_L1] = "festival" self.rconf[RuntimeConfiguration.TTS_L2] = "festival" self.rconf[RuntimeConfiguration.TTS_L3] = "espeak" elif key == u"--example-words-festival-cache": self.rconf[RuntimeConfiguration.TTS] = "festival" self.rconf[RuntimeConfiguration.TTS_CACHE] = True elif key == u"--example-faster-rate": print_faster_rate = True elif key == u"--example-no-zero": print_zero = True elif key == u"--example-py": self.rconf[RuntimeConfiguration.C_EXTENSIONS] = False elif key == u"--example-rate": print_rates = True elif key == u"--example-remove-nonspeech-rateaggressive": print_rates = True elif key == u"--example-youtube": download_from_youtube = True break else: if len(self.actual_arguments) < 4: return self.print_help() audio_file_path = self.actual_arguments[0] text_file_path = self.actual_arguments[1] config_string = self.actual_arguments[2] sync_map_file_path = self.actual_arguments[3] if presets_word: self.print_info(u"Preset for word-level alignment") self.rconf[RuntimeConfiguration.MFCC_MASK_NONSPEECH] = True self.rconf[RuntimeConfiguration.MFCC_MASK_NONSPEECH_L3] = True html_file_path = None if output_html: keep_audio = True html_file_path = sync_map_file_path + u".html" if download_from_youtube: youtube_url = gf.safe_unicode(audio_file_path) if (not download_from_youtube) and ( not self.check_input_file(audio_file_path)): return self.ERROR_EXIT_CODE if not self.check_input_file(text_file_path): return self.ERROR_EXIT_CODE if not self.check_output_file(sync_map_file_path): return self.ERROR_EXIT_CODE if (html_file_path is not None) and (not self.check_output_file(html_file_path)): return self.ERROR_EXIT_CODE self.check_c_extensions() if demo: msg = [] msg.append(u"Running example task with arguments:") if download_from_youtube: msg.append(u" YouTube URL: %s" % youtube_url) else: msg.append(u" Audio file: %s" % audio_file_path) msg.append(u" Text file: %s" % text_file_path) msg.append(u" Config string: %s" % config_string) msg.append(u" Sync map file: %s" % sync_map_file_path) if len(demo_parameters[u"options"]) > 0: msg.append(u" Options: %s" % demo_parameters[u"options"]) self.print_info(u"\n".join(msg)) if validate: self.print_info( u"Validating config string (specify --skip-validator to bypass)..." ) validator = Validator(logger=self.logger) result = validator.check_configuration_string(config_string, is_job=False, external_name=True) if not result.passed: self.print_error(u"The given config string is not valid:") self.print_generic(result.pretty_print()) return self.ERROR_EXIT_CODE self.print_info(u"Validating config string... done") if download_from_youtube: try: self.print_info(u"Downloading audio from '%s' ..." % youtube_url) downloader = Downloader(logger=self.logger) audio_file_path = downloader.audio_from_youtube( youtube_url, download=True, output_file_path=None, largest_audio=largest_audio) self.print_info(u"Downloading audio from '%s' ... done" % youtube_url) except ImportError: self.print_no_dependency_error() return self.ERROR_EXIT_CODE except Exception as exc: self.print_error( u"An unexpected error occurred while downloading audio from YouTube:" ) self.print_error(u"%s" % exc) return self.ERROR_EXIT_CODE else: audio_extension = gf.file_extension(audio_file_path) if audio_extension.lower() not in AudioFile.FILE_EXTENSIONS: self.print_warning( u"Your audio file path has extension '%s', which is uncommon for an audio file." % audio_extension) self.print_warning( u"Attempting at executing your Task anyway.") self.print_warning( u"If it fails, you might have swapped the first two arguments." ) self.print_warning( u"The audio file path should be the first argument, the text file path the second." ) try: self.print_info(u"Creating task...") task = Task(config_string, logger=self.logger) task.audio_file_path_absolute = audio_file_path task.text_file_path_absolute = text_file_path task.sync_map_file_path_absolute = sync_map_file_path self.print_info(u"Creating task... done") except Exception as exc: self.print_error( u"An unexpected error occurred while creating the task:") self.print_error(u"%s" % exc) return self.ERROR_EXIT_CODE try: self.print_info(u"Executing task...") executor = ExecuteTask(task=task, rconf=self.rconf, logger=self.logger) executor.execute() self.print_info(u"Executing task... done") except Exception as exc: self.print_error( u"An unexpected error occurred while executing the task:") self.print_error(u"%s" % exc) return self.ERROR_EXIT_CODE try: self.print_info(u"Creating output sync map file...") path = task.output_sync_map_file() self.print_info(u"Creating output sync map file... done") self.print_success(u"Created file '%s'" % path) except Exception as exc: self.print_error( u"An unexpected error occurred while writing the sync map file:" ) self.print_error(u"%s" % exc) return self.ERROR_EXIT_CODE if output_html: try: parameters = {} parameters[gc.PPN_TASK_OS_FILE_FORMAT] = task.configuration[ "o_format"] parameters[ gc.PPN_TASK_OS_FILE_EAF_AUDIO_REF] = task.configuration[ "o_eaf_audio_ref"] parameters[ gc.PPN_TASK_OS_FILE_SMIL_AUDIO_REF] = task.configuration[ "o_smil_audio_ref"] parameters[ gc.PPN_TASK_OS_FILE_SMIL_PAGE_REF] = task.configuration[ "o_smil_page_ref"] self.print_info(u"Creating output HTML file...") task.sync_map.output_html_for_tuning(audio_file_path, html_file_path, parameters) self.print_info(u"Creating output HTML file... done") self.print_success(u"Created file '%s'" % html_file_path) except Exception as exc: self.print_error( u"An unexpected error occurred while writing the HTML file:" ) self.print_error(u"%s" % exc) return self.ERROR_EXIT_CODE if download_from_youtube: if keep_audio: self.print_info( u"Option --keep-audio set: keeping downloaded file '%s'" % audio_file_path) else: gf.delete_file(None, audio_file_path) if print_zero: zero_duration = [ l for l in task.sync_map_leaves(SyncMapFragment.REGULAR) if l.begin == l.end ] if len(zero_duration) > 0: self.print_warning(u"Fragments with zero duration:") for fragment in zero_duration: self.print_generic(u" %s" % (fragment.pretty_print)) if print_rates: self.print_info(u"Fragments with rates:") for fragment in task.sync_map_leaves(SyncMapFragment.REGULAR): self.print_generic( u" %s\t%.3f" % (fragment.pretty_print, fragment.rate or 0.0)) if print_faster_rate: max_rate = task.configuration["aba_rate_value"] if max_rate is not None: faster = [ l for l in task.sync_map_leaves(SyncMapFragment.REGULAR) if l.rate >= max_rate + Decimal("0.001") ] if len(faster) > 0: self.print_warning( u"Fragments with rate greater than %.3f:" % max_rate) for fragment in faster: self.print_generic( u" %s\t%.3f" % (fragment.pretty_print, fragment.rate or 0.0)) return self.NO_ERROR_EXIT_CODE def print_examples(self, full=False): """ Print the examples and exit. :param bool full: if ``True``, print all examples; otherwise, print only selected ones """ msg = [] i = 1 for key in sorted(self.DEMOS.keys()): example = self.DEMOS[key] if full or example["show"]: msg.append(u"Example %d (%s)" % (i, example[u"description"])) msg.append(u" $ %s %s" % (self.invoke, key)) msg.append(u"") i += 1 self.print_generic(u"\n" + u"\n".join(msg) + u"\n") return self.HELP_EXIT_CODE def print_parameters(self): """ Print the list of parameters and exit. """ self.print_info( u"You can use --list-values=PARAM on parameters marked by '*'") self.print_info(u"Parameters marked by 'REQ' are required") self.print_info(u"Available parameters:") self.print_generic(u"\n" + u"\n".join(self.PARAMETERS) + u"\n") return self.HELP_EXIT_CODE def print_values(self, parameter): """ Print the list of values for the given parameter and exit. If ``parameter`` is invalid, print the list of parameter names that have allowed values. :param parameter: the parameter name :type parameter: Unicode string """ if parameter in self.VALUES: self.print_info(u"Available values for parameter '%s':" % parameter) self.print_generic(u"\n".join(self.VALUES[parameter])) return self.HELP_EXIT_CODE if parameter not in [u"?", u""]: self.print_error(u"Invalid parameter name '%s'" % parameter) self.print_info(u"Parameters for which values can be listed:") self.print_generic(u"\n".join(sorted(self.VALUES.keys()))) return self.HELP_EXIT_CODE
#!/usr/bin/env python # coding=utf-8 from aeneas.exacttiming import TimeValue from aeneas.executetask import ExecuteTask from aeneas.language import Language from aeneas.syncmap import SyncMapFormat from aeneas.task import Task from aeneas.task import TaskConfiguration from aeneas.textfile import TextFileFormat import aeneas.globalconstants as gc # create Task object config = TaskConfiguration() # config[gc.PPN_TASK_LANGUAGE] = Language.ENG config[gc.PPN_TASK_IS_TEXT_FILE_FORMAT] = TextFileFormat.MPLAIN config[gc.PPN_TASK_OS_FILE_FORMAT] = SyncMapFormat.JSON task = Task() def get_align(audio_file, text_file, lang): if lang == 'FRA': config[gc.PPN_TASK_LANGUAGE] = Language.FRA elif lang == 'ARA': config[gc.PPN_TASK_LANGUAGE] = Language.ARA elif lang == 'DEU': config[gc.PPN_TASK_LANGUAGE] = Language.DEU elif lang == 'CMN': config[gc.PPN_TASK_LANGUAGE] = Language.CMN else: config[gc.PPN_TASK_LANGUAGE] = Language.ENG
def test_tc_config_string(self): taskconf = TaskConfiguration() taskconf.language = Language.IT taskconf.description = "Test description" taskconf.custom_id = "customid" taskconf.is_audio_file_head_length = "20" taskconf.is_audio_file_process_length = "100" taskconf.os_file_format = SyncMapFormat.SMIL taskconf.os_file_name = "output.smil" taskconf.os_file_smil_audio_ref = "../audio/audio001.mp3" taskconf.os_file_smil_page_ref = "../text/page001.xhtml" expected = "task_description=Test description|task_language=it|task_custom_id=customid|is_audio_file_head_length=20|is_audio_file_process_length=100|os_task_file_format=smil|os_task_file_name=output.smil|os_task_file_smil_audio_ref=../audio/audio001.mp3|os_task_file_smil_page_ref=../text/page001.xhtml" self.assertEqual(taskconf.config_string(), expected)
def test_task_set_configuration(self): task = Task() taskconf = TaskConfiguration() task.configuration = taskconf self.assertIsNotNone(task.configuration)
def test_setter_09(self): value = "../text/page001.xhtml" taskconf = TaskConfiguration() taskconf.os_file_smil_page_ref = value self.assertEqual(taskconf.os_file_smil_page_ref, value)
def test_setter_01(self): value = Language.IT taskconf = TaskConfiguration() taskconf.language = value self.assertEqual(taskconf.language, value)
def setter(self, attribute, value): taskconf = TaskConfiguration() setattr(taskconf, attribute, value) self.assertEqual(getattr(taskconf, attribute), value)
def tc_from_string(self, config_string, properties): taskconf = TaskConfiguration(config_string) for prop in properties: self.assertEqual(getattr(taskconf, prop[0]), prop[1])