Esempio n. 1
0
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
Esempio n. 2
0
 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)
Esempio n. 3
0
 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)
Esempio n. 4
0
def force_align(audio_path,
                text_path,
                output_path,
                min_length=1.0,
                max_length=10.0,
                logging=logging):
    sentences = []
    task = Task(
        config_string=
        u"task_language=eng|is_text_type=plain|os_task_file_format=json")
    task.audio_file_path_absolute = audio_path
    task.text_file_path_absolute = text_path
    task.sync_map_file_path_absolute = output_path
    logging.info("Aligning audio and text...")
    ExecuteTask(task).execute()
    logging.info("Aligned audio and text")

    for fragment in task.sync_map_leaves():
        if fragment.length > min_length and fragment.length < max_length and fragment.text:
            sentences.append({
                "start": float(fragment.begin),
                "end": float(fragment.end),
                "length": float(fragment.length),
                "text": fragment.text,
            })

    with open(output_path, "w") as f:
        json.dump(sentences, f, indent=4)
Esempio n. 5
0
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
Esempio n. 6
0
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)
Esempio n. 7
0
def chopsounds():
    # create Task object
    config_string = u"task_language=eng|is_text_type=plain|os_task_file_format=json"
    task = Task(config_string=config_string)
    task.audio_file_path_absolute = inputsound
    task.text_file_path_absolute = inputtext

    # process Task
    ExecuteTask(task).execute()

    # Carve wav file into fragments
    sound = AudioSegment.from_wav(inputsound)
    for fragment in task.sync_map_leaves():
        if fragment.length > 0.0:
            fsound = sound[float(fragment.begin) * 1000:float(fragment.end) *
                           1000]
            fsound.export(outputdir + "/" + fragment.identifier + ".wav",
                          format="wav")
Esempio n. 8
0
def retrieve_keyword_audio(vid, keyword):
    audio_index = 0
    v_url = URL_TEMPLATE.format(vid)
    youtube = YouTube(v_url)
    y_len = youtube.player_config_args['player_response']['videoDetails']['lengthSeconds'] 
    print("Length :",y_len)
    print("Views  :",youtube.views) 

    if int(y_len) > 2700:
        # only consider video < 45 mins
        return audio_index
    print("="*40)
    caption = youtube.captions.get_by_language_code('ko')
    
    if caption:
        print("caption==ko")
        # retrieve audio from video
        youtube.streams.first().download(output_path=TEMP_DIR, filename=vid)

        temp_file_name = TEMP_DIR+vid
        if not os.path.isfile(temp_file_name + ".mp4"):
            return audio_index

        time.sleep(1) # need to wait before ffmpeg takes in as input file
        cmd = FFMPEG_TEMPLATE.format(temp_file_name).split()
        subprocess.check_output(cmd)

        audio = librosa.core.load(temp_file_name+".wav", 16000)[0]

        os.remove(temp_file_name + ".mp4")
        os.remove(temp_file_name + ".wav")

        formatted_vid = vid.replace('_', '-')

        cc_arr = caption.generate_srt_captions().split('\n\n')
        for captions in cc_arr:
            cc_split = captions.split('\n')
            if len(cc_split) == 4 and cc_split[0] == '':
                cc_split = (cc_split[1], cc_split[2], cc_split[3])
            elif len(cc_split) != 3:
                continue

            _, cc_time, cc_text = cc_split
            cc_text = TAG_CLEANER.sub('', cc_text)

            # clean up punctuation
            cc_text = cc_text.translate(TRANSPLATOR)

            cc_text = cc_text.lower()
            words = cc_text.strip().split()

            # steming words
            if keyword not in words and keyword + "s" not in words and keyword + "es" not in words:
                continue

            aligner_task = Task(config_string=ALIGNER_CONFIG_STRING)

            # prepare label file for forced aligner

            label_file = temp_file_name + "_" + keyword + ".txt"
            with open(label_file, "w+") as file:
                for word in words:
                    file.write(word+"\n")

            # prepare audio file for forced aligner

            match_result = SRT_TIME_PARSER.match(cc_time)
            if match_result:
                start_time_ms = srt_time_to_ms(
                    match_result.group(1),
                    match_result.group(2),
                    match_result.group(3),
                    match_result.group(4))
                stop_time_ms = srt_time_to_ms(
                    match_result.group(5),
                    match_result.group(6),
                    match_result.group(7),
                    match_result.group(8))

                start_pos = start_time_ms * 16
                stop_pos = stop_time_ms * 16

                block = audio[start_pos:stop_pos] # *16 since 16 samples are captured per each ms

                # temporary audio file for forced aligner
                audio_file = temp_file_name + "_" + keyword + ".wav"
                librosa.output.write_wav(audio_file, block, 16000)
                time.sleep(1) # buffer for writing wav file

            else:
                print(TEXT_COLOUR['FAIL'] + "failed pasing srt time : "
                      + cc_time + TEXT_COLOUR['ENDC'])
                raise Exception('srt time fail error')

            aligner_task.text_file_path_absolute = label_file
            aligner_task.audio_file_path_absolute = audio_file

            # process aligning task
            ExecuteTask(aligner_task).execute()

            for fragment in aligner_task.sync_map_leaves():
                if fragment.is_regular and keyword in fragment.text and fragment.length < 0.9:
                    begin = int(fragment.begin * 16000)
                    end = int(fragment.end * 16000)
                    keyword_audio = pad_and_center_align(block[begin:end], 16000)

                    file_name = keyword+"_"+str(audio_index)+".wav"
                    librosa.output.write_wav(
                        DATA_DIR + "/" + keyword + "/" + file_name, keyword_audio, 16000)
                    audio_index += 1
    return audio_index
