SYMBOL INDEX (1434 symbols across 119 files) FILE: app/common/config.py class Language (line 40) | class Language(Enum): class LanguageSerializer (line 49) | class LanguageSerializer(ConfigSerializer): method serialize (line 52) | def serialize(self, language): method deserialize (line 55) | def deserialize(self, value: str): class PlatformAwareTranscribeModelValidator (line 59) | class PlatformAwareTranscribeModelValidator(OptionsValidator): method __init__ (line 62) | def __init__(self): method options (line 67) | def options(self): method validate (line 70) | def validate(self, value): method correct (line 73) | def correct(self, value): class Config (line 77) | class Config(QConfig): FILE: app/common/signal_bus.py class SignalBus (line 4) | class SignalBus(QObject): method play_video (line 35) | def play_video(self): method pause_video (line 39) | def pause_video(self): method stop_video (line 43) | def stop_video(self): method set_video_source (line 47) | def set_video_source(self, url: QUrl): method play_video_segment (line 55) | def play_video_segment(self, start_time: int, end_time: int): method add_subtitle (line 64) | def add_subtitle(self, subtitle_file: str): FILE: app/components/DonateDialog.py class DonateDialog (line 11) | class DonateDialog(MessageBoxBase): method __init__ (line 12) | def __init__(self, parent=None): method setup_ui (line 21) | def setup_ui(self): FILE: app/components/EditComboBoxSettingCard.py class EditComboBoxSettingCard (line 10) | class EditComboBoxSettingCard(SettingCard): method __init__ (line 15) | def __init__( method _setupCompleter (line 51) | def _setupCompleter(self): method __onTextChanged (line 61) | def __onTextChanged(self, text: str): method setValue (line 66) | def setValue(self, value: str): method addItems (line 71) | def addItems(self, items: List[str]): method setItems (line 78) | def setItems(self, items: List[str]): FILE: app/components/FasterWhisperSettingWidget.py function check_faster_whisper_exists (line 126) | def check_faster_whisper_exists() -> tuple[bool, list[str]]: class UnzipThread (line 153) | class UnzipThread(QThread): method __init__ (line 159) | def __init__(self, zip_file, extract_path): method run (line 164) | def run(self): class FasterWhisperDownloadDialog (line 180) | class FasterWhisperDownloadDialog(MessageBoxBase): method __init__ (line 186) | def __init__(self, parent=None, setting_widget=None): method _setup_ui (line 195) | def _setup_ui(self): method _setup_program_section (line 207) | def _setup_program_section(self, layout): method _setup_model_section (line 266) | def _setup_model_section(self, layout): method _create_model_table (line 290) | def _create_model_table(self): method _setup_progress_section (line 328) | def _setup_progress_section(self, layout): method _populate_model_table (line 338) | def _populate_model_table(self): method _add_model_row (line 344) | def _add_model_row(self, row, model): method _connect_signals (line 387) | def _connect_signals(self): method _start_download (line 391) | def _start_download(self): method _on_program_download_progress (line 451) | def _on_program_download_progress(self, value, status_msg): method _on_program_download_finished (line 456) | def _on_program_download_finished(self, save_path): method _on_program_download_error (line 479) | def _on_program_download_error(self, error): method _on_dialog_reject (line 489) | def _on_dialog_reject(self): method closeEvent (line 498) | def closeEvent(self, event): method _download_model (line 503) | def _download_model(self, row): method _set_all_download_buttons_enabled (line 607) | def _set_all_download_buttons_enabled(self, enabled: bool): method _open_model_folder (line 622) | def _open_model_folder(self): method _open_program_folder (line 628) | def _open_program_folder(self): method _finish_program_installation (line 634) | def _finish_program_installation(self): method _on_unzip_error (line 645) | def _on_unzip_error(self, error_msg): method _cleanup_installation (line 650) | def _cleanup_installation(self): class FasterWhisperSettingWidget (line 658) | class FasterWhisperSettingWidget(QWidget): method __init__ (line 659) | def __init__(self, parent=None): method showEvent (line 664) | def showEvent(self, a0: QShowEvent) -> None: method setup_ui (line 673) | def setup_ui(self): method _connect_signals (line 853) | def _connect_signals(self): method _on_vad_filter_changed (line 858) | def _on_vad_filter_changed(self, checked: bool): method _show_model_manager (line 863) | def _show_model_manager(self): method show_error_info (line 868) | def show_error_info(self, error_msg): method check_faster_whisper_model (line 878) | def check_faster_whisper_model(self): FILE: app/components/LanguageSettingDialog.py class LanguageSettingDialog (line 19) | class LanguageSettingDialog(MessageBoxBase): method __init__ (line 22) | def __init__(self, model: TranscribeModelEnum, parent=None): method _get_available_languages (line 29) | def _get_available_languages(self) -> list[str]: method _setup_ui (line 37) | def _setup_ui(self): method _connect_signals (line 77) | def _connect_signals(self): method __onYesButtonClicked (line 81) | def __onYesButtonClicked(self): FILE: app/components/LineEditSettingCard.py class LineEditSettingCard (line 8) | class LineEditSettingCard(SettingCard): method __init__ (line 13) | def __init__( method __onTextChanged (line 38) | def __onTextChanged(self, text: str): method setValue (line 42) | def setValue(self, value: str): FILE: app/components/MySettingCard.py class SettingIconWidget (line 14) | class SettingIconWidget(IconWidget): method paintEvent (line 15) | def paintEvent(self, e): class SettingCard (line 25) | class SettingCard(QFrame): method __init__ (line 28) | def __init__( method setTitle (line 80) | def setTitle(self, title: str): method setContent (line 84) | def setContent(self, content: str): method setValue (line 89) | def setValue(self, value): method setIconSize (line 93) | def setIconSize(self, width: int, height: int): method paintEvent (line 97) | def paintEvent(self, e): class DoubleSpinBoxSettingCard (line 111) | class DoubleSpinBoxSettingCard(SettingCard): method __init__ (line 116) | def __init__( method __onValueChanged (line 142) | def __onValueChanged(self, value: float): method setValue (line 147) | def setValue(self, value: float): class SpinBoxSettingCard (line 152) | class SpinBoxSettingCard(SettingCard): method __init__ (line 157) | def __init__( method __onValueChanged (line 182) | def __onValueChanged(self, value: int): method setValue (line 187) | def setValue(self, value: int): class ComboBoxSettingCard (line 192) | class ComboBoxSettingCard(SettingCard): method __init__ (line 198) | def __init__( method __onCurrentTextChanged (line 222) | def __onCurrentTextChanged(self, text: str): method __onCurrentIndexChanged (line 226) | def __onCurrentIndexChanged(self, index: int): method setCurrentText (line 230) | def setCurrentText(self, text: str): method setCurrentIndex (line 234) | def setCurrentIndex(self, index: int): method addItem (line 238) | def addItem(self, text: str): method addItems (line 242) | def addItems(self, texts: List[str]): method clear (line 246) | def clear(self): class ColorSettingCard (line 251) | class ColorSettingCard(SettingCard): method __init__ (line 256) | def __init__( method __onColorChanged (line 293) | def __onColorChanged(self, color: QColor): method setColor (line 297) | def setColor(self, color: QColor): class ColorPickerButton (line 302) | class ColorPickerButton(QToolButton): method __init__ (line 307) | def __init__(self, color: QColor, title: str, parent=None, enableAlpha... method __showColorDialog (line 318) | def __showColorDialog(self): method __onColorChanged (line 326) | def __onColorChanged(self, color): method setColor (line 331) | def setColor(self, color): method paintEvent (line 336) | def paintEvent(self, e): FILE: app/components/MyVideoWidget.py class MediaStatus (line 25) | class MediaStatus(Enum): class PlaybackState (line 36) | class PlaybackState(Enum): class MediaPlayerBase (line 42) | class MediaPlayerBase(QObject): method __init__ (line 53) | def __init__(self, parent=None): method isPlaying (line 56) | def isPlaying(self): method mediaStatus (line 60) | def mediaStatus(self) -> MediaStatus: method playbackState (line 64) | def playbackState(self) -> PlaybackState: method duration (line 68) | def duration(self): method position (line 72) | def position(self): method volume (line 76) | def volume(self): method source (line 80) | def source(self) -> QUrl: method pause (line 84) | def pause(self): method play (line 88) | def play(self): method stop (line 92) | def stop(self): method playbackRate (line 96) | def playbackRate(self) -> float: method setPosition (line 100) | def setPosition(self, position: int): method setSource (line 104) | def setSource(self, media: QUrl): method setPlaybackRate (line 108) | def setPlaybackRate(self, rate: float): method setVolume (line 112) | def setVolume(self, volume: int): method setMuted (line 116) | def setMuted(self, isMuted: bool): method videoOutput (line 119) | def videoOutput(self) -> QObject: method setVideoOutput (line 123) | def setVideoOutput(self, output: QObject) -> None: class MediaPlayer (line 128) | class MediaPlayer(MediaPlayerBase): method __init__ (line 129) | def __init__(self, parent=None): method _on_timer_update (line 161) | def _on_timer_update(self): method isPlaying (line 182) | def isPlaying(self): method mediaStatus (line 185) | def mediaStatus(self) -> MediaStatus: method playbackState (line 206) | def playbackState(self) -> PlaybackState: method duration (line 216) | def duration(self): method position (line 219) | def position(self): method volume (line 222) | def volume(self): method source (line 225) | def source(self) -> QUrl: method get_subtitle (line 228) | def get_subtitle(self): method pause (line 258) | def pause(self): method play (line 261) | def play(self): method stop (line 264) | def stop(self): method playbackRate (line 267) | def playbackRate(self) -> float: method setPosition (line 270) | def setPosition(self, position: int): method setSource (line 275) | def setSource(self, media: QUrl): method setPlaybackRate (line 284) | def setPlaybackRate(self, rate: float): method setVolume (line 290) | def setVolume(self, volume: int): method setMuted (line 295) | def setMuted(self, isMuted: bool): method videoOutput (line 300) | def videoOutput(self) -> Optional[QObject]: method setVideoOutput (line 303) | def setVideoOutput(self, output: QObject) -> None: method hasMedia (line 307) | def hasMedia(self): method playSegment (line 311) | def playSegment(self, start_time: int, end_time: int): method add_subtitle (line 344) | def add_subtitle(self, subtitle_file: str) -> bool: method get_subtitle_tracks (line 373) | def get_subtitle_tracks(self) -> list: method set_subtitle_track (line 385) | def set_subtitle_track(self, track_id: int): class StandardMediaPlayBar (line 395) | class StandardMediaPlayBar(MediaPlayBarBase): method __init__ (line 398) | def __init__(self, parent=None): method __initWidgets (line 418) | def __initWidgets(self): method skipBack (line 448) | def skipBack(self, ms: int): method skipForward (line 452) | def skipForward(self, ms: int): method _onPositionChanged (line 456) | def _onPositionChanged(self, position: int): method _formatTime (line 463) | def _formatTime(self, time: int): method closeEvent (line 470) | def closeEvent(self, event): class MyVideoWidget (line 475) | class MyVideoWidget(QWidget): method __init__ (line 478) | def __init__(self, parent=None): method _connectSignals (line 542) | def _connectSignals(self): method addSubtitle (line 552) | def addSubtitle(self, subtitle_file: str): method setVideo (line 557) | def setVideo(self, url: QUrl): method play (line 570) | def play(self): method pause (line 574) | def pause(self): method stop (line 578) | def stop(self): method playSegment (line 582) | def playSegment(self, start_time: int, end_time: int): method hideEvent (line 591) | def hideEvent(self, e): method wheelEvent (line 595) | def wheelEvent(self, e): method togglePlayState (line 598) | def togglePlayState(self): method player (line 606) | def player(self): method keyPressEvent (line 609) | def keyPressEvent(self, event): method dragEnterEvent (line 620) | def dragEnterEvent(self, event): method dropEvent (line 635) | def dropEvent(self, event): method eventFilter (line 649) | def eventFilter(self, obj, event): method showEvent (line 657) | def showEvent(self, event): FILE: app/components/SimpleSettingCard.py class SimpleSettingCard (line 13) | class SimpleSettingCard(CardWidget): method __init__ (line 16) | def __init__(self, title, content, parent=None): method setup_ui (line 22) | def setup_ui(self): class ComboBoxSimpleSettingCard (line 37) | class ComboBoxSimpleSettingCard(SimpleSettingCard): method __init__ (line 42) | def __init__(self, title, content, items=None, parent=None): method setup_combobox (line 47) | def setup_combobox(self): method setValue (line 54) | def setValue(self, value): method value (line 57) | def value(self): class SwitchButtonSimpleSettingCard (line 61) | class SwitchButtonSimpleSettingCard(SimpleSettingCard): method __init__ (line 66) | def __init__(self, title, content, parent=None): method setup_switch (line 70) | def setup_switch(self): method setChecked (line 81) | def setChecked(self, checked): method isChecked (line 84) | def isChecked(self): FILE: app/components/SpinBoxSettingCard.py class DoubleSpinBoxSettingCard (line 9) | class DoubleSpinBoxSettingCard(SettingCard): method __init__ (line 14) | def __init__( method __onValueChanged (line 46) | def __onValueChanged(self, value: float): method setValue (line 51) | def setValue(self, value: float): class SpinBoxSettingCard (line 57) | class SpinBoxSettingCard(SettingCard): method __init__ (line 62) | def __init__( method __onValueChanged (line 90) | def __onValueChanged(self, value: int): method setValue (line 95) | def setValue(self, value: int): FILE: app/components/SubtitleSettingDialog.py class SubtitleSettingDialog (line 12) | class SubtitleSettingDialog(MessageBoxBase): method __init__ (line 15) | def __init__(self, parent=None): FILE: app/components/TranscriptionOutputDialog.py class TranscriptionSettingDialog (line 13) | class TranscriptionSettingDialog(MessageBoxBase): method __init__ (line 16) | def __init__(self, parent=None): FILE: app/components/TranscriptionSettingDialog.py class TranscriptionSettingDialog (line 13) | class TranscriptionSettingDialog(MessageBoxBase): method __init__ (line 16) | def __init__(self, parent=None): FILE: app/components/WhisperAPISettingWidget.py class WhisperAPISettingWidget (line 24) | class WhisperAPISettingWidget(QWidget): method __init__ (line 25) | def __init__(self, parent=None): method setup_ui (line 29) | def setup_ui(self): method on_check_connection (line 132) | def on_check_connection(self): method on_connection_check_finished (line 160) | def on_connection_check_finished(self, success, result): method on_connection_check_error (line 183) | def on_connection_check_error(self, message): class WhisperConnectionThread (line 197) | class WhisperConnectionThread(QThread): method __init__ (line 203) | def __init__(self, base_url, api_key, model): method run (line 209) | def run(self): FILE: app/components/WhisperCppSettingWidget.py function check_whisper_cpp_exists (line 114) | def check_whisper_cpp_exists(): class DownloadDialog (line 119) | class DownloadDialog(MessageBoxBase): method __init__ (line 120) | def __init__(self, parent=None): method setup_ui (line 126) | def setup_ui(self): method start_download (line 163) | def start_download(self): method update_progress (line 188) | def update_progress(self, value, status_msg): method download_finished (line 192) | def download_finished(self): method download_error (line 202) | def download_error(self, error): method reject (line 212) | def reject(self): class WhisperCppDownloadDialog (line 219) | class WhisperCppDownloadDialog(MessageBoxBase): method __init__ (line 225) | def __init__(self, parent=None, setting_widget=None): method _setup_ui (line 233) | def _setup_ui(self): method _setup_program_section (line 245) | def _setup_program_section(self, layout): method _setup_model_section (line 265) | def _setup_model_section(self, layout): method _create_model_table (line 289) | def _create_model_table(self): method _setup_progress_section (line 327) | def _setup_progress_section(self, layout): method _populate_model_table (line 337) | def _populate_model_table(self): method _add_model_row (line 343) | def _add_model_row(self, row, model): method _download_model (line 383) | def _download_model(self, row): method _set_all_download_buttons_enabled (line 489) | def _set_all_download_buttons_enabled(self, enabled: bool): method _open_model_folder (line 504) | def _open_model_folder(self): class WhisperCppSettingWidget (line 511) | class WhisperCppSettingWidget(QWidget): method __init__ (line 512) | def __init__(self, parent=None): method setup_ui (line 517) | def setup_ui(self): method setup_signals (line 596) | def setup_signals(self): method show_download_dialog (line 599) | def show_download_dialog(self): FILE: app/components/transcription_setting_card.py class TranscriptionSettingCard (line 18) | class TranscriptionSettingCard(QWidget): method __init__ (line 19) | def __init__(self, parent=None): method setup_ui (line 23) | def setup_ui(self): method on_model_changed (line 48) | def on_model_changed(self, value): FILE: app/core/asr/asr_data.py function handle_long_path (line 34) | def handle_long_path(path: str) -> str: class ASRDataSeg (line 52) | class ASRDataSeg: method __init__ (line 53) | def __init__( method to_srt_ts (line 61) | def to_srt_ts(self) -> str: method to_lrc_ts (line 65) | def to_lrc_ts(self) -> str: method to_ass_ts (line 69) | def to_ass_ts(self) -> Tuple[str, str]: method _ms_to_lrc_time (line 74) | def _ms_to_lrc_time(ms: int) -> str: method _ms_to_srt_time (line 81) | def _ms_to_srt_time(ms: int) -> str: method _ms_to_ass_ts (line 89) | def _ms_to_ass_ts(ms: int) -> str: method transcript (line 98) | def transcript(self) -> str: method __str__ (line 102) | def __str__(self) -> str: class ASRData (line 106) | class ASRData: method __init__ (line 107) | def __init__(self, segments: List[ASRDataSeg]): method __iter__ (line 112) | def __iter__(self): method __len__ (line 115) | def __len__(self) -> int: method has_data (line 118) | def has_data(self) -> bool: method _is_word_level_segment (line 122) | def _is_word_level_segment(self, segment: ASRDataSeg) -> bool: method is_word_timestamp (line 141) | def is_word_timestamp(self) -> bool: method split_to_word_segments (line 165) | def split_to_word_segments(self) -> "ASRData": method remove_punctuation (line 210) | def remove_punctuation(self) -> "ASRData": method save (line 220) | def save( method to_txt (line 248) | def to_txt( method to_srt (line 275) | def to_srt( method to_lrc (line 304) | def to_lrc(self, save_path=None) -> str: method to_json (line 308) | def to_json(self) -> dict: method to_ass (line 320) | def to_ass( method to_vtt (line 413) | def to_vtt(self, save_path=None) -> str: method merge_segments (line 442) | def merge_segments( method merge_with_next_segment (line 461) | def merge_with_next_segment(self, index: int) -> None: method optimize_timing (line 472) | def optimize_timing(self, threshold_ms: int = 1000) -> "ASRData": method __str__ (line 501) | def __str__(self): method from_subtitle_file (line 505) | def from_subtitle_file(file_path: str) -> "ASRData": method from_json (line 543) | def from_json(json_data: dict) -> "ASRData": method from_srt (line 558) | def from_srt(srt_str: str) -> "ASRData": method from_vtt (line 627) | def from_vtt(vtt_str: str) -> "ASRData": method from_youtube_vtt (line 682) | def from_youtube_vtt(vtt_str: str) -> "ASRData": method from_ass (line 750) | def from_ass(ass_str: str) -> "ASRData": FILE: app/core/asr/base.py class BaseASR (line 19) | class BaseASR: method __init__ (line 37) | def __init__( method _set_data (line 57) | def _set_data(self): method _get_audio_duration (line 76) | def _get_audio_duration(self) -> float: method run (line 87) | def run( method _get_key (line 120) | def _get_key(self) -> str: method _make_segments (line 131) | def _make_segments(self, resp_data: dict) -> list[ASRDataSeg]: method _run (line 144) | def _run( method _check_rate_limit (line 158) | def _check_rate_limit(self) -> None: FILE: app/core/asr/bcut.py class BcutASR (line 20) | class BcutASR(BaseASR): method __init__ (line 31) | def __init__( method upload (line 54) | def upload(self) -> None: method __upload_part (line 83) | def __upload_part(self) -> None: method __commit_upload (line 106) | def __commit_upload(self) -> None: method create_task (line 122) | def create_task(self) -> str: method result (line 134) | def result(self, task_id: Optional[str] = None): method _run (line 145) | def _run( method _make_segments (line 180) | def _make_segments(self, resp_data: dict) -> List[ASRDataSeg]: FILE: app/core/asr/chunk_merger.py class ChunkMerger (line 20) | class ChunkMerger: method __init__ (line 27) | def __init__(self, min_match_count: int = 2, fuzzy_threshold: float = ... method merge_chunks (line 37) | def merge_chunks( method _merge_two_sequences (line 101) | def _merge_two_sequences( method _find_best_alignment (line 175) | def _find_best_alignment( method _adjust_timestamps (line 249) | def _adjust_timestamps( method _extract_overlap_segments (line 271) | def _extract_overlap_segments( method _infer_chunk_offsets (line 308) | def _infer_chunk_offsets( FILE: app/core/asr/chunked_asr.py class ChunkedASR (line 28) | class ChunkedASR: method __init__ (line 58) | def __init__( method run (line 78) | def run(self, callback: Optional[Callable[[int, str], None]] = None) -... method _split_audio (line 107) | def _split_audio(self) -> List[Tuple[bytes, int]]: method _transcribe_chunks (line 154) | def _transcribe_chunks( method _merge_results (line 222) | def _merge_results( FILE: app/core/asr/faster_whisper.py class FasterWhisperASR (line 21) | class FasterWhisperASR(BaseASR): method __init__ (line 28) | def __init__( method _build_command (line 115) | def _build_command(self, audio_input: str) -> List[str]: method _make_segments (line 199) | def _make_segments(self, resp_data: str) -> List[ASRDataSeg]: method _run (line 224) | def _run( method _get_key (line 323) | def _get_key(self): function is_rtx_50_series (line 330) | def is_rtx_50_series() -> bool: FILE: app/core/asr/jianying.py class JianYingASR (line 19) | class JianYingASR(BaseASR): method __init__ (line 25) | def __init__( method submit (line 53) | def submit(self) -> str: method upload (line 82) | def upload(self): method query (line 91) | def query(self, query_id: str): method _run (line 108) | def _run( method _make_segments (line 132) | def _make_segments(self, resp_data: dict) -> List[ASRDataSeg]: method _get_key (line 145) | def _get_key(self): method _get_tid (line 148) | def _get_tid(self): method _generate_sign_parameters (line 154) | def _generate_sign_parameters( method _build_headers (line 186) | def _build_headers(self, device_time: str, sign: str) -> Dict[str, str]: method _uplosd_headers (line 198) | def _uplosd_headers(self): method _upload_sign (line 206) | def _upload_sign(self): method _upload_auth (line 222) | def _upload_auth(self): method _upload_file (line 260) | def _upload_file(self): method _upload_check (line 269) | def _upload_check(self): method _upload_commit (line 278) | def _upload_commit(self): function sign (line 286) | def sign(key: bytes, msg: str) -> bytes: function get_signature_key (line 291) | def get_signature_key( function aws_signature (line 302) | def aws_signature( FILE: app/core/asr/status.py class ASRStatus (line 5) | class ASRStatus(Enum): method message (line 38) | def message(self) -> str: method progress (line 43) | def progress(self) -> int: method with_progress (line 47) | def with_progress(self, progress: int) -> Tuple[int, str]: method callback_tuple (line 58) | def callback_tuple(self) -> Tuple[int, str]: FILE: app/core/asr/transcribe.py function transcribe (line 11) | def transcribe(audio_path: str, config: TranscribeConfig, callback=None)... function _create_asr_instance (line 45) | def _create_asr_instance(audio_path: str, config: TranscribeConfig) -> C... function _create_jianying_asr (line 76) | def _create_jianying_asr(audio_path: str, config: TranscribeConfig) -> C... function _create_bijian_asr (line 87) | def _create_bijian_asr(audio_path: str, config: TranscribeConfig) -> Chu... function _create_whisper_cpp_asr (line 96) | def _create_whisper_cpp_asr(audio_path: str, config: TranscribeConfig) -... function _create_whisper_api_asr (line 113) | def _create_whisper_api_asr(audio_path: str, config: TranscribeConfig) -... function _create_faster_whisper_asr (line 129) | def _create_faster_whisper_asr(audio_path: str, config: TranscribeConfig... function progress_callback (line 175) | def progress_callback(progress: int, message: str): FILE: app/core/asr/whisper_api.py class WhisperAPI (line 14) | class WhisperAPI(BaseASR): method __init__ (line 20) | def __init__( method _run (line 58) | def _run( method _make_segments (line 64) | def _make_segments(self, resp_data: dict) -> List[ASRDataSeg]: method _get_key (line 85) | def _get_key(self) -> str: method _submit (line 89) | def _submit(self) -> dict: FILE: app/core/asr/whisper_cpp.py class WhisperCppASR (line 21) | class WhisperCppASR(BaseASR): method __init__ (line 27) | def __init__( method _make_segments (line 68) | def _make_segments(self, resp_data: str) -> List[ASRDataSeg]: method _build_command (line 84) | def _build_command( method _run (line 114) | def _run( method _get_key (line 237) | def _get_key(self): method get_audio_duration (line 240) | def get_audio_duration(self, filepath: str) -> int: function detect_whisper_executable (line 263) | def detect_whisper_executable() -> str: FILE: app/core/entities.py function _generate_task_id (line 11) | def _generate_task_id() -> str: class SubtitleProcessData (line 17) | class SubtitleProcessData: class SupportedAudioFormats (line 26) | class SupportedAudioFormats(Enum): class SupportedVideoFormats (line 48) | class SupportedVideoFormats(Enum): class SupportedSubtitleFormats (line 76) | class SupportedSubtitleFormats(Enum): class OutputSubtitleFormatEnum (line 84) | class OutputSubtitleFormatEnum(Enum): class TranscribeOutputFormatEnum (line 94) | class TranscribeOutputFormatEnum(Enum): class LLMServiceEnum (line 104) | class LLMServiceEnum(Enum): class TranscribeModelEnum (line 116) | class TranscribeModelEnum(Enum): class TranslatorServiceEnum (line 126) | class TranslatorServiceEnum(Enum): class VadMethodEnum (line 135) | class VadMethodEnum(Enum): class SubtitleLayoutEnum (line 155) | class SubtitleLayoutEnum(Enum): class SubtitleRenderModeEnum (line 164) | class SubtitleRenderModeEnum(Enum): class VideoQualityEnum (line 171) | class VideoQualityEnum(Enum): method get_crf (line 179) | def get_crf(self) -> int: method get_preset (line 189) | def get_preset( class TranscribeLanguageEnum (line 225) | class TranscribeLanguageEnum(Enum): class WhisperModelEnum (line 332) | class WhisperModelEnum(Enum): class FasterWhisperModelEnum (line 341) | class FasterWhisperModelEnum(Enum): class ASRLanguageCapability (line 469) | class ASRLanguageCapability: function _get_all_languages_except_auto (line 476) | def _get_all_languages_except_auto() -> list[TranscribeLanguageEnum]: function get_asr_language_capability (line 511) | def get_asr_language_capability(model: TranscribeModelEnum) -> ASRLangua... class AudioStreamInfo (line 523) | class AudioStreamInfo: class VideoInfo (line 533) | class VideoInfo: class TranscribeConfig (line 551) | class TranscribeConfig: method _mask_key (line 577) | def _mask_key(self, key: Optional[str]) -> str: method print_config (line 583) | def print_config(self) -> str: class SubtitleConfig (line 625) | class SubtitleConfig: method _mask_key (line 649) | def _mask_key(self, key: Optional[str]) -> str: method print_config (line 655) | def print_config(self) -> str: class SynthesisConfig (line 694) | class SynthesisConfig: method print_config (line 706) | def print_config(self) -> str: class TranscribeTask (line 722) | class TranscribeTask: class SubtitleTask (line 748) | class SubtitleTask: class SynthesisTask (line 773) | class SynthesisTask: class TranscriptAndSubtitleTask (line 797) | class TranscriptAndSubtitleTask: class FullProcessTask (line 818) | class FullProcessTask: class BatchTaskType (line 838) | class BatchTaskType(Enum): method __str__ (line 846) | def __str__(self): class BatchTaskStatus (line 850) | class BatchTaskStatus(Enum): method __str__ (line 858) | def __str__(self): FILE: app/core/llm/check_llm.py function check_llm_connection (line 10) | def check_llm_connection( function get_available_models (line 54) | def get_available_models(base_url: str, api_key: str) -> list[str]: FILE: app/core/llm/check_whisper.py function check_whisper_connection (line 14) | def check_whisper_connection( FILE: app/core/llm/client.py function normalize_base_url (line 29) | def normalize_base_url(base_url: str) -> str: function get_llm_client (line 52) | def get_llm_client() -> OpenAI: function before_sleep_log (line 77) | def before_sleep_log(retry_state: RetryCallState) -> None: function _call_llm_api (line 89) | def _call_llm_api( function call_llm (line 112) | def call_llm( FILE: app/core/llm/context.py class TaskContext (line 13) | class TaskContext: function generate_task_id (line 25) | def generate_task_id() -> str: function set_task_context (line 30) | def set_task_context(task_id: str, file_name: str, stage: str) -> None: function get_task_context (line 37) | def get_task_context() -> Optional[TaskContext]: function update_stage (line 43) | def update_stage(stage: str) -> None: function clear_task_context (line 55) | def clear_task_context() -> None: FILE: app/core/llm/request_logger.py function _rotate_if_needed (line 23) | def _rotate_if_needed() -> None: function _write_log (line 36) | def _write_log(entry: Dict[str, Any]) -> None: function _on_request (line 51) | def _on_request(request: httpx.Request) -> None: function _on_response (line 68) | def _on_response(response: httpx.Response) -> None: function create_logging_http_client (line 83) | def create_logging_http_client() -> httpx.Client: function log_llm_response (line 93) | def log_llm_response(response: Any) -> None: FILE: app/core/optimize/optimize.py class SubtitleOptimizer (line 27) | class SubtitleOptimizer: method __init__ (line 36) | def __init__( method _init_thread_pool (line 64) | def _init_thread_pool(self) -> None: method optimize_subtitle (line 69) | def optimize_subtitle(self, subtitle_data: Union[str, ASRData]) -> ASR... method _split_chunks (line 105) | def _split_chunks(self, subtitle_dict: Dict[str, str]) -> List[Dict[st... method _parallel_optimize (line 120) | def _parallel_optimize(self, chunks: List[Dict[str, str]]) -> Dict[str... method _optimize_chunk (line 154) | def _optimize_chunk(self, subtitle_chunk: Dict[str, str]) -> Dict[str,... method agent_loop (line 187) | def agent_loop(self, subtitle_chunk: Dict[str, str]) -> Dict[str, str]: method _validate_optimization_result (line 273) | def _validate_optimization_result( method _repair_subtitle (line 344) | def _repair_subtitle( method _create_segments (line 383) | def _create_segments( method stop (line 405) | def stop(self) -> None: FILE: app/core/prompts/__init__.py function _load_prompt_file (line 25) | def _load_prompt_file(prompt_path: str) -> str: function get_prompt (line 48) | def get_prompt(prompt_path: str, **kwargs) -> str: function list_prompts (line 75) | def list_prompts() -> list[str]: function reload_cache (line 92) | def reload_cache(): FILE: app/core/split/alignment.py class SubtitleAligner (line 4) | class SubtitleAligner: method __init__ (line 22) | def __init__(self): method align_texts (line 25) | def align_texts(self, source_text, target_text): method _pair_lines (line 39) | def _pair_lines(self, diff_iterator): method _line_iterator (line 74) | def _line_iterator(self, diff_iterator): method _format_line (line 159) | def _format_line(self, lines, format_key, side): FILE: app/core/split/split.py function preprocess_segments (line 57) | def preprocess_segments( class SubtitleSplitter (line 85) | class SubtitleSplitter: method __init__ (line 91) | def __init__( method _init_thread_pool (line 113) | def _init_thread_pool(self): method split_subtitle (line 118) | def split_subtitle(self, subtitle_data: Union[str, ASRData]) -> ASRData: method _determine_num_segments (line 169) | def _determine_num_segments( method _split_asr_data (line 186) | def _split_asr_data(self, asr_data: ASRData, num_segments: int) -> Lis... method _process_segments (line 248) | def _process_segments(self, asr_data_list: List[ASRData]) -> List[List... method _process_single_segment (line 269) | def _process_single_segment(self, asr_data_part: ASRData) -> List[ASRD... method _process_by_llm (line 279) | def _process_by_llm(self, segments: List[ASRDataSeg]) -> List[ASRDataS... method _process_by_rules (line 300) | def _process_by_rules(self, segments: List[ASRDataSeg]) -> List[ASRDat... method _group_by_time_gaps (line 343) | def _group_by_time_gaps( method _split_by_common_words (line 397) | def _split_by_common_words( method _split_long_segment (line 521) | def _split_long_segment(self, segments: List[ASRDataSeg]) -> List[ASRD... method _merge_processed_segments (line 591) | def _merge_processed_segments( method merge_short_segment (line 602) | def merge_short_segment(self, segments: List[ASRDataSeg]) -> None: method _merge_segments_based_on_sentences (line 661) | def _merge_segments_based_on_sentences( method stop (line 773) | def stop(self): FILE: app/core/split/split_by_llm.py function split_by_llm (line 16) | def split_by_llm( function _split_with_agent_loop (line 42) | def _split_with_agent_loop( function _validate_split_result (line 111) | def _validate_split_result( FILE: app/core/subtitle/__init__.py function get_subtitle_style (line 27) | def get_subtitle_style(style_name: str) -> Optional[str]: FILE: app/core/subtitle/ass_renderer.py function _check_cuda_available (line 36) | def _check_cuda_available() -> bool: function _scale_ass_style (line 75) | def _scale_ass_style(style_str: str, scale_factor: float) -> str: function render_ass_preview (line 110) | def render_ass_preview( function _get_video_resolution (line 258) | def _get_video_resolution(video_path: str) -> Tuple[int, int]: function render_ass_video (line 277) | def render_ass_video( FILE: app/core/subtitle/ass_utils.py class AssStyle (line 12) | class AssStyle: class AssInfo (line 35) | class AssInfo: method get_style (line 42) | def get_style(self, style_name: str) -> AssStyle: function parse_ass_info (line 52) | def parse_ass_info(ass_content: str) -> AssInfo: function wrap_ass_text (line 179) | def wrap_ass_text( function auto_wrap_ass_file (line 222) | def auto_wrap_ass_file( FILE: app/core/subtitle/font_utils.py function _get_font_family_name (line 18) | def _get_font_family_name(font_path: Path, font_index: int = 0) -> Optio... function get_builtin_fonts (line 53) | def get_builtin_fonts() -> tuple[Dict[str, str], ...]: function get_font (line 74) | def get_font(size: int, font_name: str = "") -> FontType: function get_ass_to_pil_ratio (line 121) | def get_ass_to_pil_ratio(font_name: str) -> float: function clear_font_cache (line 165) | def clear_font_cache(): FILE: app/core/subtitle/rounded_renderer.py function _get_video_info (line 26) | def _get_video_info(video_path: str) -> Tuple[int, int, float]: function render_text_block (line 53) | def render_text_block( function render_subtitle_image (line 133) | def render_subtitle_image( function render_preview (line 200) | def render_preview( function render_rounded_video (line 268) | def render_rounded_video( FILE: app/core/subtitle/styles.py class RoundedBgStyle (line 9) | class RoundedBgStyle: FILE: app/core/subtitle/text_utils.py function is_mainly_cjk (line 12) | def is_mainly_cjk(text: str, threshold: float = 0.5) -> bool: function hex_to_rgba (line 23) | def hex_to_rgba(hex_color: str) -> Tuple[int, int, int, int]: function _calculate_text_width (line 44) | def _calculate_text_width(text: str, font: FontType, spacing: float) -> ... function wrap_text (line 65) | def wrap_text( function _wrap_cjk_balanced (line 98) | def _wrap_cjk_balanced( function _wrap_english_balanced (line 172) | def _wrap_english_balanced( FILE: app/core/task_factory.py class TaskFactory (line 21) | class TaskFactory: method get_ass_style (line 25) | def get_ass_style(style_name: str) -> str: method get_rounded_style (line 33) | def get_rounded_style() -> dict: method create_transcribe_task (line 49) | def create_transcribe_task( method create_subtitle_task (line 108) | def create_subtitle_task( method create_synthesis_task (line 207) | def create_synthesis_task( method create_transcript_and_subtitle_task (line 248) | def create_transcript_and_subtitle_task( method create_full_process_task (line 267) | def create_full_process_task( FILE: app/core/translate/base.py class BaseTranslator (line 17) | class BaseTranslator(ABC): method __init__ (line 20) | def __init__( method _init_thread_pool (line 37) | def _init_thread_pool(self): method translate_subtitle (line 42) | def translate_subtitle(self, subtitle_data: ASRData) -> ASRData: method _split_chunks (line 69) | def _split_chunks( method _parallel_translate (line 78) | def _parallel_translate( method _get_cache_key (line 101) | def _get_cache_key(self, chunk: List[SubtitleProcessData]) -> str: method _safe_translate_chunk (line 108) | def _safe_translate_chunk( method _set_segments_translated_text (line 131) | def _set_segments_translated_text( method _translate_chunk (line 147) | def _translate_chunk( method stop (line 153) | def stop(self): FILE: app/core/translate/bing_translator.py class BingTranslator (line 13) | class BingTranslator(BaseTranslator): method __init__ (line 16) | def __init__( method _init_session (line 41) | def _init_session(self): method _translate_chunk (line 52) | def _translate_chunk( method _get_cache_key (line 100) | def _get_cache_key(self, chunk: List[SubtitleProcessData]) -> str: FILE: app/core/translate/deeplx_translator.py class DeepLXTranslator (line 13) | class DeepLXTranslator(BaseTranslator): method __init__ (line 16) | def __init__( method _translate_chunk (line 34) | def _translate_chunk( method _get_cache_key (line 58) | def _get_cache_key(self, chunk: List[SubtitleProcessData]) -> str: FILE: app/core/translate/factory.py class TranslatorFactory (line 16) | class TranslatorFactory: method create_translator (line 20) | def create_translator( FILE: app/core/translate/google_translator.py class GoogleTranslator (line 15) | class GoogleTranslator(BaseTranslator): method __init__ (line 18) | def __init__( method _translate_chunk (line 39) | def _translate_chunk( method _get_cache_key (line 73) | def _get_cache_key(self, chunk: List[SubtitleProcessData]) -> str: FILE: app/core/translate/llm_translator.py class LLMTranslator (line 16) | class LLMTranslator(BaseTranslator): method __init__ (line 21) | def __init__( method _translate_chunk (line 42) | def _translate_chunk( method _agent_loop (line 96) | def _agent_loop( method _validate_llm_response (line 133) | def _validate_llm_response( method _translate_chunk_single (line 187) | def _translate_chunk_single( method _get_cache_key (line 212) | def _get_cache_key(self, chunk: List[SubtitleProcessData]) -> str: FILE: app/core/translate/types.py class TranslatorType (line 6) | class TranslatorType(Enum): class TargetLanguage (line 15) | class TargetLanguage(Enum): function get_language_code (line 201) | def get_language_code(target_language: TargetLanguage, translator_type: ... FILE: app/core/tts/base.py class BaseTTS (line 16) | class BaseTTS(ABC): method __init__ (line 25) | def __init__(self, config: TTSConfig): method synthesize (line 34) | def synthesize( method _synthesize_segment (line 91) | def _synthesize_segment(self, segment: TTSDataSeg, output_path: str) -... method _synthesize (line 130) | def _synthesize(self, segment: TTSDataSeg, output_path: str) -> None: method _generate_cache_key_for_segment (line 139) | def _generate_cache_key_for_segment(self, segment: TTSDataSeg) -> str: method _generate_filename (line 167) | def _generate_filename(self, text: str, index: int) -> str: FILE: app/core/tts/openai_fm.py class OpenAIFmTTS (line 18) | class OpenAIFmTTS(BaseTTS): method __init__ (line 47) | def __init__(self, config: TTSConfig): method _synthesize (line 61) | def _synthesize(self, segment: TTSDataSeg, output_path: str) -> None: method _build_prompt (line 103) | def _build_prompt(self) -> str: method get_available_voices (line 117) | def get_available_voices(): method get_prompt_templates (line 126) | def get_prompt_templates(): FILE: app/core/tts/openai_tts.py class OpenAITTS (line 12) | class OpenAITTS(BaseTTS): method __init__ (line 18) | def __init__(self, config: TTSConfig): method _synthesize (line 34) | def _synthesize(self, segment: TTSDataSeg, output_path: str) -> None: FILE: app/core/tts/siliconflow.py class VoiceCloneManager (line 16) | class VoiceCloneManager: method __init__ (line 19) | def __init__(self, api_key: str, base_url: str): method upload_voice (line 30) | def upload_voice( method _generate_cache_key (line 97) | def _generate_cache_key(self, audio_path: str, text: str, model: str) ... class SiliconFlowTTS (line 106) | class SiliconFlowTTS(BaseTTS): method __init__ (line 112) | def __init__(self, config: TTSConfig): method _synthesize (line 125) | def _synthesize(self, segment: TTSDataSeg, output_path: str) -> None: FILE: app/core/tts/status.py class TTSStatus (line 5) | class TTSStatus(Enum): method message (line 26) | def message(self) -> str: method progress (line 31) | def progress(self) -> int: method with_progress (line 35) | def with_progress(self, progress: int) -> Tuple[int, str]: method callback_tuple (line 46) | def callback_tuple(self) -> Tuple[int, str]: FILE: app/core/tts/tts_data.py class TTSConfig (line 8) | class TTSConfig: class TTSDataSeg (line 32) | class TTSDataSeg: method __str__ (line 47) | def __str__(self) -> str: class TTSData (line 51) | class TTSData: method __init__ (line 54) | def __init__(self, segments: Optional[List[TTSDataSeg]] = None): method __iter__ (line 67) | def __iter__(self): method __len__ (line 71) | def __len__(self) -> int: method from_texts (line 76) | def from_texts( FILE: app/core/utils/cache.py function enable_cache (line 21) | def enable_cache() -> None: function disable_cache (line 27) | def disable_cache() -> None: function is_cache_enabled (line 33) | def is_cache_enabled() -> bool: function get_llm_cache (line 46) | def get_llm_cache() -> Cache: function get_asr_cache (line 51) | def get_asr_cache() -> Cache: function get_translate_cache (line 56) | def get_translate_cache() -> Cache: function get_tts_cache (line 61) | def get_tts_cache() -> Cache: function get_version_state_cache (line 66) | def get_version_state_cache() -> Cache: function memoize (line 71) | def memoize(cache_instance: Cache, **kwargs): function generate_cache_key (line 107) | def generate_cache_key(data: Any) -> str: FILE: app/core/utils/logger.py function setup_logger (line 8) | def setup_logger( FILE: app/core/utils/platform_utils.py function open_folder (line 15) | def open_folder(path): function open_file (line 41) | def open_file(path): function get_subprocess_kwargs (line 67) | def get_subprocess_kwargs(): function is_macos (line 84) | def is_macos() -> bool: function is_windows (line 94) | def is_windows() -> bool: function is_linux (line 104) | def is_linux() -> bool: function get_available_transcribe_models (line 114) | def get_available_transcribe_models() -> list[TranscribeModelEnum]: function is_model_available (line 134) | def is_model_available(model: TranscribeModelEnum) -> bool: FILE: app/core/utils/subprocess_helper.py class StreamReader (line 13) | class StreamReader: method __init__ (line 16) | def __init__(self, process: subprocess.Popen): method start_reading (line 27) | def start_reading(self) -> None: method _read_stream (line 49) | def _read_stream(self, stream, stream_name: str) -> None: method get_output (line 60) | def get_output(self, timeout: float = 0.1) -> Optional[Tuple[str, str]]: method get_remaining_output (line 75) | def get_remaining_output(self) -> list: method is_empty (line 85) | def is_empty(self) -> bool: function run_process_with_stream_reader (line 90) | def run_process_with_stream_reader( FILE: app/core/utils/text_utils.py function is_pure_punctuation (line 21) | def is_pure_punctuation(text: str) -> bool: function is_mainly_cjk (line 26) | def is_mainly_cjk(text: str, threshold: float = 0.5) -> bool: function is_space_separated_language (line 47) | def is_space_separated_language(text: str) -> bool: function count_words (line 72) | def count_words(text: str) -> int: FILE: app/core/utils/video_utils.py function temporary_subtitle_file (line 41) | def temporary_subtitle_file(subtitle_path: str): function video2audio (line 67) | def video2audio(input_file: str, output: str = "", audio_track_index: in... function check_cuda_available (line 131) | def check_cuda_available() -> bool: function add_subtitles (line 174) | def add_subtitles( function get_video_info (line 373) | def get_video_info( function _extract_thumbnail (line 481) | def _extract_thumbnail(video_path: str, seek_time: float, thumbnail_path... function add_subtitles_with_style (line 529) | def add_subtitles_with_style( FILE: app/thread/batch_process_thread.py class BatchTask (line 22) | class BatchTask: method __init__ (line 23) | def __init__(self, file_path: str, task_type: BatchTaskType): class BatchProcessThread (line 32) | class BatchProcessThread(QThread): method __init__ (line 38) | def __init__(self): method add_task (line 47) | def add_task(self, task: BatchTask): method run (line 54) | def run(self): method _process_task (line 73) | def _process_task(self, batch_task: BatchTask): method _on_progress_wrapper (line 95) | def _on_progress_wrapper(self, batch_task: BatchTask, progress: int, m... method _on_error_wrapper (line 99) | def _on_error_wrapper(self, batch_task: BatchTask, error: str): method _on_finished_wrapper (line 105) | def _on_finished_wrapper(self, batch_task: BatchTask, task=None): method _handle_transcribe_task (line 113) | def _handle_transcribe_task(self, batch_task: BatchTask): method _handle_subtitle_task (line 134) | def _handle_subtitle_task(self, batch_task: BatchTask): method _handle_trans_sub_task (line 156) | def _handle_trans_sub_task(self, batch_task: BatchTask): method _on_trans_sub_progress_wrapper (line 177) | def _on_trans_sub_progress_wrapper( method _on_trans_sub_finished_wrapper (line 184) | def _on_trans_sub_finished_wrapper( method _on_trans_sub_subtitle_progress_wrapper (line 212) | def _on_trans_sub_subtitle_progress_wrapper( method _handle_full_process_task (line 219) | def _handle_full_process_task(self, batch_task: BatchTask): method on_full_process_progress (line 236) | def on_full_process_progress( method on_full_process_finished (line 244) | def on_full_process_finished(self, batch_task: BatchTask, task: Transc... method on_full_process_subtitle_progress (line 273) | def on_full_process_subtitle_progress( method on_full_process_subtitle_finished (line 281) | def on_full_process_subtitle_finished( method on_full_process_synthesis_progress (line 304) | def on_full_process_synthesis_progress( method stop_task (line 312) | def stop_task(self, file_path: str): method stop_all (line 323) | def stop_all(self): FILE: app/thread/file_download_thread.py class BaseDownloader (line 16) | class BaseDownloader(ABC): method __init__ (line 19) | def __init__(self, url: str, save_path: Path, progress_callback): method download (line 26) | def download(self) -> bool: method cancel (line 30) | def cancel(self): class Aria2Downloader (line 35) | class Aria2Downloader(BaseDownloader): method __init__ (line 38) | def __init__(self, url: str, save_path: Path, progress_callback): method is_available (line 43) | def is_available() -> bool: method download (line 47) | def download(self) -> bool: method _parse_progress (line 103) | def _parse_progress(self, line: str): method cancel (line 124) | def cancel(self): class RequestsDownloader (line 131) | class RequestsDownloader(BaseDownloader): method download (line 136) | def download(self) -> bool: method _format_size (line 174) | def _format_size(bytes_size: int) -> str: class FileDownloadThread (line 184) | class FileDownloadThread(QThread): method __init__ (line 191) | def __init__(self, url: str, save_path: str): method run (line 197) | def run(self): method _on_progress (line 223) | def _on_progress(self, percent: float, status: str): method stop (line 227) | def stop(self): FILE: app/thread/modelscope_download_thread.py class SuppressOutput (line 11) | class SuppressOutput: method __enter__ (line 14) | def __enter__(self): method __exit__ (line 26) | def __exit__(self, *args): function create_progress_callback_class (line 33) | def create_progress_callback_class( class ModelscopeDownloadThread (line 55) | class ModelscopeDownloadThread(QThread): method __init__ (line 59) | def __init__(self, model_id: str, save_path: str): method run (line 64) | def run(self): function on_progress (line 93) | def on_progress(percentage, message): function on_error (line 96) | def on_error(error_msg): function on_finished (line 100) | def on_finished(): FILE: app/thread/subtitle_pipeline_thread.py class SubtitlePipelineThread (line 20) | class SubtitlePipelineThread(QThread): method __init__ (line 31) | def __init__(self, task: FullProcessTask): method run (line 36) | def run(self): FILE: app/thread/subtitle_thread.py class SubtitleThread (line 31) | class SubtitleThread(QThread): method __init__ (line 38) | def __init__(self, task: SubtitleTask): method set_custom_prompt_text (line 46) | def set_custom_prompt_text(self, text: str): method _setup_llm_config (line 49) | def _setup_llm_config(self) -> Optional[SubtitleConfig]: method run (line 72) | def run(self): method need_llm (line 250) | def need_llm(self, subtitle_config: SubtitleConfig, asr_data: ASRData): method callback (line 265) | def callback(self, result: List[SubtitleProcessData]): method stop (line 277) | def stop(self): FILE: app/thread/transcript_thread.py class TranscriptThread (line 15) | class TranscriptThread(QThread): method __init__ (line 20) | def __init__(self, task: TranscribeTask): method run (line 24) | def run(self): method _validate_task (line 42) | def _validate_task(self): method _check_downloaded_subtitle (line 58) | def _check_downloaded_subtitle(self) -> bool: method _perform_transcription (line 78) | def _perform_transcription(self): method progress_callback (line 147) | def progress_callback(self, value, message): FILE: app/thread/version_checker_thread.py class VersionChecker (line 15) | class VersionChecker(QObject): method __init__ (line 22) | def __init__(self): method get_latest_version_info (line 33) | def get_latest_version_info(self) -> dict: method has_new_version (line 67) | def has_new_version(self) -> bool: method check_announcement (line 95) | def check_announcement(self) -> None: method check_new_version_announcement (line 132) | def check_new_version_announcement(self) -> None: method perform_check (line 148) | def perform_check(self) -> None: FILE: app/thread/video_download_thread.py class VideoDownloadThread (line 15) | class VideoDownloadThread(QThread): method __init__ (line 24) | def __init__(self, url: str, work_dir: str): method run (line 29) | def run(self): method progress_hook (line 39) | def progress_hook(self, d): method sanitize_filename (line 59) | def sanitize_filename(self, name: str, replacement: str = "_") -> str: method download (line 115) | def download(self, need_subtitle: bool = True, need_thumbnail: bool = ... FILE: app/thread/video_info_thread.py class VideoInfoThread (line 13) | class VideoInfoThread(QThread): method __init__ (line 17) | def __init__(self, file_path): method run (line 21) | def run(self): FILE: app/thread/video_synthesis_thread.py class VideoSynthesisThread (line 15) | class VideoSynthesisThread(QThread): method __init__ (line 20) | def __init__(self, task: SynthesisTask): method run (line 25) | def run(self): method progress_callback (line 108) | def progress_callback(self, value, message): FILE: app/view/batch_process_interface.py class BatchProcessInterface (line 47) | class BatchProcessInterface(QWidget): method __init__ (line 48) | def __init__(self, parent=None): method init_ui (line 58) | def init_ui(self): method setup_connections (line 133) | def setup_connections(self): method on_add_file_clicked (line 143) | def on_add_file_clicked(self): method dragEnterEvent (line 165) | def dragEnterEvent(self, event): method dropEvent (line 171) | def dropEvent(self, event): method add_files (line 175) | def add_files(self, file_paths): method filter_files (line 248) | def filter_files(self, file_paths, task_type: BatchTaskType): method add_task_to_table (line 269) | def add_task_to_table(self, file_path): method show_context_menu (line 294) | def show_context_menu(self, pos): method open_output_folder (line 321) | def open_output_folder(self, file_path: str): method update_task_progress (line 336) | def update_task_progress(self, file_path: str, progress: int, status: ... method on_task_error (line 346) | def on_task_error(self, file_path: str, error: str): method on_task_completed (line 354) | def on_task_completed(self, file_path: str): method start_all_tasks (line 361) | def start_all_tasks(self): method start_task (line 406) | def start_task(self, file_path: str): method cancel_task (line 422) | def cancel_task(self, file_path: str): method clear_tasks (line 430) | def clear_tasks(self): method on_task_type_changed (line 434) | def on_task_type_changed(self, task_type: str): method closeEvent (line 448) | def closeEvent(self, event): method on_table_double_clicked (line 452) | def on_table_double_clicked(self, index): FILE: app/view/home_interface.py class HomeInterface (line 14) | class HomeInterface(QWidget): method __init__ (line 15) | def __init__(self, parent=None): method switch_to_transcription (line 73) | def switch_to_transcription(self, file_path): method switch_to_subtitle_optimization (line 85) | def switch_to_subtitle_optimization(self, file_path, video_path): method switch_to_video_synthesis (line 95) | def switch_to_video_synthesis(self, video_path, subtitle_path): method addSubInterface (line 106) | def addSubInterface(self, widget, objectName, text): method onCurrentIndexChanged (line 116) | def onCurrentIndexChanged(self, index): method closeEvent (line 122) | def closeEvent(self, event): FILE: app/view/llm_logs_interface.py class LogDetailDialog (line 38) | class LogDetailDialog(MessageBoxBase): method __init__ (line 41) | def __init__(self, log_entry: Dict[str, Any], parent=None): method _setup_ui (line 46) | def _setup_ui(self): method _copy_request (line 121) | def _copy_request(self): method _copy_response (line 136) | def _copy_response(self): class LLMLogsInterface (line 152) | class LLMLogsInterface(QWidget): method __init__ (line 155) | def __init__(self, parent=None): method _setup_ui (line 169) | def _setup_ui(self): method _setup_toolbar (line 178) | def _setup_toolbar(self): method _setup_table (line 197) | def _setup_table(self): method _setup_footer (line 244) | def _setup_footer(self): method _connect_signals (line 274) | def _connect_signals(self): method _setup_file_watcher (line 282) | def _setup_file_watcher(self): method _on_file_changed (line 292) | def _on_file_changed(self, path: str): method _on_dir_changed (line 299) | def _on_dir_changed(self, path: str): method _on_refresh_clicked (line 305) | def _on_refresh_clicked(self): method _load_logs (line 316) | def _load_logs(self): method _filter_logs (line 346) | def _filter_logs(self): method _update_table (line 375) | def _update_table(self): method _create_item (line 428) | def _create_item(self, text: str, align_left: bool = False) -> QTableW... method _show_detail (line 437) | def _show_detail(self, index): method _prev_page (line 444) | def _prev_page(self): method _next_page (line 449) | def _next_page(self): method _clear_logs (line 455) | def _clear_logs(self): FILE: app/view/log_window.py class LogWindow (line 13) | class LogWindow(QWidget): method __init__ (line 14) | def __init__(self, parent=None): method load_last_lines (line 79) | def load_last_lines(self, read_size): method on_scroll_changed (line 123) | def on_scroll_changed(self, value): method update_log (line 129) | def update_log(self): method open_log_folder (line 158) | def open_log_folder(self): FILE: app/view/main_window.py class MainWindow (line 33) | class MainWindow(FluentWindow): method __init__ (line 34) | def __init__(self): method initNavigation (line 65) | def initNavigation(self): method switchTo (line 93) | def switchTo(self, interface): method initWindow (line 100) | def initWindow(self): method onGithubDialog (line 122) | def onGithubDialog(self): method onNewVersion (line 140) | def onNewVersion(self, version, update_required, update_info, download... method onAnnouncement (line 168) | def onAnnouncement(self, content): method resizeEvent (line 175) | def resizeEvent(self, e): method closeEvent (line 180) | def closeEvent(self, event): method stop (line 195) | def stop(self): method _check_ffmpeg (line 201) | def _check_ffmpeg(self): FILE: app/view/setting_interface.py class SettingInterface (line 40) | class SettingInterface(ScrollArea): method __init__ (line 43) | def __init__(self, parent=None): method __initGroups (line 61) | def __initGroups(self): method __initCards (line 84) | def __initCards(self): method __createLLMServiceCards (line 261) | def __createLLMServiceCards(self): method __createASRServiceCards (line 429) | def __createASRServiceCards(self): method __createTranslateServiceCards (line 490) | def __createTranslateServiceCards(self): method __initWidget (line 557) | def __initWidget(self): method __initLayout (line 594) | def __initLayout(self): method __connectSignalToSlot (line 627) | def __connectSignalToSlot(self): method __showRestartTooltip (line 695) | def __showRestartTooltip(self): method __onsavePathCardClicked (line 704) | def __onsavePathCardClicked(self): method __onCacheEnabledChanged (line 712) | def __onCacheEnabledChanged(self, is_enabled: bool): method checkLLMConnection (line 731) | def checkLLMConnection(self): method onConnectionCheckError (line 773) | def onConnectionCheckError(self, message): method onConnectionCheckFinished (line 784) | def onConnectionCheckFinished(self, is_success, message, models): method checkUpdate (line 821) | def checkUpdate(self): method __onLLMServiceChanged (line 824) | def __onLLMServiceChanged(self, service): method __onTranslatorServiceChanged (line 863) | def __onTranslatorServiceChanged(self, service): method __onTranscribeModelChanged (line 886) | def __onTranscribeModelChanged(self, model_name): method checkWhisperConnection (line 905) | def checkWhisperConnection(self): method onWhisperConnectionCheckFinished (line 960) | def onWhisperConnectionCheckFinished(self, success, result): method onWhisperConnectionCheckError (line 981) | def onWhisperConnectionCheckError(self, message): class WhisperConnectionThread (line 995) | class WhisperConnectionThread(QThread): method __init__ (line 1001) | def __init__(self, base_url, api_key, model): method run (line 1007) | def run(self): class LLMConnectionThread (line 1018) | class LLMConnectionThread(QThread): method __init__ (line 1022) | def __init__(self, api_base, api_key, model): method run (line 1028) | def run(self): FILE: app/view/subtitle_interface.py class SubtitleTableModel (line 61) | class SubtitleTableModel(QAbstractTableModel): method __init__ (line 62) | def __init__(self, data: Union[str, Dict[str, Any]] = ""): method load_data (line 70) | def load_data(self, data: str): method data (line 78) | def data(self, index: QModelIndex, role: int = Qt.DisplayRole) -> Any:... method setData (line 111) | def setData(self, index: QModelIndex, value: Any, role: int = Qt.EditR... method headerData (line 134) | def headerData( method rowCount (line 158) | def rowCount(self, parent: Optional[QModelIndex] = None) -> int: method columnCount (line 161) | def columnCount(self, parent: Optional[QModelIndex] = None) -> int: method flags (line 164) | def flags(self, index: QModelIndex) -> Qt.ItemFlags: method update_data (line 171) | def update_data(self, new_data: Dict[str, str]) -> None: method update_all (line 190) | def update_all(self, data: Dict[str, Any]) -> None: class SubtitleInterface (line 196) | class SubtitleInterface(QWidget): method __init__ (line 199) | def __init__(self, parent: Optional[QWidget] = None): method _init_ui (line 211) | def _init_ui(self): method set_values (line 220) | def set_values(self): method _setup_top_layout (line 229) | def _setup_top_layout(self): method _setup_subtitle_table (line 352) | def _setup_subtitle_table(self): method _setup_bottom_layout (line 386) | def _setup_bottom_layout(self): method _setup_signals (line 403) | def _setup_signals(self) -> None: method show_prompt_dialog (line 415) | def show_prompt_dialog(self) -> None: method _update_prompt_button_style (line 421) | def _update_prompt_button_style(self) -> None: method set_task (line 430) | def set_task(self, task: SubtitleTask) -> None: method update_info (line 439) | def update_info(self, task: SubtitleTask) -> None: method start_subtitle_optimization (line 449) | def start_subtitle_optimization(self, need_create_task: bool = True) -... method process (line 490) | def process(self) -> None: method on_subtitle_optimization_finished (line 495) | def on_subtitle_optimization_finished( method on_subtitle_optimization_error (line 511) | def on_subtitle_optimization_error(self, error: str) -> None: method on_subtitle_optimization_progress (line 522) | def on_subtitle_optimization_progress(self, value: int, status: str) -... method update_data (line 526) | def update_data(self, data): method update_all (line 529) | def update_all(self, data): method remove_widget (line 532) | def remove_widget(self) -> None: method on_file_select (line 542) | def on_file_select(self) -> None: method on_save_format_clicked (line 556) | def on_save_format_clicked(self, format: str) -> None: method on_open_folder_clicked (line 602) | def on_open_folder_clicked(self) -> None: method load_subtitle_file (line 625) | def load_subtitle_file(self, file_path: str) -> None: method dragEnterEvent (line 632) | def dragEnterEvent(self, event: QDragEnterEvent) -> None: method dropEvent (line 635) | def dropEvent(self, event: QDropEvent) -> None: method closeEvent (line 666) | def closeEvent(self, event: QCloseEvent) -> None: method show_subtitle_settings (line 671) | def show_subtitle_settings(self) -> None: method show_video_player (line 676) | def show_video_player(self) -> None: method on_subtitle_clicked (line 717) | def on_subtitle_clicked(self, index: QModelIndex) -> None: method show_context_menu (line 728) | def show_context_menu(self, pos) -> None: method merge_selected_rows (line 760) | def merge_selected_rows(self, rows: List[int]) -> None: method keyPressEvent (line 823) | def keyPressEvent(self, event: QKeyEvent) -> None: method cancel_optimization (line 836) | def cancel_optimization(self) -> None: method on_target_language_changed (line 852) | def on_target_language_changed(self, language: str) -> None: method on_subtitle_optimization_changed (line 860) | def on_subtitle_optimization_changed(self, checked: bool) -> None: method on_subtitle_translation_changed (line 865) | def on_subtitle_translation_changed(self, checked: bool) -> None: method on_subtitle_layout_changed (line 872) | def on_subtitle_layout_changed(self, layout: str) -> None: class PromptDialog (line 879) | class PromptDialog(MessageBoxBase): method __init__ (line 880) | def __init__(self, parent: Optional[QWidget] = None): method setup_ui (line 887) | def setup_ui(self) -> None: method get_prompt (line 919) | def get_prompt(self) -> str: method save_prompt (line 922) | def save_prompt(self) -> None: FILE: app/view/subtitle_style_interface.py class AssPreviewThread (line 62) | class AssPreviewThread(QThread): method __init__ (line 67) | def __init__( method run (line 82) | def run(self): class RoundedBgPreviewThread (line 93) | class RoundedBgPreviewThread(QThread): method __init__ (line 98) | def __init__( method run (line 114) | def run(self): class SubtitleStyleInterface (line 126) | class SubtitleStyleInterface(QWidget): method __init__ (line 127) | def __init__(self, parent=None): method _initSettingsArea (line 152) | def _initSettingsArea(self): method _initPreviewArea (line 180) | def _initPreviewArea(self): method _initSettingCards (line 230) | def _initSettingCards(self): method _initLayout (line 455) | def _initLayout(self): method _initStyle (line 506) | def _initStyle(self): method __setValues (line 521) | def __setValues(self): method connectSignals (line 599) | def connectSignals(self): method on_open_style_folder_clicked (line 686) | def on_open_style_folder_clicked(self): method on_subtitle_layout_changed (line 690) | def on_subtitle_layout_changed(self, layout: str): method on_render_mode_changed_external (line 695) | def on_render_mode_changed_external(self, mode_text: str): method onRenderModeChanged (line 706) | def onRenderModeChanged(self): method onRoundedBgSettingChanged (line 719) | def onRoundedBgSettingChanged(self): method _updateVisibleGroups (line 756) | def _updateVisibleGroups(self): method _getStyleFileExtension (line 769) | def _getStyleFileExtension(self) -> str: method _refreshStyleList (line 774) | def _refreshStyleList(self): method _getCurrentRenderMode (line 811) | def _getCurrentRenderMode(self) -> SubtitleRenderModeEnum: method _parseRgbaHex (line 816) | def _parseRgbaHex(self, hex_color: str) -> QColor: method onOrientationChanged (line 829) | def onOrientationChanged(self): method onAssSettingChanged (line 838) | def onAssSettingChanged(self): method selectPreviewImage (line 850) | def selectPreviewImage(self): method generateAssStyles (line 862) | def generateAssStyles(self) -> str: method updatePreview (line 900) | def updatePreview(self): method onPreviewReady (line 967) | def onPreviewReady(self, preview_path): method updatePreviewImage (line 972) | def updatePreviewImage(self): method resizeEvent (line 981) | def resizeEvent(self, event): method showEvent (line 985) | def showEvent(self, event): method loadStyle (line 990) | def loadStyle(self, style_name): method _loadAssStyle (line 1020) | def _loadAssStyle(self, style_path: Path): method _loadRoundedBgStyle (line 1088) | def _loadRoundedBgStyle(self, style_path: Path): method createNewStyle (line 1114) | def createNewStyle(self): method saveStyle (line 1153) | def saveStyle(self, style_name): method _saveAssStyle (line 1166) | def _saveAssStyle(self, style_path: Path): method _saveRoundedBgStyle (line 1172) | def _saveRoundedBgStyle(self, style_path: Path): method dragEnterEvent (line 1192) | def dragEnterEvent(self, event): method dropEvent (line 1203) | def dropEvent(self, event): class StyleNameDialog (line 1226) | class StyleNameDialog(MessageBoxBase): method __init__ (line 1229) | def __init__(self, parent=None): method _validateInput (line 1249) | def _validateInput(self, text): FILE: app/view/task_creation_interface.py class TaskCreationInterface (line 46) | class TaskCreationInterface(QWidget): method __init__ (line 53) | def __init__(self, parent=None): method setup_ui (line 66) | def setup_ui(self): method setup_logo (line 76) | def setup_logo(self): method setup_search_layout (line 91) | def setup_search_layout(self): method setup_status_layout (line 142) | def setup_status_layout(self): method setup_info_label (line 158) | def setup_info_label(self): method setup_signals (line 207) | def setup_signals(self): method setup_values (line 213) | def setup_values(self): method on_start_clicked (line 216) | def on_start_clicked(self): method on_search_input_changed (line 237) | def on_search_input_changed(self): method dragEnterEvent (line 243) | def dragEnterEvent(self, event): method dropEvent (line 246) | def dropEvent(self, event): method create_task (line 278) | def create_task(self): method _is_valid_url (line 292) | def _is_valid_url(self, url): method _process_file (line 299) | def _process_file(self, file_path): method _process_url (line 302) | def _process_url(self, url): method on_video_download_finished (line 327) | def on_video_download_finished(self, video_file_path): method on_create_task_progress (line 346) | def on_create_task_progress(self, value, status): method on_create_task_error (line 352) | def on_create_task_error(self, error): method set_task (line 360) | def set_task(self, task): method update_info (line 364) | def update_info(self): method process (line 368) | def process(self): method show_log_window (line 383) | def show_log_window(self): method show_donate_dialog (line 392) | def show_donate_dialog(self): FILE: app/view/transcription_interface.py class VideoInfoCard (line 61) | class VideoInfoCard(CardWidget): method __init__ (line 64) | def __init__(self, parent: Optional[QWidget] = None): method setup_ui (line 73) | def setup_ui(self) -> None: method setup_thumbnail (line 83) | def setup_thumbnail(self) -> None: method setup_info_layout (line 98) | def setup_info_layout(self) -> None: method create_pill_button (line 131) | def create_pill_button(self, text: str, width: int) -> PillPushButton: method setup_button_layout (line 139) | def setup_button_layout(self) -> None: method update_info (line 153) | def update_info(self, video_info: VideoInfo) -> None: method update_audio_tracks (line 176) | def update_audio_tracks(self, video_info: VideoInfo) -> None: method update_audio_track_button_text (line 216) | def update_audio_track_button_text( method on_audio_track_selected (line 233) | def on_audio_track_selected(self, array_index: int, audio_streams: lis... method update_thumbnail (line 243) | def update_thumbnail(self, thumbnail_path): method setup_signals (line 255) | def setup_signals(self) -> None: method on_start_button_clicked (line 259) | def on_start_button_clicked(self): method on_open_folder_clicked (line 266) | def on_open_folder_clicked(self): method start_transcription (line 284) | def start_transcription(self, need_create_task=True): method on_transcript_progress (line 304) | def on_transcript_progress(self, value, message): method on_transcript_error (line 309) | def on_transcript_error(self, error): method on_transcript_finished (line 322) | def on_transcript_finished(self, task): method reset_ui (line 329) | def reset_ui(self): method set_task (line 336) | def set_task(self, task): method stop (line 341) | def stop(self): class TranscriptionInterface (line 346) | class TranscriptionInterface(QWidget): method __init__ (line 351) | def __init__(self, parent: Optional[QWidget] = None): method _init_ui (line 362) | def _init_ui(self) -> None: method _setup_command_bar (line 378) | def _setup_command_bar(self): method _setup_signals (line 430) | def _setup_signals(self) -> None: method _show_output_settings (line 447) | def _show_output_settings(self): method _set_value (line 452) | def _set_value(self) -> None: method on_transcription_model_changed (line 458) | def on_transcription_model_changed(self, model_name: str): method _on_transcript_finished (line 467) | def _on_transcript_finished(self, task: TranscribeTask): method _on_file_select (line 481) | def _on_file_select(self): method update_info (line 496) | def update_info(self, file_path): method _on_video_info_error (line 503) | def _on_video_info_error(self, error_msg): method set_task (line 513) | def set_task(self, task: TranscribeTask) -> None: method process (line 519) | def process(self): method dragEnterEvent (line 524) | def dragEnterEvent(self, event): method dropEvent (line 528) | def dropEvent(self, event): method closeEvent (line 569) | def closeEvent(self, event): FILE: app/view/video_synthesis_interface.py class VideoSynthesisInterface (line 47) | class VideoSynthesisInterface(QWidget): method __init__ (line 50) | def __init__(self, parent=None): method setup_ui (line 63) | def setup_ui(self): method _setup_command_bar (line 133) | def _setup_command_bar(self): method setup_style (line 214) | def setup_style(self): method setup_signals (line 257) | def setup_signals(self): method set_value (line 274) | def set_value(self): method on_soft_subtitle_action_triggered (line 285) | def on_soft_subtitle_action_triggered(self, checked: bool): method on_soft_subtitle_changed (line 312) | def on_soft_subtitle_changed(self, checked: bool): method on_need_video_action_triggered (line 316) | def on_need_video_action_triggered(self, checked: bool): method on_need_video_changed (line 339) | def on_need_video_changed(self, checked: bool): method on_video_quality_action_changed (line 344) | def on_video_quality_action_changed(self, quality_text: str): method on_video_quality_changed (line 359) | def on_video_quality_changed(self, quality_text: str): method on_use_style_action_triggered (line 363) | def on_use_style_action_triggered(self, checked: bool): method on_use_style_changed (line 389) | def on_use_style_changed(self, checked: bool): method on_render_mode_changed (line 394) | def on_render_mode_changed(self, mode_text: str): method on_render_mode_changed_external (line 406) | def on_render_mode_changed_external(self, mode_text: str): method _update_synthesis_controls_state (line 410) | def _update_synthesis_controls_state(self): method _update_style_controls_state (line 422) | def _update_style_controls_state(self): method choose_subtitle_file (line 429) | def choose_subtitle_file(self): method choose_video_file (line 442) | def choose_video_file(self): method create_task (line 453) | def create_task(self): method set_task (line 467) | def set_task(self, task: SynthesisTask): method update_info (line 471) | def update_info(self): method start_video_synthesis (line 476) | def start_video_synthesis(self, need_create_task=True): method process (line 496) | def process(self): method on_video_synthesis_finished (line 499) | def on_video_synthesis_finished(self, task): method on_video_synthesis_progress (line 511) | def on_video_synthesis_progress(self, progress, message): method on_video_synthesis_error (line 515) | def on_video_synthesis_error(self, error): method open_video_folder (line 526) | def open_video_folder(self): method dragEnterEvent (line 549) | def dragEnterEvent(self, event): method dropEvent (line 553) | def dropEvent(self, event: QDropEvent): FILE: docs/.vitepress/theme/index.ts method enhanceApp (line 7) | enhanceApp({ app }) { FILE: main.py function exception_hook (line 45) | def exception_hook(exctype, value, tb): function main (line 83) | def main(): FILE: scripts/translate_llm.py class Translation (line 77) | class Translation(BaseModel): class TranslationBatch (line 85) | class TranslationBatch(BaseModel): function detect_target_language (line 111) | def detect_target_language(filename: str) -> str: function translate_batch (line 133) | def translate_batch( function translate_file (line 188) | def translate_file(ts_file: Path, target_lang: str) -> None: function main (line 277) | def main(): FILE: tests/conftest.py function sample_asr_data (line 50) | def sample_asr_data(): function sample_translate_data (line 77) | def sample_translate_data(): function target_language (line 95) | def target_language(): function check_env_vars (line 110) | def check_env_vars(): function expected_translations (line 136) | def expected_translations() -> Dict[str, Dict[str, List[str]]]: function mock_llm_client (line 185) | def mock_llm_client(monkeypatch): function assert_translation_quality (line 390) | def assert_translation_quality( FILE: tests/test_asr/conftest.py function test_audio_path (line 17) | def test_audio_path() -> Path: function test_audio_path_zh (line 41) | def test_audio_path_zh() -> Path: function test_audio_path_en (line 65) | def test_audio_path_en() -> Path: function assert_asr_result_valid (line 88) | def assert_asr_result_valid(result, min_segments: int = 0) -> None: FILE: tests/test_asr/test_asr_data.py class TestASRDataSegEdgeCases (line 11) | class TestASRDataSegEdgeCases: method test_zero_duration_segment (line 14) | def test_zero_duration_segment(self): method test_negative_duration (line 21) | def test_negative_duration(self): method test_very_long_timestamp (line 26) | def test_very_long_timestamp(self): method test_unicode_text_extreme (line 32) | def test_unicode_text_extreme(self): method test_empty_translation (line 39) | def test_empty_translation(self): method test_multiline_text (line 45) | def test_multiline_text(self): class TestASRDataEdgeCases (line 53) | class TestASRDataEdgeCases: method test_mixed_empty_and_whitespace (line 56) | def test_mixed_empty_and_whitespace(self): method test_overlapping_timestamps (line 69) | def test_overlapping_timestamps(self): method test_unsorted_large_dataset (line 81) | def test_unsorted_large_dataset(self): method test_duplicate_timestamps (line 93) | def test_duplicate_timestamps(self): method test_single_segment (line 103) | def test_single_segment(self): class TestWordTimestampEdgeCases (line 112) | class TestWordTimestampEdgeCases: method test_exactly_80_percent_threshold (line 115) | def test_exactly_80_percent_threshold(self): method test_79_percent_below_threshold (line 128) | def test_79_percent_below_threshold(self): method test_mixed_cjk_latin_single_chars (line 142) | def test_mixed_cjk_latin_single_chars(self): method test_three_char_cjk (line 153) | def test_three_char_cjk(self): class TestSplitToWordsEdgeCases (line 160) | class TestSplitToWordsEdgeCases: method test_split_empty_text (line 163) | def test_split_empty_text(self): method test_split_only_punctuation (line 170) | def test_split_only_punctuation(self): method test_split_very_long_word (line 177) | def test_split_very_long_word(self): method test_split_mixed_scripts (line 186) | def test_split_mixed_scripts(self): method test_split_numbers_and_words (line 199) | def test_split_numbers_and_words(self): method test_split_thai_with_combining_chars (line 210) | def test_split_thai_with_combining_chars(self): method test_split_zero_duration_distribution (line 218) | def test_split_zero_duration_distribution(self): class TestMergeEdgeCases (line 228) | class TestMergeEdgeCases: method test_merge_single_segment (line 231) | def test_merge_single_segment(self): method test_merge_all_segments (line 239) | def test_merge_all_segments(self): method test_merge_invalid_indices (line 248) | def test_merge_invalid_indices(self): method test_merge_with_next_at_boundary (line 260) | def test_merge_with_next_at_boundary(self): method test_merge_with_unicode (line 268) | def test_merge_with_unicode(self): class TestOptimizeTimingEdgeCases (line 280) | class TestOptimizeTimingEdgeCases: method test_optimize_negative_gap (line 283) | def test_optimize_negative_gap(self): method test_optimize_exact_threshold (line 294) | def test_optimize_exact_threshold(self): method test_optimize_word_level_no_change (line 306) | def test_optimize_word_level_no_change(self): class TestRemovePunctuationEdgeCases (line 320) | class TestRemovePunctuationEdgeCases: method test_remove_multiple_punctuation (line 323) | def test_remove_multiple_punctuation(self): method test_remove_punctuation_only (line 330) | def test_remove_punctuation_only(self): method test_remove_punctuation_middle (line 337) | def test_remove_punctuation_middle(self): method test_remove_non_chinese_punctuation (line 344) | def test_remove_non_chinese_punctuation(self): class TestFormatConversionEdgeCases (line 352) | class TestFormatConversionEdgeCases: method test_srt_layout_modes_all (line 355) | def test_srt_layout_modes_all(self): method test_srt_no_translation_all_layouts (line 375) | def test_srt_no_translation_all_layouts(self): method test_json_large_dataset (line 384) | def test_json_large_dataset(self): method test_txt_multiline_segments (line 395) | def test_txt_multiline_segments(self): class TestFileIOEdgeCases (line 406) | class TestFileIOEdgeCases: method test_save_unsupported_format (line 409) | def test_save_unsupported_format(self): method test_load_nonexistent_file (line 423) | def test_load_nonexistent_file(self): method test_save_load_unicode_path (line 428) | def test_save_load_unicode_path(self): class TestParseEdgeCases (line 440) | class TestParseEdgeCases: method test_parse_malformed_srt (line 443) | def test_parse_malformed_srt(self): method test_parse_srt_missing_text (line 456) | def test_parse_srt_missing_text(self): method test_parse_srt_97_percent_translation (line 469) | def test_parse_srt_97_percent_translation(self): method test_parse_json_non_numeric_keys (line 487) | def test_parse_json_non_numeric_keys(self): method test_parse_vtt_empty_blocks (line 500) | def test_parse_vtt_empty_blocks(self): FILE: tests/test_asr/test_bcut_asr.py class TestBcutASR (line 14) | class TestBcutASR: method bcut_asr_sentence (line 22) | def bcut_asr_sentence(self, test_audio_path: Path) -> BcutASR: method bcut_asr_word (line 37) | def bcut_asr_word(self, test_audio_path: Path) -> BcutASR: method test_transcribe_parametrized (line 104) | def test_transcribe_parametrized( FILE: tests/test_asr/test_chunk_merger.py function create_sentence_segments (line 16) | def create_sentence_segments(sentences, start_time=0): function create_word_level_segments (line 31) | def create_word_level_segments(words, start_time=0, is_chinese=True): class TestSentenceLevelMerging (line 66) | class TestSentenceLevelMerging: method merger (line 70) | def merger(self): method test_chinese_podcast_perfect_overlap (line 73) | def test_chinese_podcast_perfect_overlap(self, merger): method test_english_lecture_perfect_overlap (line 112) | def test_english_lecture_perfect_overlap(self, merger): method test_no_overlap_sequential_chunks (line 142) | def test_no_overlap_sequential_chunks(self, merger): method test_three_chunks_continuous_merge (line 159) | def test_three_chunks_continuous_merge(self, merger): class TestASRErrorCases (line 198) | class TestASRErrorCases: method merger (line 202) | def merger(self): method test_homophone_error_chinese (line 205) | def test_homophone_error_chinese(self, merger): method test_punctuation_difference_english (line 232) | def test_punctuation_difference_english(self, merger): method test_partial_match_only_one_sentence (line 266) | def test_partial_match_only_one_sentence(self, merger): method test_complete_mismatch_noise_in_overlap (line 292) | def test_complete_mismatch_noise_in_overlap(self, merger): method test_filler_words_different_recognition (line 318) | def test_filler_words_different_recognition(self, merger): class TestWordLevelMerging (line 358) | class TestWordLevelMerging: method merger (line 362) | def merger(self): method test_chinese_word_level_perfect_overlap (line 365) | def test_chinese_word_level_perfect_overlap(self, merger): method test_english_word_level_perfect_overlap (line 391) | def test_english_word_level_perfect_overlap(self, merger): method test_chinese_word_level_partial_match (line 415) | def test_chinese_word_level_partial_match(self, merger): method test_english_word_level_capitalization_difference (line 442) | def test_english_word_level_capitalization_difference(self, merger): class TestMixedLanguage (line 473) | class TestMixedLanguage: method merger (line 477) | def merger(self): method test_tech_talk_chinese_english_mixed (line 480) | def test_tech_talk_chinese_english_mixed(self, merger): method test_product_name_mixed_word_level (line 508) | def test_product_name_mixed_word_level(self, merger): class TestEdgeCases (line 541) | class TestEdgeCases: method merger (line 545) | def merger(self): method test_empty_chunk (line 548) | def test_empty_chunk(self, merger): method test_single_word_segments (line 562) | def test_single_word_segments(self, merger): method test_identical_chunks_100_percent_overlap (line 576) | def test_identical_chunks_100_percent_overlap(self, merger): method test_very_long_overlap_90_percent (line 594) | def test_very_long_overlap_90_percent(self, merger): class TestLongSequences (line 620) | class TestLongSequences: method merger (line 624) | def merger(self): method test_10_chunks_continuous_chinese (line 627) | def test_10_chunks_continuous_chinese(self, merger): method test_very_long_text_word_level_english (line 666) | def test_very_long_text_word_level_english(self, merger): class TestOutputFormat (line 696) | class TestOutputFormat: method merger (line 700) | def merger(self): method test_output_has_valid_timestamps (line 703) | def test_output_has_valid_timestamps(self, merger): method test_can_save_to_srt (line 720) | def test_can_save_to_srt(self, merger, tmp_path): class TestStrictMode (line 751) | class TestStrictMode: method strict_merger (line 755) | def strict_merger(self): method test_insufficient_overlap_fallback_to_time (line 758) | def test_insufficient_overlap_fallback_to_time(self, strict_merger): method test_sufficient_overlap_merge_normally (line 779) | def test_sufficient_overlap_merge_normally(self, strict_merger): FILE: tests/test_asr/test_chunked_asr.py class MockASR (line 33) | class MockASR(BaseASR): method __init__ (line 42) | def __init__( method _run (line 55) | def _run( method _make_segments (line 87) | def _make_segments(self, resp_data: dict) -> List[ASRDataSeg]: function create_test_audio_file (line 99) | def create_test_audio_file(duration_sec: int = 60) -> str: class TestChunkedASRBasics (line 124) | class TestChunkedASRBasics: method test_init_default_params (line 127) | def test_init_default_params(self): method test_init_custom_params (line 143) | def test_init_custom_params(self): method test_short_audio_no_chunking (line 163) | def test_short_audio_no_chunking(self): method test_long_audio_with_chunking (line 185) | def test_long_audio_with_chunking(self): class TestAudioSplitting (line 215) | class TestAudioSplitting: method test_split_exact_chunks (line 218) | def test_split_exact_chunks(self): method test_split_with_overlap (line 238) | def test_split_with_overlap(self): method test_split_remainder_chunk (line 262) | def test_split_remainder_chunk(self): class TestConcurrentTranscription (line 289) | class TestConcurrentTranscription: method test_concurrency_3_workers (line 292) | def test_concurrency_3_workers(self): method test_independent_asr_instances (line 314) | def test_independent_asr_instances(self): class TestChunkMerging (line 345) | class TestChunkMerging: method test_merge_preserves_order (line 348) | def test_merge_preserves_order(self): class TestEdgeCases (line 371) | class TestEdgeCases: method test_very_short_audio (line 374) | def test_very_short_audio(self): method test_zero_overlap (line 386) | def test_zero_overlap(self): class TestErrorHandling (line 411) | class TestErrorHandling: method test_asr_failure_propagates (line 414) | def test_asr_failure_propagates(self): class TestProgressCallback (line 436) | class TestProgressCallback: method test_callback_invoked (line 439) | def test_callback_invoked(self): class TestIntegration (line 468) | class TestIntegration: method test_full_pipeline_short_audio (line 471) | def test_full_pipeline_short_audio(self): method test_full_pipeline_long_audio (line 491) | def test_full_pipeline_long_audio(self): FILE: tests/test_asr/test_chunking.py class MockASR (line 27) | class MockASR(BaseASR): method __init__ (line 33) | def __init__( method _run (line 56) | def _run( method _make_segments (line 98) | def _make_segments(self, resp_data: dict) -> List[ASRDataSeg]: method _get_subclass_params (line 109) | def _get_subclass_params(self) -> dict: function create_test_audio (line 122) | def create_test_audio(duration_ms: int, frequency: int = 440) -> bytes: function create_test_audio_file (line 141) | def create_test_audio_file(duration_sec: int) -> str: class TestAudioSplitting (line 168) | class TestAudioSplitting: method test_split_long_audio_into_chunks (line 171) | def test_split_long_audio_into_chunks(self): method test_split_short_audio_no_chunks (line 205) | def test_split_short_audio_no_chunks(self): method test_split_exact_chunk_length (line 230) | def test_split_exact_chunk_length(self): method test_split_with_zero_overlap (line 251) | def test_split_with_zero_overlap(self): FILE: tests/test_asr/test_jianying_asr.py class TestJianYingASR (line 14) | class TestJianYingASR: method test_transcribe_parametrized (line 106) | def test_transcribe_parametrized( FILE: tests/test_asr/test_whisper_api_asr.py class TestWhisperAPI (line 14) | class TestWhisperAPI: method skip_if_no_env (line 18) | def skip_if_no_env(self, check_env_vars) -> None: method test_chinese_word_timestamp (line 26) | def test_chinese_word_timestamp(self, test_audio_path_zh: Path) -> None: method test_transcribe_parametrized (line 65) | def test_transcribe_parametrized( FILE: tests/test_optimize/test_optimize.py class TestSubtitleOptimizer (line 19) | class TestSubtitleOptimizer: method optimizer (line 23) | def optimizer(self, mock_llm_client) -> SubtitleOptimizer: method sample_asr_data (line 34) | def sample_asr_data(self) -> ASRData: method test_optimize_basic (line 55) | def test_optimize_basic( method test_agent_loop_validation (line 84) | def test_agent_loop_validation( method test_optimize_empty_handling (line 107) | def test_optimize_empty_handling(self, optimizer: SubtitleOptimizer): FILE: tests/test_split/test_alignment.py class TestSubtitleAligner (line 11) | class TestSubtitleAligner: method aligner (line 15) | def aligner(self) -> SubtitleAligner: method test_align_identical_texts (line 19) | def test_align_identical_texts(self, aligner): method test_align_with_missing_items (line 30) | def test_align_with_missing_items(self, aligner): method test_align_with_extra_items (line 43) | def test_align_with_extra_items(self, aligner): method test_align_empty_texts (line 56) | def test_align_empty_texts(self, aligner): method test_align_single_item (line 66) | def test_align_single_item(self, aligner): method test_align_completely_different_texts (line 76) | def test_align_completely_different_texts(self, aligner): method test_align_chinese_text (line 87) | def test_align_chinese_text(self, aligner): FILE: tests/test_split/test_split.py class TestPreprocessEdgeCases (line 12) | class TestPreprocessEdgeCases: method test_unicode_extremes (line 15) | def test_unicode_extremes(self): method test_mixed_punctuation_types (line 29) | def test_mixed_punctuation_types(self): method test_zero_duration_segments (line 40) | def test_zero_duration_segments(self): method test_overlapping_timestamps (line 49) | def test_overlapping_timestamps(self): method test_reversed_timestamps (line 59) | def test_reversed_timestamps(self): method test_very_long_text (line 67) | def test_very_long_text(self): method test_whitespace_only_segments (line 75) | def test_whitespace_only_segments(self): method test_mixed_case_with_numbers (line 87) | def test_mixed_case_with_numbers(self): method test_special_characters (line 96) | def test_special_characters(self): method test_newlines_and_tabs_in_text (line 106) | def test_newlines_and_tabs_in_text(self): class TestSubtitleSplitterEdgeCases (line 115) | class TestSubtitleSplitterEdgeCases: method test_extremely_short_segments (line 118) | def test_extremely_short_segments(self): method test_extremely_long_single_segment (line 133) | def test_extremely_long_single_segment(self): method test_alternating_long_short_segments (line 147) | def test_alternating_long_short_segments(self): method test_all_same_timestamp (line 170) | def test_all_same_timestamp(self): method test_large_time_gaps (line 183) | def test_large_time_gaps(self): method test_1000_segments_stress (line 197) | def test_1000_segments_stress(self): method test_mixed_language_segments (line 215) | def test_mixed_language_segments(self): method test_numbers_only_segments (line 230) | def test_numbers_only_segments(self): method test_repeated_text_segments (line 245) | def test_repeated_text_segments(self): class TestSplitterParameters (line 260) | class TestSplitterParameters: method test_max_word_count_zero (line 263) | def test_max_word_count_zero(self): method test_max_word_count_very_large (line 278) | def test_max_word_count_very_large(self): method test_max_word_count_exactly_matches (line 290) | def test_max_word_count_exactly_matches(self): class TestMergeShortSegments (line 303) | class TestMergeShortSegments: method test_all_segments_very_short (line 306) | def test_all_segments_very_short(self): method test_mixed_short_and_long (line 319) | def test_mixed_short_and_long(self): method test_alternating_short_long_pattern (line 336) | def test_alternating_short_long_pattern(self): class TestStopAndThreading (line 359) | class TestStopAndThreading: method test_stop_before_start (line 362) | def test_stop_before_start(self): method test_stop_during_processing (line 370) | def test_stop_during_processing(self): method test_multiple_stop_calls (line 393) | def test_multiple_stop_calls(self): class TestTimestampIntegrity (line 404) | class TestTimestampIntegrity: method test_no_negative_durations (line 407) | def test_no_negative_durations(self): method test_no_gaps_in_timeline (line 422) | def test_no_gaps_in_timeline(self): method test_preserves_total_duration (line 440) | def test_preserves_total_duration(self): FILE: tests/test_split/test_split_by_llm.py class TestSplitByLLM (line 18) | class TestSplitByLLM: method test_count_words_chinese (line 21) | def test_count_words_chinese(self): method test_count_words_english (line 26) | def test_count_words_english(self): method test_count_words_mixed (line 31) | def test_count_words_mixed(self): method test_split_chinese_text (line 37) | def test_split_chinese_text(self, mock_llm_client): method test_split_english_text (line 64) | def test_split_english_text(self, mock_llm_client): method test_split_mixed_text (line 88) | def test_split_mixed_text(self, mock_llm_client): method test_split_preserves_content (line 108) | def test_split_preserves_content(self, mock_llm_client): method test_split_short_text (line 119) | def test_split_short_text(self, mock_llm_client): method test_agent_loop_correction (line 132) | def test_agent_loop_correction(self, mock_llm_client): FILE: tests/test_split/test_split_core.py class TestPreprocessSegments (line 15) | class TestPreprocessSegments: method test_remove_pure_punctuation (line 18) | def test_remove_pure_punctuation(self): method test_english_word_lowercase (line 31) | def test_english_word_lowercase(self): method test_need_lower_false (line 44) | def test_need_lower_false(self): method test_mixed_language (line 50) | def test_mixed_language(self): method test_empty_segments (line 63) | def test_empty_segments(self): method test_chinese_punctuation (line 68) | def test_chinese_punctuation(self): method test_apostrophe_in_word (line 80) | def test_apostrophe_in_word(self): class TestSubtitleSplitterInit (line 92) | class TestSubtitleSplitterInit: method test_default_initialization (line 95) | def test_default_initialization(self): method test_custom_parameters (line 105) | def test_custom_parameters(self): method test_thread_pool_created (line 118) | def test_thread_pool_created(self): class TestDetermineNumSegments (line 125) | class TestDetermineNumSegments: method test_small_word_count (line 128) | def test_small_word_count(self): method test_exact_threshold (line 134) | def test_exact_threshold(self): method test_just_above_threshold (line 140) | def test_just_above_threshold(self): method test_multiple_segments (line 146) | def test_multiple_segments(self): method test_zero_word_count (line 152) | def test_zero_word_count(self): class TestGroupByTimeGaps (line 159) | class TestGroupByTimeGaps: method test_no_gaps (line 162) | def test_no_gaps(self): method test_large_gap (line 174) | def test_large_gap(self): method test_multiple_gaps (line 187) | def test_multiple_gaps(self): method test_empty_segments (line 199) | def test_empty_segments(self): method test_single_segment (line 205) | def test_single_segment(self): method test_check_large_gaps_enabled (line 213) | def test_check_large_gaps_enabled(self): class TestSplitByCommonWords (line 230) | class TestSplitByCommonWords: method test_split_on_prefix_word (line 233) | def test_split_on_prefix_word(self): method test_split_on_suffix_word (line 250) | def test_split_on_suffix_word(self): method test_english_common_words (line 266) | def test_english_common_words(self): method test_no_common_words (line 283) | def test_no_common_words(self): method test_empty_segments (line 293) | def test_empty_segments(self): class TestSplitLongSegment (line 300) | class TestSplitLongSegment: method test_short_segment (line 303) | def test_short_segment(self): method test_long_segment_with_gaps (line 317) | def test_long_segment_with_gaps(self): method test_very_short_segments (line 337) | def test_very_short_segments(self): method test_equal_time_gaps (line 347) | def test_equal_time_gaps(self): method test_preserves_timestamps (line 360) | def test_preserves_timestamps(self): class TestMergeShortSegment (line 375) | class TestMergeShortSegment: method test_merge_very_short_segments (line 378) | def test_merge_very_short_segments(self): method test_merge_with_short_gap (line 390) | def test_merge_with_short_gap(self): method test_no_merge_long_segments (line 402) | def test_no_merge_long_segments(self): method test_no_merge_large_gap (line 414) | def test_no_merge_large_gap(self): method test_merge_respects_max_word_count (line 426) | def test_merge_respects_max_word_count(self): method test_english_text_merge (line 440) | def test_english_text_merge(self): method test_empty_segments (line 452) | def test_empty_segments(self): method test_single_segment (line 459) | def test_single_segment(self): class TestStopMethod (line 467) | class TestStopMethod: method test_stop_sets_running_false (line 470) | def test_stop_sets_running_false(self): method test_stop_shuts_down_executor (line 477) | def test_stop_shuts_down_executor(self): method test_multiple_stops (line 484) | def test_multiple_stops(self): method test_stop_idempotent (line 491) | def test_stop_idempotent(self): class TestEdgeCases (line 501) | class TestEdgeCases: method test_zero_thread_num (line 504) | def test_zero_thread_num(self): method test_negative_max_word_count (line 515) | def test_negative_max_word_count(self): method test_very_large_thread_num (line 523) | def test_very_large_thread_num(self): FILE: tests/test_split/test_split_realistic.py function create_whisper_style_segments (line 14) | def create_whisper_style_segments( class TestRealWorldScenarios (line 58) | class TestRealWorldScenarios: method test_podcast_long_monologue (line 61) | def test_podcast_long_monologue(self): method test_interview_qa_with_pauses (line 79) | def test_interview_qa_with_pauses(self): method test_news_broadcast_style (line 114) | def test_news_broadcast_style(self): method test_casual_conversation_with_hesitation (line 126) | def test_casual_conversation_with_hesitation(self): method test_technical_presentation_bilingual (line 163) | def test_technical_presentation_bilingual(self): method test_subtitle_with_background_noise_gaps (line 203) | def test_subtitle_with_background_noise_gaps(self): class TestEdgeCasesRealistic (line 233) | class TestEdgeCasesRealistic: method test_very_fast_speech (line 236) | def test_very_fast_speech(self): method test_very_slow_speech (line 246) | def test_very_slow_speech(self): method test_subtitle_with_numbers_and_punctuation (line 256) | def test_subtitle_with_numbers_and_punctuation(self): method test_empty_or_whitespace_segments (line 294) | def test_empty_or_whitespace_segments(self): method test_subtitle_crossing_one_hour (line 307) | def test_subtitle_crossing_one_hour(self): class TestGroupByTimeGapsRealistic (line 330) | class TestGroupByTimeGapsRealistic: method test_scene_change_detection (line 333) | def test_scene_change_detection(self): method test_natural_sentence_pauses (line 360) | def test_natural_sentence_pauses(self): class TestSplitByCommonWordsRealistic (line 387) | class TestSplitByCommonWordsRealistic: method test_long_compound_sentence_chinese (line 390) | def test_long_compound_sentence_chinese(self): method test_english_compound_sentence (line 401) | def test_english_compound_sentence(self): class TestMergeShortSegmentRealistic (line 413) | class TestMergeShortSegmentRealistic: method test_merge_single_character_words (line 416) | def test_merge_single_character_words(self): method test_dont_merge_across_large_pause (line 437) | def test_dont_merge_across_large_pause(self): method test_merge_interjections (line 454) | def test_merge_interjections(self): FILE: tests/test_subtitle/conftest.py function qapp (line 10) | def qapp(): function use_qapp (line 20) | def use_qapp(qapp): FILE: tests/test_subtitle/test_subtitle_thread.py function get_test_model (line 30) | def get_test_model(): function run_thread_with_timeout (line 57) | def run_thread_with_timeout(thread, timeout_ms=60000): function subtitle_file (line 104) | def subtitle_file(): function output_dir (line 114) | def output_dir(): function base_config (line 121) | def base_config(): class TestSubtitleThreadSplit (line 132) | class TestSubtitleThreadSplit: method test_split_sentence (line 135) | def test_split_sentence( method test_split_semantic (line 161) | def test_split_semantic( class TestSubtitleThreadOptimize (line 184) | class TestSubtitleThreadOptimize: method test_optimize_with_llm (line 187) | def test_optimize_with_llm( class TestSubtitleThreadTranslate (line 211) | class TestSubtitleThreadTranslate: method test_translate_google (line 215) | def test_translate_google(self, subtitle_file, output_dir, base_config): method test_translate_bing (line 238) | def test_translate_bing(self, subtitle_file, output_dir, base_config): method test_translate_llm (line 257) | def test_translate_llm( class TestSubtitleThreadFullPipeline (line 282) | class TestSubtitleThreadFullPipeline: method test_split_and_translate (line 285) | def test_split_and_translate( method test_optimize_and_translate (line 310) | def test_optimize_and_translate( class TestSubtitleThreadError (line 336) | class TestSubtitleThreadError: method test_missing_file (line 339) | def test_missing_file(self, output_dir, base_config): method test_no_translator_service (line 350) | def test_no_translator_service(self, subtitle_file, output_dir, base_c... FILE: tests/test_thread/conftest.py function qapp (line 16) | def qapp(): function sample_audio_path (line 25) | def sample_audio_path() -> str: function sample_video_path (line 35) | def sample_video_path(tmp_path: Path, sample_audio_path: str) -> str: function sample_subtitle_path (line 66) | def sample_subtitle_path(tmp_path: Path) -> str: function output_dir (line 76) | def output_dir(tmp_path: Path) -> Generator[str, None, None]: function run_thread_with_timeout (line 83) | def run_thread_with_timeout(thread, timeout_ms: int = 30000) -> dict: FILE: tests/test_thread/test_subtitle_pipeline_thread.py class TestSubtitlePipelineThread (line 9) | class TestSubtitlePipelineThread: method test_pipeline_placeholder (line 12) | def test_pipeline_placeholder(self, qapp): FILE: tests/test_thread/test_transcript_thread.py class TestTranscriptThread (line 17) | class TestTranscriptThread: method base_config (line 21) | def base_config(self) -> TranscribeConfig: method test_transcribe_audio_with_faster_whisper (line 34) | def test_transcribe_audio_with_faster_whisper( method test_transcribe_video_with_faster_whisper (line 61) | def test_transcribe_video_with_faster_whisper( method test_transcribe_missing_video (line 83) | def test_transcribe_missing_video( method test_transcribe_empty_path (line 100) | def test_transcribe_empty_path( FILE: tests/test_thread/test_video_info_thread.py class TestVideoInfoThread (line 10) | class TestVideoInfoThread: method test_get_video_info_missing_file (line 13) | def test_get_video_info_missing_file(self, qapp): method test_get_video_info_invalid_file (line 20) | def test_get_video_info_invalid_file(self, tmp_path, qapp): FILE: tests/test_thread/test_video_synthesis_thread.py class TestVideoSynthesisThread (line 14) | class TestVideoSynthesisThread: method base_config (line 18) | def base_config(self) -> SynthesisConfig: method test_synthesize_skip_video (line 25) | def test_synthesize_skip_video( method test_synthesize_missing_video (line 50) | def test_synthesize_missing_video( method test_synthesize_empty_paths (line 71) | def test_synthesize_empty_paths( FILE: tests/test_translate/test_bing_translator.py class TestBingTranslator (line 14) | class TestBingTranslator: method bing_translator (line 18) | def bing_translator(self, target_language: TargetLanguage) -> BingTran... method test_translate_simple_text (line 31) | def test_translate_simple_text( method test_translate_chunk (line 61) | def test_translate_chunk( FILE: tests/test_translate/test_cache_validation.py function ensure_cache_enabled (line 16) | def ensure_cache_enabled(): function test_cache (line 24) | def test_cache(tmp_path) -> Cache: class TestCacheValidation (line 31) | class TestCacheValidation: method test_exception_not_cached (line 34) | def test_exception_not_cached(self, test_cache: Cache) -> None: method test_validate_none_not_cached (line 55) | def test_validate_none_not_cached(self, test_cache: Cache) -> None: method test_validate_empty_not_cached (line 78) | def test_validate_empty_not_cached(self, test_cache: Cache) -> None: method test_custom_validator (line 101) | def test_custom_validator(self, test_cache: Cache) -> None: method test_valid_result_cached (line 128) | def test_valid_result_cached(self, test_cache: Cache) -> None: method test_no_validator_caches_all (line 149) | def test_no_validator_caches_all(self, test_cache: Cache) -> None: method test_cache_disabled_bypasses_cache (line 172) | def test_cache_disabled_bypasses_cache(self, test_cache: Cache) -> None: FILE: tests/test_translate/test_deeplx_translator.py class TestDeepLXTranslator (line 23) | class TestDeepLXTranslator: method deeplx_translator (line 27) | def deeplx_translator( method test_translate_simple_text (line 45) | def test_translate_simple_text( method test_translate_chunk (line 79) | def test_translate_chunk( FILE: tests/test_translate/test_google_translator.py class TestGoogleTranslator (line 14) | class TestGoogleTranslator: method google_translator (line 18) | def google_translator(self, target_language: TargetLanguage) -> Google... method test_translate_simple_text (line 32) | def test_translate_simple_text( method test_translate_chunk (line 62) | def test_translate_chunk( FILE: tests/test_translate/test_llm_translator.py class TestLLMTranslator (line 22) | class TestLLMTranslator: method llm_translator (line 26) | def llm_translator( method test_translate_simple_text (line 46) | def test_translate_simple_text( method test_translate_chunk (line 69) | def test_translate_chunk( method test_cache_works (line 97) | def test_cache_works( method test_reflect_translation (line 124) | def test_reflect_translation( FILE: tests/test_tts/test_tts_core.py class TestTTSConfig (line 23) | class TestTTSConfig: method test_default_config (line 26) | def test_default_config(self): method test_custom_config (line 42) | def test_custom_config(self): class TestTTSData (line 60) | class TestTTSData: method test_create_tts_data_seg (line 63) | def test_create_tts_data_seg(self): method test_create_tts_data_from_segments (line 80) | def test_create_tts_data_from_segments(self): method test_from_texts (line 91) | def test_from_texts(self): method test_filter_empty_segments (line 100) | def test_filter_empty_segments(self): class TestTTSStatus (line 114) | class TestTTSStatus: method test_status_properties (line 117) | def test_status_properties(self): method test_callback_tuple (line 123) | def test_callback_tuple(self): method test_with_progress (line 128) | def test_with_progress(self): method test_all_statuses (line 133) | def test_all_statuses(self): class MockTTS (line 144) | class MockTTS(BaseTTS): method __init__ (line 147) | def __init__(self, config: TTSConfig): method _synthesize (line 151) | def _synthesize(self, segment: TTSDataSeg, output_path: str) -> None: class TestBaseTTS (line 161) | class TestBaseTTS: method test_generate_cache_key (line 164) | def test_generate_cache_key(self): method test_generate_filename (line 187) | def test_generate_filename(self): method test_synthesize_single (line 202) | def test_synthesize_single(self): method test_synthesize_batch (line 220) | def test_synthesize_batch(self): method test_batch_with_callback (line 243) | def test_batch_with_callback(self): method test_cache_parameter (line 265) | def test_cache_parameter(self): class TestSiliconFlowTTS (line 302) | class TestSiliconFlowTTS: method test_init_without_api_key (line 305) | def test_init_without_api_key(self): method test_synthesize_success (line 312) | def test_synthesize_success(self, mock_post): method test_synthesize_with_optional_params (line 347) | def test_synthesize_with_optional_params(self, mock_post): class TestOpenAITTS (line 374) | class TestOpenAITTS: method test_init_without_api_key (line 377) | def test_init_without_api_key(self): method test_synthesize_success (line 384) | def test_synthesize_success(self, mock_openai_class): method test_synthesize_with_custom_voice (line 436) | def test_synthesize_with_custom_voice(self, mock_openai_class): method test_default_voice (line 473) | def test_default_voice(self, mock_openai_class): FILE: tests/test_tts/test_tts_integration.py function siliconflow_config (line 47) | def siliconflow_config(): function openai_config (line 72) | def openai_config(): class TestSiliconFlowIntegration (line 84) | class TestSiliconFlowIntegration: method test_siliconflow_single_synthesis (line 87) | def test_siliconflow_single_synthesis(self, siliconflow_config): method test_siliconflow_batch_synthesis (line 103) | def test_siliconflow_batch_synthesis(self, siliconflow_config): class TestOpenAITTSIntegration (line 141) | class TestOpenAITTSIntegration: method test_openai_single_synthesis (line 144) | def test_openai_single_synthesis(self, openai_config): method test_openai_batch_synthesis (line 160) | def test_openai_batch_synthesis(self, openai_config):