FunASR-powered video transcription, subtitle generation, and LLM-assisted clipping tool with a local Gradio UI.
This report summarizes scanner evidence for modelscope/FunClip, a Python project with 6,383 GitHub stars. SynthScan examined 5,819 lines of code across 55 source files, recording 112 pattern matches distributed across 5 syntactic categories. The legacy adjusted pattern signal is 21.1 (Elevated pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 106 finding(s).
Are imports declared and package/API names verified? 6 finding(s).
Are wrappers, guards, and repeated structures necessary? 97 finding(s).
Which changes need focused human review? 112 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 112 distinct pattern matches across 5 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. 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 configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | funclip/videoclipper.py | 98 | def _normalize_recognition_result(result): | CODE |
| LOW | funclip/llm/twelvelabs_api.py | 40 | def _normalize_pegasus_timestamps(text): | CODE |
| LOW | tests/test_funasr_requirement.py | 6 | def test_funasr_minimum_version_matches_current_model_paths(): | CODE |
| LOW | tests/test_funasr_requirement.py | 16 | def test_readmes_explain_upgrade_for_existing_installs(): | CODE |
| LOW | tests/test_funasr_requirement.py | 28 | def test_readmes_document_moss_ownership_backends_and_timestamp_boundary(): | CODE |
| LOW | tests/test_funasr_requirement.py | 49 | def test_readmes_describe_moss_speakers_as_anonymous_labels(): | CODE |
| LOW | tests/test_funasr_requirement.py | 68 | def test_readmes_route_edge_asr_users_to_gguf_runtime(): | CODE |
| LOW | tests/test_funasr_requirement.py | 80 | def test_english_readme_avoids_visible_typo_regressions(): | CODE |
| LOW | tests/test_gradio_runtime_compat.py | 21 | def test_supported_gradio_stack_renders_index(): | CODE |
| LOW | tests/test_gradio_runtime_compat.py | 35 | def test_local_launch_keeps_gradio_frontend_probe_enabled(): | CODE |
| LOW | tests/test_gradio_runtime_compat.py | 45 | def test_explicit_listen_skips_only_the_local_frontend_probe(): | CODE |
| LOW | tests/test_gradio_runtime_compat.py | 57 | def test_explicit_share_choice_is_preserved(): | CODE |
| LOW | tests/test_gradio_runtime_compat.py | 65 | def test_launcher_does_not_patch_dependencies_or_retry_with_public_share(): | CODE |
| LOW | tests/test_github_templates.py | 7 | def test_issue_templates_collect_funclip_repro_details(): | CODE |
| LOW | tests/test_github_templates.py | 33 | def test_pull_request_template_keeps_validation_visible(): | CODE |
| LOW | tests/test_github_templates.py | 48 | def test_contributing_guide_documents_local_validation_path(): | CODE |
| LOW | tests/test_cheaperinference_api.py | 21 | def test_cheaperinference_prefix_uses_gateway_base_url(self): | CODE |
| LOW | tests/test_cheaperinference_api.py | 42 | def test_cheaperinference_api_key_falls_back_to_env(self): | CODE |
| LOW | tests/test_cheaperinference_api.py | 57 | def test_cheaperinference_api_base_env_overrides(self): | CODE |
| LOW | tests/test_cheaperinference_api.py | 74 | def test_empty_cheaperinference_model_raises(self): | CODE |
| LOW | tests/test_cheaperinference_api.py | 78 | def test_missing_cheaperinference_key_does_not_fall_back_to_openai_key(self): | CODE |
| LOW | tests/test_minimax_api.py | 22 | def test_minimax_prefix_uses_global_base_url(self): | CODE |
| LOW | tests/test_minimax_api.py | 42 | def test_minimax_api_key_falls_back_to_env(self): | CODE |
| LOW | tests/test_minimax_api.py | 57 | def test_minimax_api_base_env_overrides_region(self): | CODE |
| LOW | tests/test_minimax_api.py | 70 | def test_empty_minimax_model_raises(self): | CODE |
| LOW | tests/test_minimax_api.py | 74 | def test_missing_minimax_key_does_not_fall_back_to_openai_key(self): | CODE |
| LOW | tests/test_release_contract.py | 33 | def _create_fixture_repository(repository): | CODE |
| LOW | tests/test_release_contract.py | 54 | def test_release_version_and_public_download_routes_are_in_sync(): | CODE |
| LOW | tests/test_release_contract.py | 68 | def test_release_notes_define_installation_and_asset_boundaries(): | CODE |
| LOW | tests/test_release_contract.py | 83 | def test_tag_workflow_builds_and_publishes_all_release_assets(): | CODE |
| LOW | tests/test_release_contract.py | 115 | def test_release_builder_creates_reproducible_scoped_archives(tmp_path): | CODE |
| LOW | tests/test_release_contract.py | 175 | def test_release_builder_rejects_non_commit_refs(tmp_path): | CODE |
| LOW | tests/test_release_contract.py | 206 | def test_release_builder_supports_cross_filesystem_outputs(tmp_path): | CODE |
| LOW | tests/test_openai_api.py | 18 | def test_atlascloud_prefix_uses_atlas_base_url(self): | CODE |
| LOW | tests/test_openai_api.py | 38 | def test_atlascloud_api_key_falls_back_to_env(self): | CODE |
| LOW | tests/test_openai_api.py | 53 | def test_empty_atlascloud_model_raises(self): | CODE |
| LOW⚡ | tests/test_installation_docs.py | 10 | def test_installation_entries_use_one_python_environment(filename): | CODE |
| LOW⚡ | tests/test_installation_docs.py | 18 | def test_contributor_minimum_matches_application_requirements(): | CODE |
| LOW⚡ | tests/test_installation_docs.py | 26 | def test_troubleshooting_keeps_tls_and_runtime_boundaries(): | CODE |
| LOW | tests/test_subtitle_renderer.py | 24 | def test_subtitle_renderer_preserves_selected_colors(): | CODE |
| LOW | tests/test_subtitle_renderer.py | 36 | def test_subtitle_renderer_rejects_invalid_font_size(): | CODE |
| LOW | tests/test_subtitle_renderer.py | 47 | def test_selected_color_reaches_composited_video_frame(): | CODE |
| LOW | tests/test_subtitle_renderer.py | 63 | def test_pillow_is_an_explicit_runtime_dependency(): | CODE |
| LOW | tests/test_minimax_launch_integration.py | 16 | def test_openai_compatible_route_preserves_prompt_roles(self): | CODE |
| LOW | tests/test_minimax_launch_integration.py | 43 | def test_dropdown_only_lists_documented_minimax_models(self): | CODE |
| LOW | tests/test_litellm_api.py | 45 | def test_no_prefix_passes_through(self): | CODE |
| LOW⚡ | tests/test_litellm_api.py | 66 | def test_api_key_omitted_when_empty(self): | CODE |
| LOW⚡ | tests/test_litellm_api.py | 73 | def test_system_content_included(self): | CODE |
| LOW⚡ | tests/test_litellm_api.py | 83 | def test_system_content_skipped_when_empty(self): | CODE |
| LOW⚡ | tests/test_litellm_api.py | 92 | def test_empty_choices_returns_empty(self): | CODE |
| LOW⚡ | tests/test_litellm_api.py | 99 | def test_null_content_returns_empty(self): | CODE |
| LOW | tests/test_litellm_api.py | 130 | def test_empty_model_after_strip_raises(self): | CODE |
| LOW | tests/test_cheaperinference_launch_integration.py | 16 | def test_openai_compatible_route_handles_cheaperinference_prefix(self): | CODE |
| LOW | tests/test_cheaperinference_launch_integration.py | 39 | def test_support_prefix_list_includes_cheaperinference(self): | CODE |
| LOW | tests/test_cheaperinference_launch_integration.py | 60 | def test_dropdown_lists_cheaperinference_gateway_models(self): | CODE |
| LOW⚡ | tests/test_cli_stage_help.py | 35 | def test_help_describes_recognition_and_clipping_stages(self): | CODE |
| LOW⚡ | tests/test_cli_stage_help.py | 44 | def test_stage_one_and_two_remain_accepted(self): | CODE |
| LOW⚡ | tests/test_cli_stage_help.py | 52 | def test_stage_zero_remains_invalid(self): | CODE |
| LOW | tests/test_community_links.py | 17 | def test_community_section_has_stable_discussions_fallback( | CODE |
| LOW | tests/test_canonical_qwenaudio_links.py | 35 | def test_legacy_owner_matcher_covers_repository_api_and_charts(): | CODE |
| 37 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | funclip/videoclipper.py | 15 | CODE | |
| LOW | funclip/launch.py | 6 | CODE | |
| LOW | funclip/llm/g4f_openai_api.py | 4 | CODE | |
| LOW | funclip/test/imagemagick_test.py | 1 | CODE | |
| LOW | funclip/test/imagemagick_test.py | 3 | CODE | |
| LOW | tests/test_subtitle_renderer.py | 3 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | funclip/videoclipper.py | 175 | CODE | |
| LOW | funclip/videoclipper.py | 280 | CODE | |
| LOW | funclip/llm/openai_api.py | 28 | CODE | |
| LOW | funclip/utils/subtitle_utils.py | 69 | CODE | |
| LOW | funclip/utils/argparse_tools.py | 30 | CODE | |
| LOW | funclip/utils/trans_utils.py | 100 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | README.md | 137 | OrcaRouter exposes one endpoint for all frontier and open-weight models, so you can switch routing targets without chang | CODE |
| MEDIUM | README_zh.md | 162 | OrcaRouter 用单一端点接入所有前沿与开源模型,无需修改 FunClip 即可切换路由目标。它还可以在同一端点上为 AI agent 提供网关级零信任控制。对经网关转发的 prompt、response 与工具调用,实际执行方式由相 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | funclip/launch.py | 66 | # Create a temporary file | COMMENT |