# pkanderi-abio/youtube-autopilot architecture

> Architecture diagram of the GitHub repository pkanderi-abio/youtube-autopilot, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-14). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/pkanderi-abio/youtube-autopilot
- Repository: https://github.com/pkanderi-abio/youtube-autopilot

## Overview

#### Purpose and Entry Points
YouTube Autopilot is a GitHub Actions-driven, unattended video-production system for multiple YouTube channels. It discovers topics, creates short- and long-form videos, schedules uploads, and records channel history. The primary runtime entry point is `backend/src/run-pipeline.js`; scheduled orchestration is defined in `.github/workflows/pipeline.yml`. The static dashboard begins at `frontend/index.html`.

#### Channel Configuration and Persistent State
Channels, their topic strategy, formats, and cadence are centrally defined in `backend/config/channels.json`. Pipeline state and publishing history are maintained as committed JSON data, including `backend/data/history-channel1.json` and `backend/data/history-channel2.json`. This makes GitHub repository state both the durable record and the dashboard’s primary data source.

#### Pipeline Orchestrator
`backend/src/run-pipeline.js` coordinates the numbered production stages, selects applicable channel/format work, tracks stage outcomes, and establishes the failure boundary for a run. Shared state handling is isolated in `backend/src/lib/state.js`, while channel-specific historical performance can be accessed through `backend/src/lib/analytics.js`.

#### Topic Discovery and Content Generation
The first stage, `backend/src/steps/1-discover-topic.js`, chooses either current trends or a configured evergreen pool. Trend acquisition is abstracted by `backend/src/lib/trends.js`. Script generation in `backend/src/steps/2-generate-script.js` uses the local LLM integration in `backend/src/lib/llm.js`, so generative text does not require a paid hosted model API. `backend/src/steps/3-optimize-seo.js` transforms the content into YouTube-oriented metadata.

#### Media Production
Voice generation is performed by `backend/src/steps/4-generate-voice.js`. Background creation in `backend/src/steps/5-generate-background.js` uses stock footage through `backend/src/lib/stockFootage.js`, with a gradient fallback when usable footage is unavailable. Video assembly is performed by `backend/src/steps/6-assemble-video.js`, implying a local ffmpeg runtime boundary. Nursery audio assets and their lookup manifest are held under `backend/audio/nursery/` and `backend/audio/nursery-manifest.json`, accessed through `backend/src/lib/nurseryAudio.js`.

#### Publishing and External Boundaries
Thumbnail generation is a distinct late-stage artifact step in `backend/src/steps/7-generate-thumbnail.js`. `backend/src/steps/8-upload-youtube.js` publishes and schedules completed media through the YouTube integration in `backend/src/lib/youtube.js`. External service boundaries are YouTube APIs, Pexels’ stock-footage API, local Ollama, free TTS tooling, and ffmpeg; credentials are expected through environment configuration such as `backend/.env.example`.

#### Automation, Analytics, and Dashboard
GitHub Actions supplies cron execution and repository-write automation via `.github/workflows/pipeline.yml`. Post-publication analytics can be fetched with `backend/scripts/fetch-analytics.js` and persisted in files such as `backend/data/analytics-channel1.json`; `.github/workflows/analytics.yml` likely schedules this independently. The frontend is a static control panel whose data is assembled by `frontend/build-data.js` and rendered by `frontend/index.html`, separating operational visualization from the production runtime.

Main entry points: [`backend/src/run-pipeline.js`](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/run-pipeline.js) (Run pipeline), [`backend/src/steps/1-discover-topic.js`](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/1-discover-topic.js) (Discover topic), [`backend/src/steps/2-generate-script.js`](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/2-generate-script.js) (Generate script), [`backend/src/steps/4-generate-voice.js`](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/4-generate-voice.js) (Generate voice)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_automation["Automation"]
  node_pipeline_workflow{{"Pipeline workflow<br/>GitHub Actions<br/>[pipeline.yml]"}}
  node_analytics_workflow{{"Analytics workflow<br/>GitHub Actions<br/>[analytics.yml]"}}
end