Esempio n. 9
0
 def test_task_sync_map_leaves_empty(self):
     task = Task()
     self.assertEqual(len(task.sync_map_leaves()), 0)
Esempio n. 10
0
 def test_task_sync_map_leaves_empty(self):
     task = Task()
     self.assertEqual(len(task.sync_map_leaves()), 0)
Esempio n. 11
0
def create_aeneas_csv(df=input_df,
                      book_chapter_list=book_chapter_list,
                      input_audio_dir=input_audio_dir):
    for each_chapter in book_chapter_list:

        #Find respective audio file
        if len(each_chapter.split('_')) == 3:
            sequence = re.findall(r'\d+', each_chapter.split('_')[0])[0]

            if each_chapter.split('_')[1] == 'THESSALONIANS': book = 'Thess'
            else: book = (each_chapter.split('_')[1]).capitalize()

            chapter = each_chapter.split('_')[2]
            find_audio_string = chapter + '_' + sequence + book

            search_book = ' '.join(each_chapter.split('_')[0:2])
        else:
            if each_chapter.split('_')[1] == 'THESSALONIANS': book = 'Thess'
            else:
                book = (each_chapter.split('_')[0]).capitalize()
                search_book = each_chapter.split('_')[0]

            chapter = each_chapter.split('_')[1]
            find_audio_string = chapter + '_' + book

        if sound_find_string is not None:
            #find_audio_string=chapter+'_'+sound_find_string
            find_audio_string = sound_find_string + '_' + chapter
            if language_code == 'en':
                find_audio_string = chapter + '_' + sound_find_string

        print(find_audio_string)
        chapter_audio = glob.glob(input_audio_dir + '/*' + find_audio_string +
                                  '*')[0]
        if not (chapter_audio): missing_chapters.append(each_chapter)

        #Create aeneas text input
        aeneas_file_name = (
            chapter_audio.split('/')[-1]).split('.')[0] + '_aeneas_input.txt'
        aeneas_write = codecs.open(output_dir + '/' + aeneas_file_name, 'w',
                                   'utf-8')
        chapter = chapter.lstrip('0')

        for i in range(0, len(df)):
            if ((str(df['book'][i])).strip()
                ).upper() == search_book.upper() and int(
                    df['chapter'][i]) == int(chapter):
                aeneas_write.write(df['verse_content'][i] + '\n')
        aeneas_write.close()

        #Run aeneas
        from aeneas.executetask import ExecuteTask
        from aeneas.task import Task
        from aeneas.tools.execute_task import ExecuteTaskCLI

        # create Task object
        aeneas_output_file = (
            chapter_audio.split('/')[-1]).split('.')[0] + '_aeneas_out.txt'
        config_string = u"task_adjust_boundary_percent_value=50|task_adjust_boundary_nonspeech_min=0.4|task_language=epo|is_text_type=plain|os_task_file_format=aud"
        print(config_string)

        # Save .txt file
        ExecuteTaskCLI(use_sys=False).run(arguments=[
            None,  # dummy program name argument
            chapter_audio,
            os.path.join(output_dir, aeneas_file_name),
            config_string,
            os.path.join(output_dir, aeneas_output_file)
        ])

        # Save time boundary
        task = Task(config_string=config_string)
        task.audio_file_path_absolute = chapter_audio
        task.text_file_path_absolute = os.path.join(output_dir,
                                                    aeneas_file_name)
        task.sync_map_file_path_absolute = os.path.join(
            output_dir, aeneas_output_file)

        index_list = list()
        # process Task
        ExecuteTask(task).execute()

        new_aeneas = list()
        with open(output_dir + '/' + aeneas_output_file, 'r') as a:
            with open(output_dir + '/' + 'new' + aeneas_output_file, 'w') as b:
                for line in a:
                    if not (line.__contains__('......')):
                        #print(line)
                        b.write(line)
                        # new_aeneas.append(line)
        a.close()
        b.close()

        # with open(output_dir+'/'+'new'+aeneas_output_file,'w') as b:
        #     b.write(str(new_aeneas))
        # b.close()

        shutil.move(output_dir + '/new' + aeneas_output_file,
                    output_dir + '/' + aeneas_output_file)

        last = len(task.sync_map_leaves())
        for i, time in enumerate(task.sync_map_leaves()):
            if 0 < i < last - 1:
                index_list.append(time.end)
                # print(time.end)

        inc = 0
        verse_list = list()
        for i in range(0, len(df)):
            if ((str(df['book'][i])).strip()
                ).upper() == search_book.upper() and int(
                    df['chapter'][i]) == int(chapter):
                write_file.writerow(
                    (df['fileset'][i], df['book'][i], df['chapter'][i],
                     df['line_number'][i], df['verse_number'][i],
                     df['verse_content'][i], index_list[inc]))
                verse_list.append(df['verse_number'][i])
                inc += 1

        print(chapter_audio)

        if args.move_adjustment:
            silence_file = output_dir + '/' + (aeneas_output_file.split(
                '/')[-1]).split('.')[0] + '_silence.txt'
            extract_silence_intervals(chapter_audio, silence_file)
            adjust_update_boundaries_with_silence(
                output_dir + '/' + aeneas_output_file,
                silence_file,
                output_dir + '/' +
                (chapter_audio.split('/')[-1]).split('.')[0] +
                '_sync_adjusted.txt',
                verse_list,
                input_split_field='\t',
                output_split_field='\t')

        elif args.adjust_silence:
            silence_file = output_dir + '/' + (aeneas_output_file.split(
                '/')[-1]).split('.')[0] + '_silence.txt'
            extract_silence_intervals(chapter_audio, silence_file)
            adjust_boundaries_with_silence(
                output_dir + '/' + aeneas_output_file,
                silence_file,
                output_dir + '/' +
                (chapter_audio.split('/')[-1]).split('.')[0] + '_adjusted.txt',
                verse_list,
                input_split_field='\t',
                output_split_field='\t')

    write_file_handle.close()

    if missing_chapters:
        with open(output_dir + '/missing_chapters.txt', 'w',
                  encoding='utf-8') as missing:
            for each_missing in missing_chapters:
                missing.write(each_missing)
            missing.close()
