| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 | from autosub import FLACConverterfrom autosub import SpeechRecognizerfrom autosub import extract_audiofrom autosub import find_speech_regionsfrom autosub import DEFAULT_CONCURRENCYfrom autosub import DEFAULT_SUBTITLE_FORMATfrom autosub import GOOGLE_SPEECH_API_KEYfrom autosub.formatters import FORMATTERSimport multiprocessingimport timeimport osfrom pytranscriber.util.util import MyUtilclass Ctr_Autosub():    cancel = False    @staticmethod    def init():        Ctr_Autosub.cancel = False    @staticmethod    def is_operation_canceled():        return Ctr_Autosub.cancel    @staticmethod    def output_progress(listener_progress, str_task, progress_percent):        # only update progress if not requested to cancel        if not Ctr_Autosub.cancel:            listener_progress(str_task, progress_percent)    @staticmethod    def cancel_operation():        Ctr_Autosub.cancel = True        while Ctr_Autosub.step == 0:            time.sleep(0.1)        # the first step involves ffmpeg and cannot be stopped safely        if Ctr_Autosub.step == 1:            # close wait for threads to finish their work first            Ctr_Autosub.pool.close()            Ctr_Autosub.pool.join()        else:            # terminates the threads immediately            Ctr_Autosub.pool.terminate()            Ctr_Autosub.pool.join()    @staticmethod    def generate_subtitles(# pylint: disable=too-many-locals,too-many-arguments            source_path,            src_language,            listener_progress,            output=None,            concurrency=DEFAULT_CONCURRENCY,            subtitle_file_format=DEFAULT_SUBTITLE_FORMAT        ):        # windows not support forkserver... only spawn        if os.name != "nt" and "Darwin" in os.uname():            # necessary for running on MacOS            # method can be set only once, otherwise crash            #from python 3.8 above the default for macos is spawn and not fork            if 'spawn' != multiprocessing.get_start_method(allow_none=True):                multiprocessing.set_start_method('spawn')        Ctr_Autosub.cancel = False        Ctr_Autosub.step = 0        """        Given an input audio/video file, generate subtitles in the specified language and format.        """        audio_filename, audio_rate = extract_audio(source_path)        regions = find_speech_regions(audio_filename)        converter = FLACConverter(source_path=audio_filename)        recognizer = SpeechRecognizer(language=src_language, rate=audio_rate,                                      api_key=GOOGLE_SPEECH_API_KEY)        transcripts = []        if regions:            try:                if Ctr_Autosub.cancel:                    return -1                str_task_1 = "Step 1 of 2: Converting speech regions to FLAC files "                len_regions = len(regions)                extracted_regions = []                Ctr_Autosub.pool = multiprocessing.Pool(concurrency)                for i, extracted_region in enumerate(Ctr_Autosub.pool.imap(converter, regions)):                    Ctr_Autosub.step = 1                    extracted_regions.append(extracted_region)                    progress_percent = MyUtil.percentage(i, len_regions)                    Ctr_Autosub.output_progress(listener_progress, str_task_1, progress_percent)                if Ctr_Autosub.cancel:                    return -1                else:                    Ctr_Autosub.pool.close()                    Ctr_Autosub.pool.join()                str_task_2 = "Step 2 of 2: Performing speech recognition "                Ctr_Autosub.pool = multiprocessing.Pool(concurrency)                for i, transcript in enumerate(Ctr_Autosub.pool.imap(recognizer, extracted_regions)):                    Ctr_Autosub.step = 2                    transcripts.append(transcript)                    progress_percent = MyUtil.percentage(i, len_regions)                    Ctr_Autosub.output_progress(listener_progress, str_task_2, progress_percent)                if Ctr_Autosub.cancel:                    return -1                else:                    Ctr_Autosub.pool.close()                    Ctr_Autosub.pool.join()            except KeyboardInterrupt:                Ctr_Autosub.pbar.finish()                Ctr_Autosub.pool.terminate()                Ctr_Autosub.pool.join()                raise        timed_subtitles = [(r, t) for r, t in zip(regions, transcripts) if t]        formatter = FORMATTERS.get(subtitle_file_format)        formatted_subtitles = formatter(timed_subtitles)        dest = output        if not dest:            base = os.path.splitext(source_path)[0]            dest = "{base}.{format}".format(base=base, format=subtitle_file_format)        with open(dest, 'wb') as output_file:            output_file.write(formatted_subtitles.encode("utf-8"))        os.remove(audio_filename)        if Ctr_Autosub.cancel:            return -1        else:            Ctr_Autosub.pool.close()            Ctr_Autosub.pool.join()        return dest
 |