subgraph group_pipeline["Production Pipeline"]
  node_channel_config["Channel configuration<br/>JSON config<br/>[channels.json]"]
  node_orchestrator["Run pipeline<br/>Node.js orchestrator<br/>[run-pipeline.js]"]
  node_state["State handling<br/>State library<br/>[state.js]"]
  node_history[("Channel history<br/>Committed JSON state")]
  node_discovery["Discover topic<br/>Pipeline stage"]
  node_script["Generate script<br/>Pipeline stage"]
  node_seo["Optimize SEO<br/>Pipeline stage<br/>[3-optimize-seo.js]"]
  node_trends_api(("Trend sources<br/>External trends<br/>[trends.js]"))
  node_ollama(("Local Ollama<br/>Local LLM runtime<br/>[llm.js]"))
end

subgraph group_media["Media Runtime"]
  node_voice["Generate voice<br/>Pipeline stage"]
  node_background["Generate background<br/>Pipeline stage"]
  node_assembly["Assemble video<br/>Pipeline stage"]
  node_stock_api(("Pexels API<br/>Stock footage API<br/>[stockFootage.js]"))
  node_media_tools(("TTS and ffmpeg<br/>Local media tools"))
end

subgraph group_publishing["Publishing &amp; Analytics"]
  node_thumbnail["Generate thumbnail<br/>Pipeline stage"]
  node_upload["Upload YouTube<br/>Pipeline stage"]
  node_youtube_api(("YouTube APIs<br/>External publishing API<br/>[youtube.js]"))
  node_analytics_fetch["Fetch analytics<br/>Analytics job<br/>[fetch-analytics.js]"]
  node_analytics_data[("Channel analytics<br/>Committed JSON data")]
end

subgraph group_dashboard["Dashboard"]
  node_dashboard_build["Build dashboard data<br/>Static data builder<br/>[build-data.js]"]
  node_dashboard["Static dashboard<br/>Control panel<br/>[index.html]"]
end

node_pipeline_workflow -->|"runs"| node_orchestrator
node_orchestrator -->|"reads"| node_channel_config
node_orchestrator -->|"uses"| node_state
node_state -->|"updates"| node_history
node_orchestrator -->|"starts"| node_discovery
node_discovery -->|"gets trends"| node_trends_api
node_discovery -->|"topic"| node_script
node_script -->|"generates via"| node_ollama
node_script -->|"script"| node_seo
node_seo -->|"content"| node_voice
node_voice -->|"TTS"| node_media_tools
node_voice -->|"audio"| node_background
node_background -->|"fetches footage"| node_stock_api
node_background -->|"visuals"| node_assembly
node_assembly -->|"ffmpeg"| node_media_tools
node_assembly -->|"video"| node_thumbnail
node_thumbnail -->|"media package"| node_upload
node_upload -->|"publishes"| node_youtube_api
node_analytics_workflow -->|"runs"| node_analytics_fetch
node_analytics_fetch -->|"retrieves metrics"| node_youtube_api
node_analytics_fetch -->|"persists"| node_analytics_data
node_history -->|"supplies state"| node_dashboard_build
node_analytics_data -->|"supplies metrics"| node_dashboard_build
node_dashboard_build -->|"builds data for"| node_dashboard

