🎬 卡卡字幕助手 | VideoCaptioner - 基于 LLM 的智能字幕助手 - 视频字幕生成、断句、校正、字幕翻译全流程处理!- A powered tool for easy and efficient video subtitling.
This report presents the forensic synthetic code analysis of WEIFENG2333/VideoCaptioner, a Python project with 15,316 GitHub stars. SynthScan v2.0 examined 54,319 lines of code across 262 source files, recording 703 pattern matches distributed across 19 syntactic categories. The overall adjusted score of 19.1 places this repository in the Moderate AI signal band.
The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).
This chart maps the temporal evolution of the adjusted synthetic code score across successive scan runs. An upward trajectory indicates ongoing incorporation of AI-generated code or expanding LLM-assisted scaffolding; a stable or declining trajectory may reflect active human refactoring, code removal, or the adoption of stricter authorship policies. The dashed secondary line (right axis) independently tracks total raw pattern hit count, which can diverge from the normalised score when codebase size changes significantly between scans.
Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.
This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.
The scanner identified 703 distinct pattern matches across 19 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | videocaptioner/ui/task_factory.py | 245 | def create_transcript_and_subtitle_task( | CODE |
| LOW | videocaptioner/ui/components/WhisperCppSettingWidget.py | 408 | def _on_model_download_progress(value, msg): | CODE |
| LOW | videocaptioner/ui/components/WhisperCppSettingWidget.py | 412 | def _on_model_download_finished(): | CODE |
| LOW | videocaptioner/ui/components/WhisperCppSettingWidget.py | 489 | def _set_all_download_buttons_enabled(self, enabled: bool): | CODE |
| LOW | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 126 | def check_faster_whisper_exists() -> tuple[bool, list[str]]: | CODE |
| LOW | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 451 | def _on_program_download_progress(self, value, status_msg): | CODE |
| LOW | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 456 | def _on_program_download_finished(self, save_path): | CODE |
| LOW | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 479 | def _on_program_download_error(self, error): | CODE |
| LOW | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 533 | def _on_model_download_progress(value, msg): | CODE |
| LOW | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 537 | def _on_model_download_finished(): | CODE |
| LOW | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 607 | def _set_all_download_buttons_enabled(self, enabled: bool): | CODE |
| LOW | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 634 | def _finish_program_installation(self): | CODE |
| LOW | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 878 | def check_faster_whisper_model(self): | CODE |
| LOW | videocaptioner/ui/components/WhisperAPISettingWidget.py | 161 | def on_connection_check_finished(self, success, result): | CODE |
| LOW | videocaptioner/ui/components/WhisperAPISettingWidget.py | 184 | def on_connection_check_error(self, message): | CODE |
| LOW | videocaptioner/ui/view/video_synthesis_interface.py | 285 | def on_soft_subtitle_action_triggered(self, checked: bool): | CODE |
| LOW | videocaptioner/ui/view/video_synthesis_interface.py | 316 | def on_need_video_action_triggered(self, checked: bool): | CODE |
| LOW | videocaptioner/ui/view/video_synthesis_interface.py | 344 | def on_video_quality_action_changed(self, quality_text: str): | CODE |
| LOW | videocaptioner/ui/view/video_synthesis_interface.py | 363 | def on_use_style_action_triggered(self, checked: bool): | CODE |
| LOW | videocaptioner/ui/view/video_synthesis_interface.py | 406 | def on_render_mode_changed_external(self, mode_text: str): | CODE |
| LOW | videocaptioner/ui/view/video_synthesis_interface.py | 410 | def _update_synthesis_controls_state(self): | CODE |
| LOW | videocaptioner/ui/view/video_synthesis_interface.py | 422 | def _update_style_controls_state(self): | CODE |
| LOW | videocaptioner/ui/view/video_synthesis_interface.py | 499 | def on_video_synthesis_finished(self, task): | CODE |
| LOW | videocaptioner/ui/view/video_synthesis_interface.py | 511 | def on_video_synthesis_progress(self, progress, message): | CODE |
| LOW⚡ | videocaptioner/ui/view/subtitle_interface.py | 421 | def _update_prompt_button_style(self) -> None: | CODE |
| LOW⚡ | videocaptioner/ui/view/subtitle_interface.py | 449 | def start_subtitle_optimization(self, need_create_task: bool = True) -> None: | CODE |
| LOW | videocaptioner/ui/view/subtitle_interface.py | 502 | def on_subtitle_optimization_finished( | CODE |
| LOW | videocaptioner/ui/view/subtitle_interface.py | 518 | def on_subtitle_optimization_error(self, error: str) -> None: | CODE |
| LOW | videocaptioner/ui/view/subtitle_interface.py | 529 | def on_subtitle_optimization_progress(self, value: int, status: str) -> None: | CODE |
| LOW | videocaptioner/ui/view/subtitle_interface.py | 861 | def retranslate_selected_rows(self, rows: List[int]) -> None: | CODE |
| LOW⚡ | videocaptioner/ui/view/subtitle_interface.py | 956 | def on_target_language_changed(self, language: str) -> None: | CODE |
| LOW⚡ | videocaptioner/ui/view/subtitle_interface.py | 964 | def on_subtitle_optimization_changed(self, checked: bool) -> None: | CODE |
| LOW⚡ | videocaptioner/ui/view/subtitle_interface.py | 969 | def on_subtitle_translation_changed(self, checked: bool) -> None: | CODE |
| LOW⚡ | videocaptioner/ui/view/subtitle_interface.py | 976 | def on_subtitle_layout_changed(self, layout: str) -> None: | CODE |
| LOW⚡ | videocaptioner/ui/view/subtitle_style_interface.py | 687 | def on_open_style_folder_clicked(self): | CODE |
| LOW⚡ | videocaptioner/ui/view/subtitle_style_interface.py | 691 | def on_subtitle_layout_changed(self, layout: str): | CODE |
| LOW⚡ | videocaptioner/ui/view/subtitle_style_interface.py | 696 | def on_render_mode_changed_external(self, mode_text: str): | CODE |
| LOW | videocaptioner/ui/view/transcription_interface.py | 216 | def update_audio_track_button_text( | CODE |
| LOW | videocaptioner/ui/view/transcription_interface.py | 458 | def on_transcription_model_changed(self, model_name: str): | CODE |
| LOW | videocaptioner/ui/view/task_creation_interface.py | 327 | def on_video_download_finished(self, video_file_path): | STRING |
| LOW | videocaptioner/ui/view/home_interface.py | 85 | def switch_to_subtitle_optimization(self, file_path, video_path): | CODE |
| LOW | videocaptioner/ui/view/home_interface.py | 95 | def switch_to_video_synthesis(self, video_path, subtitle_path): | CODE |
| LOW | videocaptioner/ui/thread/batch_process_thread.py | 177 | def _on_trans_sub_progress_wrapper( | CODE |
| LOW | videocaptioner/ui/thread/batch_process_thread.py | 184 | def _on_trans_sub_finished_wrapper( | CODE |
| LOW | videocaptioner/ui/thread/batch_process_thread.py | 212 | def _on_trans_sub_subtitle_progress_wrapper( | CODE |
| LOW | videocaptioner/ui/thread/batch_process_thread.py | 219 | def _handle_full_process_task(self, batch_task: BatchTask): | CODE |
| LOW | videocaptioner/ui/thread/batch_process_thread.py | 273 | def on_full_process_subtitle_progress( | CODE |
| LOW | videocaptioner/ui/thread/batch_process_thread.py | 281 | def on_full_process_subtitle_finished( | CODE |
| LOW | videocaptioner/ui/thread/batch_process_thread.py | 304 | def on_full_process_synthesis_progress( | CODE |
| LOW | videocaptioner/ui/thread/transcript_thread.py | 58 | def _check_downloaded_subtitle(self) -> bool: | CODE |
| LOW | videocaptioner/ui/thread/subtitle_thread.py | 38 | def create_translator_from_config( | CODE |
| LOW | videocaptioner/ui/thread/modelscope_download_thread.py | 33 | def create_progress_callback_class( | CODE |
| LOW | videocaptioner/ui/thread/version_checker_thread.py | 132 | def check_new_version_announcement(self) -> None: | CODE |
| LOW | videocaptioner/core/entities.py | 476 | def _get_all_languages_except_auto() -> list[TranscribeLanguageEnum]: | CODE |
| LOW | videocaptioner/core/entities.py | 511 | def get_asr_language_capability(model: TranscribeModelEnum) -> ASRLanguageCapability: | CODE |
| LOW | videocaptioner/core/split/split.py | 591 | def _merge_processed_segments( | CODE |
| LOW | videocaptioner/core/split/split.py | 661 | def _merge_segments_based_on_sentences( | CODE |
| LOW | videocaptioner/core/llm/request_logger.py | 83 | def create_logging_http_client() -> httpx.Client: | CODE |
| LOW | videocaptioner/core/optimize/optimize.py | 273 | def _validate_optimization_result( | CODE |
| LOW | videocaptioner/core/translate/base.py | 150 | def _set_segments_translated_text( | CODE |
| 227 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | videocaptioner/cli/main.py | 526 | # ── Command runners ────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | tests/test_tts/test_tts_integration.py | 195 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_tts/test_tts_integration.py | 197 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_tts/test_tts_core.py | 504 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_tts/test_tts_core.py | 506 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunk_merger.py | 61 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunk_merger.py | 63 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunk_merger.py | 193 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunk_merger.py | 195 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunk_merger.py | 353 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunk_merger.py | 355 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunk_merger.py | 468 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunk_merger.py | 470 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunk_merger.py | 691 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunk_merger.py | 693 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunk_merger.py | 746 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunk_merger.py | 748 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunk_merger.py | 536 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunk_merger.py | 538 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunk_merger.py | 615 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunk_merger.py | 617 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/conftest.py | 11 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/conftest.py | 13 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 163 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 165 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 277 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 279 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 282 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 293 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 295 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 303 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 305 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 313 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 315 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 323 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 325 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 333 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunking.py | 335 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunking.py | 22 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunking.py | 24 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunking.py | 117 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunking.py | 119 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunking.py | 413 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunking.py | 421 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunked_asr.py | 340 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunked_asr.py | 342 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunked_asr.py | 406 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunked_asr.py | 408 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunked_asr.py | 463 | # ============================================================================ | COMMENT |
| MEDIUM⚡ | tests/test_asr/test_chunked_asr.py | 465 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunked_asr.py | 28 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunked_asr.py | 30 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunked_asr.py | 119 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunked_asr.py | 121 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunked_asr.py | 210 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunked_asr.py | 212 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunked_asr.py | 284 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunked_asr.py | 286 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunked_asr.py | 366 | # ============================================================================ | COMMENT |
| MEDIUM | tests/test_asr/test_chunked_asr.py | 368 | # ============================================================================ | COMMENT |
| 12 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | videocaptioner/config.py | 11 | except Exception: | CODE |
| LOW | videocaptioner/ui/components/WhisperCppSettingWidget.py | 459 | except Exception as e: | CODE |
| LOW | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 176 | except Exception as e: | CODE |
| LOW | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 475 | except Exception as e: | CODE |
| MEDIUM | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 164 | def run(self): | CODE |
| LOW | videocaptioner/ui/components/WhisperAPISettingWidget.py | 217 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/components/MyVideoWidget.py | 255 | except Exception: | CODE |
| LOW | videocaptioner/ui/components/MyVideoWidget.py | 370 | except Exception: | CODE |
| LOW | videocaptioner/ui/view/subtitle_interface.py | 602 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/view/log_window.py | 60 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/view/log_window.py | 110 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/view/log_window.py | 152 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/view/setting_interface.py | 1014 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/view/setting_interface.py | 1036 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/view/llm_logs_interface.py | 325 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/view/llm_logs_interface.py | 466 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/thread/subtitle_pipeline_thread.py | 128 | except Exception as e: | CODE |
| MEDIUM | videocaptioner/ui/thread/subtitle_pipeline_thread.py | 36 | def run(self): | CODE |
| LOW | videocaptioner/ui/thread/video_download_thread.py | 35 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/thread/video_download_thread.py | 163 | except Exception: | CODE |
| MEDIUM | videocaptioner/ui/thread/video_download_thread.py | 29 | def run(self): | CODE |
| LOW | videocaptioner/ui/thread/batch_process_thread.py | 89 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/thread/transcript_thread.py | 37 | except Exception as e: | CODE |
| MEDIUM | videocaptioner/ui/thread/transcript_thread.py | 24 | def run(self): | CODE |
| LOW | videocaptioner/ui/thread/subtitle_thread.py | 235 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/thread/subtitle_thread.py | 276 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/thread/subtitle_thread.py | 288 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/thread/subtitle_thread.py | 351 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/thread/video_synthesis_thread.py | 103 | except Exception as e: | CODE |
| MEDIUM | videocaptioner/ui/thread/video_synthesis_thread.py | 25 | def run(self): | CODE |
| LOW | videocaptioner/ui/thread/modelscope_download_thread.py | 79 | except Exception as e: | CODE |
| MEDIUM | videocaptioner/ui/thread/modelscope_download_thread.py | 64 | def run(self): | CODE |
| LOW | videocaptioner/ui/thread/version_checker_thread.py | 90 | except Exception as e: | CODE |
| LOW | videocaptioner/ui/thread/version_checker_thread.py | 158 | except Exception: | CODE |
| LOW | videocaptioner/ui/thread/video_info_thread.py | 36 | except Exception as e: | CODE |
| MEDIUM | videocaptioner/ui/thread/video_info_thread.py | 21 | def run(self): | CODE |
| LOW | videocaptioner/ui/thread/file_download_thread.py | 121 | except Exception: | CODE |
| LOW | videocaptioner/ui/thread/file_download_thread.py | 219 | except Exception as e: | CODE |
| MEDIUM | videocaptioner/ui/thread/file_download_thread.py | 197 | def run(self): | CODE |
| LOW | videocaptioner/core/split/split_by_llm.py | 36 | except Exception as e: | CODE |
| LOW | videocaptioner/core/split/split.py | 165 | except Exception as e: | CODE |
| LOW | videocaptioner/core/split/split.py | 264 | except Exception as e: | CODE |
| LOW | videocaptioner/core/split/split.py | 275 | except Exception as e: | CODE |
| LOW | videocaptioner/core/split/split.py | 781 | except Exception as e: | CODE |
| LOW | videocaptioner/core/llm/check_whisper.py | 74 | except Exception as e: | CODE |
| LOW | videocaptioner/core/llm/request_logger.py | 44 | except Exception: | CODE |
| LOW | videocaptioner/core/llm/check_llm.py | 50 | except Exception as e: | CODE |
| LOW | videocaptioner/core/llm/check_llm.py | 108 | except Exception: | CODE |
| LOW | videocaptioner/core/optimize/optimize.py | 101 | except Exception as e: | CODE |
| LOW | videocaptioner/core/optimize/optimize.py | 148 | except Exception as e: | CODE |
| LOW | videocaptioner/core/optimize/optimize.py | 183 | except Exception as e: | CODE |
| LOW | videocaptioner/core/optimize/optimize.py | 378 | except Exception as e: | CODE |
| LOW | videocaptioner/core/optimize/optimize.py | 415 | except Exception: | CODE |
| LOW | videocaptioner/core/translate/google_translator.py | 67 | except Exception as e: | CODE |
| LOW | videocaptioner/core/translate/bing_translator.py | 48 | except Exception as e: | CODE |
| LOW | videocaptioner/core/translate/bing_translator.py | 87 | except Exception as e: | CODE |
| LOW | videocaptioner/core/translate/bing_translator.py | 96 | except Exception as e: | CODE |
| LOW | videocaptioner/core/translate/factory.py | 72 | except Exception as e: | CODE |
| LOW | videocaptioner/core/translate/deeplx_translator.py | 53 | except Exception as e: | CODE |
| LOW | videocaptioner/core/translate/llm_translator.py | 95 | except Exception as e: | CODE |
| 56 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | videocaptioner/core/entities.py | 8 | CODE | |
| LOW | videocaptioner/core/llm/__init__.py | 3 | CODE | |
| LOW | videocaptioner/core/llm/__init__.py | 3 | CODE | |
| LOW | videocaptioner/core/llm/__init__.py | 4 | CODE | |
| LOW | videocaptioner/core/llm/__init__.py | 5 | CODE | |
| LOW | videocaptioner/core/llm/__init__.py | 5 | CODE | |
| LOW | videocaptioner/core/translate/__init__.py | 7 | CODE | |
| LOW | videocaptioner/core/translate/__init__.py | 8 | CODE | |
| LOW | videocaptioner/core/translate/__init__.py | 9 | CODE | |
| LOW | videocaptioner/core/translate/__init__.py | 10 | CODE | |
| LOW | videocaptioner/core/translate/__init__.py | 11 | CODE | |
| LOW | videocaptioner/core/translate/__init__.py | 12 | CODE | |
| LOW | videocaptioner/core/translate/__init__.py | 13 | CODE | |
| LOW | videocaptioner/core/translate/__init__.py | 14 | CODE | |
| LOW | videocaptioner/core/translate/__init__.py | 14 | CODE | |
| LOW | videocaptioner/core/utils/video_utils.py | 22 | CODE | |
| LOW | videocaptioner/core/speech/__init__.py | 3 | CODE | |
| LOW | videocaptioner/core/speech/__init__.py | 3 | CODE | |
| LOW | videocaptioner/core/speech/__init__.py | 3 | CODE | |
| LOW | videocaptioner/core/speech/__init__.py | 4 | CODE | |
| LOW | videocaptioner/core/speech/__init__.py | 4 | CODE | |
| LOW | videocaptioner/core/speech/__init__.py | 4 | CODE | |
| LOW | videocaptioner/core/speech/__init__.py | 4 | CODE | |
| LOW | videocaptioner/core/speech/__init__.py | 4 | CODE | |
| LOW | videocaptioner/core/asr/__init__.py | 1 | CODE | |
| LOW | videocaptioner/core/asr/__init__.py | 2 | CODE | |
| LOW | videocaptioner/core/asr/__init__.py | 3 | CODE | |
| LOW | videocaptioner/core/asr/__init__.py | 4 | CODE | |
| LOW | videocaptioner/core/asr/__init__.py | 5 | CODE | |
| LOW | videocaptioner/core/asr/__init__.py | 6 | CODE | |
| LOW | videocaptioner/core/asr/__init__.py | 7 | CODE | |
| LOW | videocaptioner/core/asr/__init__.py | 8 | CODE | |
| LOW | videocaptioner/core/subtitle/rounded_renderer.py | 21 | CODE | |
| LOW | videocaptioner/core/subtitle/ass_renderer.py | 19 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 5 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 5 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 6 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 6 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 6 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 6 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 6 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 13 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 13 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 13 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 13 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 13 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 20 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 20 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 21 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 21 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 21 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 21 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 21 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 29 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 30 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 30 | CODE | |
| LOW | videocaptioner/core/subtitle/__init__.py | 30 | CODE | |
| LOW | videocaptioner/core/tts/__init__.py | 6 | CODE | |
| LOW | videocaptioner/core/tts/__init__.py | 7 | CODE | |
| LOW | videocaptioner/core/tts/__init__.py | 8 | CODE | |
| 15 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | videocaptioner/ui/task_factory.py | 110 | CODE | |
| LOW | videocaptioner/ui/components/WhisperCppSettingWidget.py | 383 | CODE | |
| LOW | videocaptioner/ui/components/WhisperCppSettingWidget.py | 412 | CODE | |
| LOW | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 503 | CODE | |
| LOW | …ocaptioner/ui/components/FasterWhisperSettingWidget.py | 537 | CODE | |
| LOW | videocaptioner/ui/components/MyVideoWidget.py | 185 | CODE | |
| LOW | videocaptioner/ui/view/subtitle_interface.py | 78 | CODE | |
| LOW | videocaptioner/ui/view/subtitle_interface.py | 915 | CODE | |
| LOW | videocaptioner/ui/view/subtitle_style_interface.py | 909 | CODE | |
| LOW | videocaptioner/ui/view/llm_logs_interface.py | 308 | CODE | |
| LOW | videocaptioner/ui/view/batch_process_interface.py | 176 | CODE | |
| LOW | videocaptioner/ui/thread/video_download_thread.py | 115 | CODE | |
| LOW | videocaptioner/ui/thread/batch_process_thread.py | 73 | CODE | |
| LOW | videocaptioner/ui/thread/subtitle_thread.py | 100 | CODE | |
| LOW | videocaptioner/ui/thread/file_download_thread.py | 136 | CODE | |
| LOW | videocaptioner/core/split/alignment.py | 74 | CODE | |
| LOW | videocaptioner/core/split/split_by_llm.py | 110 | CODE | |
| LOW | videocaptioner/core/split/split.py | 57 | CODE | |
| LOW | videocaptioner/core/split/split.py | 343 | CODE | |
| LOW | videocaptioner/core/split/split.py | 661 | CODE | |
| LOW | videocaptioner/core/llm/client.py | 52 | CODE | |
| LOW | videocaptioner/core/llm/check_llm.py | 54 | CODE | |
| LOW | videocaptioner/core/translate/bing_translator.py | 52 | CODE | |
| LOW | videocaptioner/core/translate/factory.py | 20 | CODE | |
| LOW | videocaptioner/core/utils/video_utils.py | 173 | CODE | |
| LOW | videocaptioner/core/utils/platform_utils.py | 15 | CODE | |
| LOW | videocaptioner/core/utils/platform_utils.py | 56 | CODE | |
| LOW | videocaptioner/core/utils/subprocess_helper.py | 90 | CODE | |
| LOW | videocaptioner/core/utils/subprocess_helper.py | 142 | CODE | |
| LOW | videocaptioner/core/asr/whisper_cpp.py | 114 | CODE | |
| LOW | videocaptioner/core/asr/asr_data.py | 220 | CODE | |
| LOW | videocaptioner/core/asr/asr_data.py | 248 | CODE | |
| LOW | videocaptioner/core/asr/asr_data.py | 275 | CODE | |
| LOW | videocaptioner/core/asr/asr_data.py | 320 | CODE | |
| LOW | videocaptioner/core/asr/asr_data.py | 515 | CODE | |
| LOW | videocaptioner/core/asr/asr_data.py | 782 | CODE | |
| LOW | videocaptioner/core/asr/faster_whisper.py | 227 | CODE | |
| LOW | videocaptioner/core/asr/transcribe.py | 45 | CODE | |
| LOW | videocaptioner/core/subtitle/font_utils.py | 18 | CODE | |
| LOW | videocaptioner/core/subtitle/font_utils.py | 74 | CODE | |
| LOW | videocaptioner/core/subtitle/text_utils.py | 98 | CODE | |
| LOW | videocaptioner/core/subtitle/text_utils.py | 172 | CODE | |
| LOW | videocaptioner/core/subtitle/rounded_renderer.py | 268 | CODE | |
| LOW | videocaptioner/core/subtitle/ass_renderer.py | 244 | CODE | |
| LOW | videocaptioner/core/subtitle/ass_utils.py | 52 | CODE | |
| LOW | videocaptioner/core/tts/siliconflow.py | 30 | CODE | |
| LOW | videocaptioner/cli/commands/config_cmd.py | 24 | CODE | |
| LOW | videocaptioner/cli/commands/subtitle.py | 49 | CODE | |
| LOW | videocaptioner/cli/commands/style_cmd.py | 28 | CODE | |
| LOW | videocaptioner/cli/commands/synthesize.py | 39 | CODE | |
| LOW | videocaptioner/cli/commands/synthesize.py | 155 | CODE | |
| LOW | videocaptioner/cli/commands/transcribe.py | 13 | CODE | |
| LOW | tests/test_split/test_split_realistic.py | 13 | CODE | |
| LOW | scripts/translate_llm.py | 188 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | videocaptioner/core/split/split.py | 119 | 分割字幕(主入口) 处理流程: 1. Reading并预处理字幕 2. 按字数Segments 3. 并发调用LLM处理 4. 合并结果并优化 | STRING |
| HIGH | videocaptioner/core/split/split.py | 667 | 基于LLM返回的句子列表合并ASRSegments 使用滑动窗口匹配算法: 1. 对每个LLM句子,寻找最佳匹配的ASRSegments序列 2. 使用相似度算法进行匹配 3 | STRING |
| HIGH | videocaptioner/core/optimize/optimize.py | 188 | 使用agent loop优化字幕 LLM → 验证 → 反馈 → 重试 (最多MAX_STEPS次) Args: subtitle_chunk: 字幕批次字典 R | STRING |
| HIGH | videocaptioner/core/utils/cache.py | 72 | Decorator to cache function results with global switch support. This is a thin wrapper around diskcache.Cache.memoi | STRING |
| HIGH | videocaptioner/core/asr/asr_data.py | 516 | Load ASRData from subtitle file. Args: file_path: Subtitle file path (supports .srt, .vtt, .ass, .j | STRING |
| HIGH | videocaptioner/core/asr/chunk_merger.py | 43 | 合并多个音频片段的 ASR 结果 Args: chunks: ASRData 对象列表(每个 chunk 的 segments 应从 0 开始) chunk_offsets: | STRING |
| HIGH | videocaptioner/core/tts/siliconflow.py | 36 | 上传音频并获取声音克隆 URI Args: audio_path: 音频文件路径 text: 对应文本内容 model: 模型名称 | STRING |
| HIGH | videocaptioner/core/prompts/__init__.py | 25 | 从文件加载提示词(带LRU缓存) Args: prompt_path: 提示词相对路径,如 "split/semantic" Returns: 提示词原始文本 Raises: | STRING |
| HIGH | videocaptioner/core/prompts/__init__.py | 48 | 获取提示词并进行变量替换 Args: prompt_path: 提示词路径,如 "split/semantic", "optimize/subtitle" **kwargs: 模板变量,用于替换提示 | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/test_asr/test_bcut_asr.py | 0 | test transcription with different configurations and languages. args: need_word_ts: whether to use word-level timestamps | STRING |
| HIGH | tests/test_asr/test_jianying_asr.py | 0 | test transcription with different configurations and languages. args: need_word_ts: whether to use word-level timestamps | STRING |
| HIGH | tests/test_asr/test_whisper_api_asr.py | 0 | test transcription with different configurations and languages. args: need_word_ts: whether to use word-level timestamps | STRING |
| HIGH | tests/test_translate/test_deeplx_translator.py | 0 | test translating simple asr data with quality validation. | STRING |
| HIGH | tests/test_translate/test_bing_translator.py | 0 | test translating simple asr data with quality validation. | STRING |
| HIGH | tests/test_translate/test_google_translator.py | 0 | test translating simple asr data with quality validation. | STRING |
| HIGH | tests/test_translate/test_deeplx_translator.py | 0 | test translating a single chunk of data with quality validation. | STRING |
| HIGH | tests/test_translate/test_bing_translator.py | 0 | test translating a single chunk of data with quality validation. | STRING |
| HIGH | tests/test_translate/test_google_translator.py | 0 | test translating a single chunk of data with quality validation. | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | videocaptioner/ui/view/subtitle_interface.py | 171 | def update_data(self, new_data: Dict[str, str]) -> None: | CODE |
| LOW | videocaptioner/ui/view/subtitle_interface.py | 190 | def update_all(self, data: Dict[str, Any]) -> None: | CODE |
| LOW | videocaptioner/ui/view/subtitle_interface.py | 403 | def _setup_signals(self) -> None: | CODE |
| LOW⚡ | videocaptioner/ui/view/subtitle_interface.py | 421 | def _update_prompt_button_style(self) -> None: | CODE |
| LOW⚡ | videocaptioner/ui/view/subtitle_interface.py | 430 | def set_task(self, task: SubtitleTask) -> None: | CODE |
| LOW⚡ | videocaptioner/ui/view/subtitle_interface.py | 439 | def update_info(self, task: SubtitleTask) -> None: | CODE |
| LOW | videocaptioner/ui/view/transcription_interface.py | 153 | def update_info(self, video_info: VideoInfo) -> None: | CODE |
| LOW | videocaptioner/ui/view/transcription_interface.py | 176 | def update_audio_tracks(self, video_info: VideoInfo) -> None: | CODE |
| LOW | videocaptioner/ui/view/transcription_interface.py | 430 | def _setup_signals(self) -> None: | CODE |
| LOW | videocaptioner/ui/view/transcription_interface.py | 452 | def _set_value(self) -> None: | CODE |
| LOW | videocaptioner/ui/view/transcription_interface.py | 513 | def set_task(self, task: TranscribeTask) -> None: | CODE |
| LOW | videocaptioner/core/llm/__init__.py | 7 | __all__ = [ | CODE |
| LOW | videocaptioner/core/llm/context.py | 30 | def set_task_context(task_id: str, file_name: str, stage: str) -> None: | CODE |
| LOW | videocaptioner/core/llm/context.py | 43 | def update_stage(stage: str) -> None: | CODE |
| LOW | videocaptioner/core/translate/__init__.py | 16 | __all__ = [ | CODE |
| LOW | videocaptioner/core/utils/platform_utils.py | 12 | logger = logging.getLogger(__name__) | CODE |
| LOW | videocaptioner/core/speech/__init__.py | 12 | __all__ = [ | CODE |
| LOW | videocaptioner/core/asr/__init__.py | 10 | __all__ = [ | CODE |
| LOW | videocaptioner/core/subtitle/__init__.py | 44 | __all__ = [ | CODE |
| LOW | videocaptioner/core/subtitle/style_manager.py | 14 | logger = logging.getLogger(__name__) | CODE |
| LOW | videocaptioner/core/tts/__init__.py | 13 | __all__ = [ | CODE |
| LOW | videocaptioner/core/prompts/__init__.py | 96 | __all__ = ["get_prompt", "list_prompts", "reload_cache"] | CODE |
| LOW | videocaptioner/core/dubbing/__init__.py | 7 | __all__ = [ | CODE |
| LOW | videocaptioner/cli/config.py | 156 | def _set_nested(d: dict, dotted_key: str, value: Any) -> None: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | videocaptioner/core/subtitle/text_utils.py | 103 | # Step 1: Calculate minimum required lines using greedy algorithm | COMMENT |
| LOW⚡ | videocaptioner/core/subtitle/text_utils.py | 124 | # Step 2: Calculate total width and target width per line | COMMENT |
| LOW⚡ | videocaptioner/core/subtitle/text_utils.py | 129 | # Step 3: Redistribute text to achieve balanced lines | COMMENT |
| LOW | videocaptioner/core/subtitle/text_utils.py | 181 | # Step 1: Calculate minimum required lines | COMMENT |
| LOW⚡ | videocaptioner/core/subtitle/text_utils.py | 202 | # Step 2: Calculate target width | COMMENT |
| LOW⚡ | videocaptioner/core/subtitle/text_utils.py | 207 | # Step 3: Redistribute words to achieve balanced lines | COMMENT |
| LOW | videocaptioner/cli/commands/process.py | 74 | # Step 1: Transcribe | COMMENT |
| LOW | videocaptioner/cli/commands/process.py | 98 | # Step 2: Subtitle (optimize + translate) | COMMENT |
| LOW | videocaptioner/cli/commands/process.py | 132 | # Step 3: Dub | COMMENT |
| LOW | videocaptioner/cli/commands/process.py | 196 | # Step 4: Synthesize | COMMENT |
| LOW⚡ | skills/SKILL.md | 87 | # Step 1: Transcribe | COMMENT |
| LOW⚡ | skills/SKILL.md | 90 | # Step 2: Translate (bilingual, original text above translation) | COMMENT |
| LOW⚡ | skills/SKILL.md | 93 | # Step 3: Burn into video with rounded background, high quality | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL | videocaptioner/core/tts/openai_tts.py | 47 | with self.client.audio.speech.with_streaming_response.create( | CODE |
| CRITICAL | tests/test_tts/test_tts_core.py | 416 | mock_client.audio.speech.with_streaming_response.create.assert_called_once_with( | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | videocaptioner/core/subtitle/text_utils.py | 103 | # Step 1: Calculate minimum required lines using greedy algorithm | COMMENT |
| LOW⚡ | videocaptioner/core/subtitle/text_utils.py | 124 | # Step 2: Calculate total width and target width per line | COMMENT |
| LOW⚡ | videocaptioner/core/subtitle/text_utils.py | 129 | # Step 3: Redistribute text to achieve balanced lines | COMMENT |
| LOW | videocaptioner/core/subtitle/text_utils.py | 181 | # Step 1: Calculate minimum required lines | COMMENT |
| LOW⚡ | videocaptioner/core/subtitle/text_utils.py | 202 | # Step 2: Calculate target width | COMMENT |
| LOW⚡ | videocaptioner/core/subtitle/text_utils.py | 207 | # Step 3: Redistribute words to achieve balanced lines | COMMENT |
| LOW | videocaptioner/cli/commands/process.py | 74 | # Step 1: Transcribe | COMMENT |
| LOW | videocaptioner/cli/commands/process.py | 98 | # Step 2: Subtitle (optimize + translate) | COMMENT |
| LOW | videocaptioner/cli/commands/process.py | 132 | # Step 3: Dub | COMMENT |
| LOW | videocaptioner/cli/commands/process.py | 196 | # Step 4: Synthesize | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/README.md | 54 | OPENAI_API_KEY=sk-your-api-key | CODE |
| HIGH | tests/test_tts/test_tts_integration.py | 5 | OPENAI_TTS_API_KEY=your-api-key-here | STRING |
| HIGH | tests/test_tts/test_tts_integration.py | 10 | OPENAI_API_KEY=your-api-key-here | STRING |
| HIGH | docs/dev/translate-module.md | 109 | export OPENAI_API_KEY="your-api-key" | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | videocaptioner/ui/thread/version_checker_thread.py | 41 | data = response.json() | COMMENT |
| LOW | videocaptioner/core/asr/asr_data.py | 421 | WebVTT format subtitle content | COMMENT |
| LOW | tests/test_asr/test_chunking.py | 281 | # 现在使用 ChunkedASR 包装器模式,相关测试已在 test_chunked_asr.py 中实现 | COMMENT |
| LOW | tests/test_asr/test_chunking.py | 401 | COMMENT | |
| LOW | tests/test_asr/test_bcut_asr.py | 61 | # print(f" Total segments: {len(result.segments)}") | COMMENT |
| LOW | tests/test_asr/test_bcut_asr.py | 81 | # print("BcutASR Word-Level Transcription Results:") | COMMENT |
| LOW | tests/test_asr/test_jianying_asr.py | 21 | # @pytest.fixture | COMMENT |
| LOW | tests/test_asr/test_jianying_asr.py | 41 | # test_audio_path: Path to test audio file | COMMENT |
| LOW | tests/test_asr/test_jianying_asr.py | 61 | # print("\n" + "=" * 60) | COMMENT |
| LOW | tests/test_asr/test_jianying_asr.py | 81 | COMMENT | |
| LOW | .github/workflows/claude-code-review.yml | 1 | name: Claude Code Review | COMMENT |
| LOW | .github/workflows/claude-code-review.yml | 61 | # - For TypeScript files: Type safety and proper interface usage | COMMENT |
| LOW | .github/workflows/claude.yml | 41 | actions: read | COMMENT |
| LOW | .github/workflows/claude.yml | 61 | # Optional: Custom environment variables for Claude | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | videocaptioner/core/subtitle/text_utils.py | 137 | # Check if we should break the line | COMMENT |
| LOW | videocaptioner/core/subtitle/text_utils.py | 150 | # Check if next char would significantly exceed target | COMMENT |
| LOW | videocaptioner/core/subtitle/text_utils.py | 227 | # Check if next word would significantly exceed target | COMMENT |
| LOW | videocaptioner/cli/commands/transcribe.py | 151 | # Check if the temp file is empty (no audio track) | COMMENT |
| LOW | tests/test_subtitle/test_subtitle_thread.py | 33 | # Check if model specified in environment | COMMENT |
| LOW | scripts/trans-extract.sh | 17 | # Check if pylupdate5 is available | COMMENT |
| LOW | scripts/run.sh | 26 | # Check if running from within the project directory | COMMENT |
| LOW | scripts/run.sh | 28 | # Check if in project directory | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | .github/workflows/claude-code-review.yml | 63 | # - For React components: Performance, accessibility, and best practices | COMMENT |
| MEDIUM | .github/workflows/claude-code-review.yml | 70 | # 'Please provide a thorough code review focusing on our coding standards and best practices.' }} | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | videocaptioner/ui/components/MyVideoWidget.py | 277 | path = media.toLocalFile() or media.toString() | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/test_thread/conftest.py | 37 | # Create a simple video with a solid color and the audio | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | videocaptioner/core/asr/bcut.py | 195 | # Example usage | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | videocaptioner/core/asr/faster_whisper.py | 31 | CODE |