# marcuth/podcast-clipper architecture

> Architecture diagram of the GitHub repository marcuth/podcast-clipper, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-10). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/marcuth/podcast-clipper
- Repository: https://github.com/marcuth/podcast-clipper

## Overview

AutoClip Studio turns YouTube podcast videos into vertical Shorts, horizontal long-form cuts, or timestamp-and-metadata plans. Users configure a run through the desktop UI or CLI; the Python pipeline gathers video information, transcribes, selects segments with Gemini or heuristics, then exports plans or renders clips. The desktop also exposes project-library and optional YouTube-upload capabilities. README statements and sampled call sites support the main flow; several specialized render and UI details are documented but their implementations were not sampled.

Main entry points: [`src/core/pipeline.py`](https://github.com/marcuth/podcast-clipper/blob/master/src/core/pipeline.py) (Pipeline engine), [`src/strategies/clip_selection.py`](https://github.com/marcuth/podcast-clipper/blob/master/src/strategies/clip_selection.py) (Clip selection), [`src/gui/api.py`](https://github.com/marcuth/podcast-clipper/blob/master/src/gui/api.py) (Desktop API), [`src/utils/cut_clip.py`](https://github.com/marcuth/podcast-clipper/blob/master/src/utils/cut_clip.py) (Shorts rendering)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry["User interfaces"]
  node_desktop["Desktop shell<br/>[app.py]"]
  node_webui["Studio UI<br/>[App.tsx]"]
  node_cli["CLI<br/>[app.py]"]
  node_api["Desktop API<br/>[api.py]"]
end

subgraph group_pipeline["Processing pipeline"]
  node_pipeline_engine["Pipeline engine<br/>[pipeline.py]"]
  node_events["Progress events<br/>[events.py]"]
  node_progress["Progress state"]
  node_transcription["Transcription modes<br/>[transcription.py]"]
  node_youtube_transcript["YouTube captions"]
end

subgraph group_selection["Transcript selection"]
  node_segment["Transcript segments<br/>[segment.py]"]
  node_selection_strategy["Clip selection<br/>[clip_selection.py]"]
  node_ai_clips["AI clip planning<br/>[ai_create_clips.py]"]
  node_gemini["Gemini service<br/>[gemini_service.py]"]
  node_heuristics["Scoring heuristics"]
  node_heatmap["YouTube heatmap"]
end

subgraph group_render["Clip rendering"]
  node_short_render["Shorts rendering<br/>[cut_clip.py]"]
  node_face_tracking["Face tracking<br/>[face_tracking.py]"]
  node_face_detection["Face detection"]
  node_long_render["Long-cut rendering<br/>[cut_long_clip.py]"]
  node_captions["Caption rendering"]
  node_subtitles["Subtitle generation"]
end

subgraph group_projects["Projects and publishing"]
  node_layout["Project layout<br/>[project_layout.py]"]
  node_titles["Video metadata<br/>[video_titles.py]"]
  node_library["Project library<br/>[library-tab.tsx]"]
  node_youtube_upload["YouTube publishing<br/>[youtube_service.py]"]
  node_media_server["Media server<br/>[server.py]"]
end

node_user(("Creator"))

node_user -->|"opens"| node_desktop
node_user -->|"runs"| node_cli
node_desktop -->|"hosts"| node_webui
node_webui -->|"invokes"| node_api
node_cli -->|"runs"| node_pipeline_engine
node_api -->|"runs"| node_pipeline_engine
node_pipeline_engine -->|"transcribes with"| node_transcription
node_transcription -->|"loads captions"| node_youtube_transcript
node_transcription -.->|"produces"| node_segment
node_pipeline_engine -->|"selects clips"| node_selection_strategy
node_selection_strategy -->|"requests AI plan"| node_ai_clips
node_ai_clips -->|"requests analysis"| node_gemini
node_selection_strategy -->|"scores segments"| node_heuristics
node_selection_strategy -.->|"uses heatmap"| node_heatmap
node_selection_strategy -->|"groups segments"| node_segment
node_pipeline_engine -->|"renders Shorts"| node_short_render
node_pipeline_engine -->|"renders long cuts"| node_long_render
node_short_render -->|"tracks faces"| node_face_tracking
node_face_tracking -->|"detects faces"| node_face_detection
node_short_render -->|"renders captions"| node_captions
node_short_render -->|"generates subtitles"| node_subtitles
node_pipeline_engine -->|"organizes output"| node_layout
node_pipeline_engine -->|"generates metadata"| node_titles
node_api -.->|"serves project actions"| node_library
node_api -->|"offers upload"| node_youtube_upload
node_desktop -->|"starts server"| node_media_server
node_pipeline_engine -->|"emits progress"| node_events
node_events -->|"reports state"| node_progress

click node_desktop "https://github.com/marcuth/podcast-clipper/blob/master/src/gui/app.py"
click node_webui "https://github.com/marcuth/podcast-clipper/blob/master/client/src/App.tsx"
click node_cli "https://github.com/marcuth/podcast-clipper/blob/master/src/cli/app.py"
click node_api "https://github.com/marcuth/podcast-clipper/blob/master/src/gui/api.py"
click node_pipeline_engine "https://github.com/marcuth/podcast-clipper/blob/master/src/core/pipeline.py"
click node_events "https://github.com/marcuth/podcast-clipper/blob/master/src/core/events.py"
click node_progress "https://github.com/marcuth/podcast-clipper/blob/master/src/core/pipeline_progress.py"
click node_transcription "https://github.com/marcuth/podcast-clipper/blob/master/src/strategies/transcription.py"
click node_youtube_transcript "https://github.com/marcuth/podcast-clipper/blob/master/src/utils/get_youtube_transcription.py"
click node_segment "https://github.com/marcuth/podcast-clipper/blob/master/src/domain/segment.py"
click node_selection_strategy "https://github.com/marcuth/podcast-clipper/blob/master/src/strategies/clip_selection.py"
click node_ai_clips "https://github.com/marcuth/podcast-clipper/blob/master/src/utils/ai_create_clips.py"
click node_gemini "https://github.com/marcuth/podcast-clipper/blob/master/src/services/gemini_service.py"
click node_heuristics "https://github.com/marcuth/podcast-clipper/tree/master/src/heuristics"
click node_heatmap "https://github.com/marcuth/podcast-clipper/blob/master/src/utils/get_youtube_heatmap.py"
click node_short_render "https://github.com/marcuth/podcast-clipper/blob/master/src/utils/cut_clip.py"
click node_face_tracking "https://github.com/marcuth/podcast-clipper/blob/master/src/utils/face_tracking.py"
click node_face_detection "https://github.com/marcuth/podcast-clipper/blob/master/src/utils/detect_face_center.py"
click node_long_render "https://github.com/marcuth/podcast-clipper/blob/master/src/utils/cut_long_clip.py"
click node_captions "https://github.com/marcuth/podcast-clipper/blob/master/src/utils/render_remotion_captions.py"
click node_subtitles "https://github.com/marcuth/podcast-clipper/blob/master/src/utils/generate_subtitles.py"
click node_layout "https://github.com/marcuth/podcast-clipper/blob/master/src/core/project_layout.py"
click node_titles "https://github.com/marcuth/podcast-clipper/blob/master/src/services/video_titles.py"
click node_library "https://github.com/marcuth/podcast-clipper/blob/master/client/src/components/library-tab.tsx"
click node_youtube_upload "https://github.com/marcuth/podcast-clipper/blob/master/src/services/youtube_service.py"
click node_media_server "https://github.com/marcuth/podcast-clipper/blob/master/src/gui/server.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_desktop,node_webui,node_cli,node_api toneBlue
class node_pipeline_engine,node_events,node_progress,node_transcription,node_youtube_transcript toneAmber
class node_segment,node_selection_strategy,node_ai_clips,node_gemini,node_heuristics,node_heatmap toneMint
class node_short_render,node_face_tracking,node_face_detection,node_long_render,node_captions,node_subtitles toneRose
class node_layout,node_titles,node_library,node_youtube_upload,node_media_server,node_user toneIndigo
```

## Components

### User interfaces

- [Desktop shell](https://github.com/marcuth/podcast-clipper/blob/master/src/gui/app.py): `src/gui/app.py`
- [Studio UI](https://github.com/marcuth/podcast-clipper/blob/master/client/src/App.tsx): `client/src/App.tsx`
- [CLI](https://github.com/marcuth/podcast-clipper/blob/master/src/cli/app.py): `src/cli/app.py`
- [Desktop API](https://github.com/marcuth/podcast-clipper/blob/master/src/gui/api.py): `src/gui/api.py`

### Processing pipeline

- [Pipeline engine](https://github.com/marcuth/podcast-clipper/blob/master/src/core/pipeline.py): `src/core/pipeline.py`
- [Progress events](https://github.com/marcuth/podcast-clipper/blob/master/src/core/events.py): `src/core/events.py`
- [Progress state](https://github.com/marcuth/podcast-clipper/blob/master/src/core/pipeline_progress.py): `src/core/pipeline_progress.py`
- [Transcription modes](https://github.com/marcuth/podcast-clipper/blob/master/src/strategies/transcription.py): `src/strategies/transcription.py`
- [YouTube captions](https://github.com/marcuth/podcast-clipper/blob/master/src/utils/get_youtube_transcription.py): `src/utils/get_youtube_transcription.py`

### Transcript selection

- [Transcript segments](https://github.com/marcuth/podcast-clipper/blob/master/src/domain/segment.py): `src/domain/segment.py`
- [Clip selection](https://github.com/marcuth/podcast-clipper/blob/master/src/strategies/clip_selection.py): `src/strategies/clip_selection.py`
- [AI clip planning](https://github.com/marcuth/podcast-clipper/blob/master/src/utils/ai_create_clips.py): `src/utils/ai_create_clips.py`
- [Gemini service](https://github.com/marcuth/podcast-clipper/blob/master/src/services/gemini_service.py): `src/services/gemini_service.py`
- [Scoring heuristics](https://github.com/marcuth/podcast-clipper/tree/master/src/heuristics): `src/heuristics`
- [YouTube heatmap](https://github.com/marcuth/podcast-clipper/blob/master/src/utils/get_youtube_heatmap.py): `src/utils/get_youtube_heatmap.py`

### Clip rendering

- [Shorts rendering](https://github.com/marcuth/podcast-clipper/blob/master/src/utils/cut_clip.py): `src/utils/cut_clip.py`
- [Face tracking](https://github.com/marcuth/podcast-clipper/blob/master/src/utils/face_tracking.py): `src/utils/face_tracking.py`
- [Face detection](https://github.com/marcuth/podcast-clipper/blob/master/src/utils/detect_face_center.py): `src/utils/detect_face_center.py`
- [Long-cut rendering](https://github.com/marcuth/podcast-clipper/blob/master/src/utils/cut_long_clip.py): `src/utils/cut_long_clip.py`
- [Caption rendering](https://github.com/marcuth/podcast-clipper/blob/master/src/utils/render_remotion_captions.py): `src/utils/render_remotion_captions.py`
- [Subtitle generation](https://github.com/marcuth/podcast-clipper/blob/master/src/utils/generate_subtitles.py): `src/utils/generate_subtitles.py`

### Projects and publishing

- [Project layout](https://github.com/marcuth/podcast-clipper/blob/master/src/core/project_layout.py): `src/core/project_layout.py`
- [Video metadata](https://github.com/marcuth/podcast-clipper/blob/master/src/services/video_titles.py): `src/services/video_titles.py`
- [Project library](https://github.com/marcuth/podcast-clipper/blob/master/client/src/components/library-tab.tsx): `client/src/components/library-tab.tsx`
- [YouTube publishing](https://github.com/marcuth/podcast-clipper/blob/master/src/services/youtube_service.py): `src/services/youtube_service.py`
- [Media server](https://github.com/marcuth/podcast-clipper/blob/master/src/gui/server.py): `src/gui/server.py`

### Other components

- **Creator**

## Connections

- Creator → Desktop shell: opens (evidence: `README.md`)
- Creator → CLI: runs (evidence: `README.md`)
- Desktop shell → Studio UI: hosts (evidence: `src/gui/app.py`)
- Studio UI → Desktop API: invokes (evidence: `README.md`)
- CLI → Pipeline engine: runs (evidence: `src/cli/app.py`)
- Desktop API → Pipeline engine: runs (evidence: `src/gui/api.py`)
- Pipeline engine → Transcription modes: transcribes with (evidence: `src/core/pipeline.py`)
- Transcription modes → YouTube captions: loads captions (evidence: `src/strategies/transcription.py`)
- Transcription modes → Transcript segments: produces
- Pipeline engine → Clip selection: selects clips (evidence: `src/core/pipeline.py`)
- Clip selection → AI clip planning: requests AI plan (evidence: `src/strategies/clip_selection.py`)
- AI clip planning → Gemini service: requests analysis (evidence: `src/utils/ai_create_clips.py`)
- Clip selection → Scoring heuristics: scores segments (evidence: `src/strategies/clip_selection.py`)
- Clip selection → YouTube heatmap: uses heatmap
- Clip selection → Transcript segments: groups segments (evidence: `src/strategies/clip_selection.py`)
- Pipeline engine → Shorts rendering: renders Shorts (evidence: `src/core/pipeline.py`)
- Pipeline engine → Long-cut rendering: renders long cuts (evidence: `README.md`)
- Shorts rendering → Face tracking: tracks faces (evidence: `src/utils/cut_clip.py`)
- Face tracking → Face detection: detects faces (evidence: `src/utils/face_tracking.py`)
- Shorts rendering → Caption rendering: renders captions (evidence: `src/utils/cut_clip.py`)
- Shorts rendering → Subtitle generation: generates subtitles (evidence: `src/utils/cut_clip.py`)
- Pipeline engine → Project layout: organizes output (evidence: `src/core/pipeline.py`)
- Pipeline engine → Video metadata: generates metadata (evidence: `README.md`)
- Desktop API → Project library: serves project actions
- Desktop API → YouTube publishing: offers upload (evidence: `src/gui/api.py`)
- Desktop shell → Media server: starts server (evidence: `src/gui/app.py`)
- Pipeline engine → Progress events: emits progress (evidence: `src/core/pipeline.py`)
- Progress events → Progress state: reports state (evidence: `src/core/events.py`)