click node_pipeline_workflow "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/.github/workflows/pipeline.yml"
click node_analytics_workflow "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/.github/workflows/analytics.yml"
click node_channel_config "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/config/channels.json"
click node_orchestrator "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/run-pipeline.js"
click node_state "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/lib/state.js"
click node_history "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/data/history-channel1.json"
click node_discovery "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/1-discover-topic.js"
click node_script "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/2-generate-script.js"
click node_seo "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/3-optimize-seo.js"
click node_voice "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/4-generate-voice.js"
click node_background "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/5-generate-background.js"
click node_assembly "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/6-assemble-video.js"
click node_thumbnail "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/7-generate-thumbnail.js"
click node_upload "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/8-upload-youtube.js"
click node_trends_api "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/lib/trends.js"
click node_ollama "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/lib/llm.js"
click node_stock_api "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/lib/stockFootage.js"
click node_youtube_api "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/lib/youtube.js"
click node_analytics_fetch "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/scripts/fetch-analytics.js"
click node_analytics_data "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/data/analytics-channel1.json"
click node_dashboard_build "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/frontend/build-data.js"
click node_dashboard "https://github.com/pkanderi-abio/youtube-autopilot/blob/main/frontend/index.html"

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_pipeline_workflow,node_analytics_workflow toneBlue
class node_channel_config,node_orchestrator,node_state,node_history,node_discovery,node_script,node_seo,node_trends_api,node_ollama toneAmber
class node_voice,node_background,node_assembly,node_stock_api,node_media_tools toneMint
class node_thumbnail,node_upload,node_youtube_api,node_analytics_fetch,node_analytics_data toneRose
class node_dashboard_build,node_dashboard toneIndigo
```

## Components

### Automation

- [Pipeline workflow](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/.github/workflows/pipeline.yml): GitHub Actions · Cron-triggered repository-write automation. · `.github/workflows/pipeline.yml`
- [Analytics workflow](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/.github/workflows/analytics.yml): GitHub Actions · `.github/workflows/analytics.yml`

### Production Pipeline

- [Channel configuration](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/config/channels.json): JSON config · Defines channel strategy, formats, and cadence. · `backend/config/channels.json`
- [Run pipeline](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/run-pipeline.js): Node.js orchestrator · Selects work, coordinates stages, and owns run failures. · `backend/src/run-pipeline.js`
- [State handling](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/lib/state.js): State library · `backend/src/lib/state.js`
- [Channel history](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/data/history-channel1.json): Committed JSON state · `backend/data/history-channel1.json`
- [Discover topic](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/1-discover-topic.js): Pipeline stage · Chooses trend or evergreen topics. · `backend/src/steps/1-discover-topic.js`
- [Generate script](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/2-generate-script.js): Pipeline stage · `backend/src/steps/2-generate-script.js`
- [Optimize SEO](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/3-optimize-seo.js): Pipeline stage · Produces YouTube-oriented metadata. · `backend/src/steps/3-optimize-seo.js`
- [Trend sources](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/lib/trends.js): External trends · `backend/src/lib/trends.js`
- [Local Ollama](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/lib/llm.js): Local LLM runtime · `backend/src/lib/llm.js`

### Media Runtime

- [Generate voice](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/4-generate-voice.js): Pipeline stage · `backend/src/steps/4-generate-voice.js`
- [Generate background](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/5-generate-background.js): Pipeline stage · Uses footage or a gradient fallback. · `backend/src/steps/5-generate-background.js`
- [Assemble video](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/6-assemble-video.js): Pipeline stage · `backend/src/steps/6-assemble-video.js`
- [Pexels API](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/lib/stockFootage.js): Stock footage API · `backend/src/lib/stockFootage.js`
- **TTS and ffmpeg**: Local media tools

### Publishing & Analytics

- [Generate thumbnail](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/7-generate-thumbnail.js): Pipeline stage · `backend/src/steps/7-generate-thumbnail.js`
- [Upload YouTube](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/steps/8-upload-youtube.js): Pipeline stage · Publishes and schedules completed media. · `backend/src/steps/8-upload-youtube.js`
- [YouTube APIs](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/src/lib/youtube.js): External publishing API · `backend/src/lib/youtube.js`
- [Fetch analytics](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/scripts/fetch-analytics.js): Analytics job · Persists post-publication channel metrics. · `backend/scripts/fetch-analytics.js`
- [Channel analytics](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/backend/data/analytics-channel1.json): Committed JSON data · `backend/data/analytics-channel1.json`

### Dashboard

- [Build dashboard data](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/frontend/build-data.js): Static data builder · `frontend/build-data.js`
- [Static dashboard](https://github.com/pkanderi-abio/youtube-autopilot/blob/main/frontend/index.html): Control panel · `frontend/index.html`

## Connections

- Pipeline workflow → Run pipeline: runs
- Run pipeline → Channel configuration: reads
- Run pipeline → State handling: uses
- State handling → Channel history: updates
- Run pipeline → Discover topic: starts
- Discover topic → Trend sources: gets trends
- Discover topic → Generate script: topic
- Generate script → Local Ollama: generates via
- Generate script → Optimize SEO: script
- Optimize SEO → Generate voice: content
- Generate voice → TTS and ffmpeg: TTS
- Generate voice → Generate background: audio
- Generate background → Pexels API: fetches footage
- Generate background → Assemble video: visuals
- Assemble video → TTS and ffmpeg: ffmpeg
- Assemble video → Generate thumbnail: video
- Generate thumbnail → Upload YouTube: media package
- Upload YouTube → YouTube APIs: publishes
- Analytics workflow → Fetch analytics: runs
- Fetch analytics → YouTube APIs: retrieves metrics
- Fetch analytics → Channel analytics: persists
- Channel history → Build dashboard data: supplies state
- Channel analytics → Build dashboard data: supplies metrics
- Build dashboard data → Static dashboard: builds data for