Esempio n. 12
0
    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 create_aeneas_csv(df=input_df,
                      book_chapter_list=book_chapter_list,
                      input_audio_dir=input_audio_dir):

    try:
        for each_chapter in book_chapter_list:

            search_book = each_chapter.split('_')[0]
            chapter = each_chapter.split('_')[1]
            book1 = each_chapter.split('_')[0]

            if (book1[0]).isdigit():
                book = book1[0] + (book1[1:])
            else:
                book = book1

            print(book, chapter)

            map_book_df = pd.read_csv(book_to_audio_map)
            #print(sys.path[0],file_name)
            audio_book_id = (map_book_df[(
                map_book_df.iloc[:, 0].str).contains(book) == True].iloc[0, 1])

            if int(audio_book_id) < 10:
                audio_book_id = '0' + str(audio_book_id)
            else:
                audio_book_id = str(audio_book_id)

            find_audio_string = audio_book_id + '*' + chapter

            print(find_audio_string)
            chapter_audio = glob.glob(input_audio_dir + '/*' +
                                      find_audio_string + '*.mp3')[0]

            if not (chapter_audio): missing_chapters.append(each_chapter)

            #Create aeneas text input
            aeneas_file_name = (chapter_audio.split('/')[-1]
                                ).split('.')[0] + '_aeneas_input.txt'
            aeneas_write = codecs.open(output_dir + '/' + aeneas_file_name,
                                       'w', 'utf-8')
            chapter = chapter.lstrip('0')

            for i in range(0, len(df)):
                if (((str(df['book'][i])).strip()).upper()).replace(
                        ' ', '') == search_book.upper() and int(
                            df['chapter'][i]) == int(chapter):
                    aeneas_write_string = ''.join(
                        (filter(lambda i: i not in remove_chars_list,
                                str(df['verse_content'][i]))))
                    aeneas_write.write(aeneas_write_string + '\n')
            aeneas_write.close()

            #Run aeneas
            from aeneas.executetask import ExecuteTask
            from aeneas.task import Task
            from aeneas.tools.execute_task import ExecuteTaskCLI

            # create Task object
            aeneas_output_file = (
                chapter_audio.split('/')[-1]).split('.')[0] + '_aeneas_out.txt'

            if (args.skip_matthew1_audio_head
                    is not None) and (find_audio_string == '01_*01'):
                config_string = (
                    "is_audio_file_head_length=skip_length|task_adjust_boundary_percent_value=50|task_adjust_boundary_nonspeech_min=0.4|task_language=aeneas_lang|is_text_type=plain|os_task_file_format=aud"
                    .replace('aeneas_lang', language_code)).replace(
                        'skip_length', args.skip_matthew1_audio_head[0])
            else:
                config_string = "task_adjust_boundary_percent_value=50|task_adjust_boundary_nonspeech_min=0.4|task_language=aeneas_lang|is_text_type=plain|os_task_file_format=aud".replace(
                    'aeneas_lang', language_code)

            #print(config_string)
            check_file = os.path.join(
                output_dir, (chapter_audio.split('/')[-1]).split('.')[0] +
                '_sync_adjusted.txt')

            if not os.path.isfile(check_file):
                print(os.path.isfile(check_file), check_file)
                print(os.path.join(output_dir, aeneas_output_file))
                #Save .txt file
                ExecuteTaskCLI(use_sys=False).run(arguments=[
                    None,  # dummy program name argument
                    chapter_audio,
                    os.path.join(output_dir, aeneas_file_name),
                    config_string,
                    os.path.join(output_dir, aeneas_output_file)
                ])

                # # Save time boundary
                task = Task(config_string=config_string)
                task.audio_file_path_absolute = chapter_audio
                print(aeneas_file_name)
                task.text_file_path_absolute = os.path.join(
                    output_dir, aeneas_file_name)
                task.sync_map_file_path_absolute = os.path.join(
                    output_dir, aeneas_output_file)

                # #process Task
                ExecuteTask(task).execute()

                index_list = list()

                with open(output_dir + '/' + aeneas_output_file, 'r') as a:
                    with open(output_dir + '/' + 'new' + aeneas_output_file,
                              'w') as b:
                        for line in a:
                            if not (line.__contains__('......')):

                                b.write(line)
                a.close()
                b.close()

                shutil.move(output_dir + '/new' + aeneas_output_file,
                            output_dir + '/' + aeneas_output_file)

                last = len(task.sync_map_leaves())
                for i, time in enumerate(task.sync_map_leaves()):
                    if 0 < i < last - 1:
                        index_list.append(time.end)

                inc = 0
                verse_list = list()
                for i in range(0, len(df)):
                    if (((str(df['book'][i])).strip()).replace(
                            ' ', '')).upper() == search_book.upper() and int(
                                df['chapter'][i]) == int(chapter):
                        write_file.writerow(
                            (df['fileset'][i], df['book'][i], df['chapter'][i],
                             df['line_number'][i], df['verse_number'][i],
                             df['verse_content'][i], index_list[inc]))
                        verse_list.append(df['verse_number'][i])
                        inc += 1

                print(chapter_audio)

                if args.no_move_adjustment:
                    silence_file = output_dir + '/' + (
                        aeneas_output_file.split('/')[-1]
                    ).split('.')[0] + '_silence.txt'
                    extract_silence_intervals(chapter_audio, silence_file)
                    sound = AudioSegment.from_mp3(chapter_audio)
                    framerate = sound.frame_rate

                    print(verse_list)
                    adjust_update_boundaries_with_silence(
                        output_dir + '/' + aeneas_output_file,
                        silence_file,
                        output_dir + '/' +
                        (chapter_audio.split('/')[-1]).split('.')[0] +
                        '_sync_adjusted.txt',
                        verse_list,
                        framerate,
                        input_split_field='\t',
                        output_split_field='\t')

                elif args.adjust_silence:
                    silence_file = output_dir + '/' + (
                        aeneas_output_file.split('/')[-1]
                    ).split('.')[0] + '_silence.txt'
                    extract_silence_intervals(chapter_audio, silence_file)
                    adjust_boundaries_with_silence(
                        output_dir + '/' + aeneas_output_file,
                        silence_file,
                        output_dir + '/' +
                        (chapter_audio.split('/')[-1]).split('.')[0] +
                        '_adjusted.txt',
                        verse_list,
                        input_split_field='\t',
                        output_split_field='\t')

        write_file_handle.close()

        if missing_chapters:
            with open(output_dir + '/missing_chapters.txt',
                      'w',
                      encoding='utf-8') as missing:
                for each_missing in missing_chapters:
                    missing.write(each_missing)
                missing.close()
    except Exception as err:
        print(
            type(err).__name__,  # TypeError
            __file__,  # /tmp/example.py
            err.__traceback__.tb_lineno  # 2
        )
Esempio n. 14
0
    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