From 47d1f014480cc59c9768a34bf4b5c64dc050de3b Mon Sep 17 00:00:00 2001 From: LIAOWEIRAN Date: Wed, 14 Jan 2026 13:55:38 +0900 Subject: [PATCH] Initial commit: Life Plan Video Generator PoC - Remotion-based video rendering system for financial life plans - Python backend for PDF parsing, video extraction, and B-roll fetching - Animated charts: Life Plan, Cash Flow, and Dual Chart views - Integration with Google Gemini, OpenAI, and Pexels APIs - Complete testing framework and documentation --- .env.example | 22 + .github/copilot-instructions.md | 275 + .github/workflows/lint.yml | 33 + .gitignore | 117 +- .prettierignore | 10 + .prettierrc | 9 +- PROJECT_README.md | 245 + README.md | 54 - assets/0_input/.gitkeep | 1 + assets/1_processed/.gitkeep | 1 + assets/1_processed/broll_fetch_results.json | 77 + .../complete_comparison.json | 2091 +++++ .../№1_基本情報_movie_comparison.json | 24 + ...№1_基本情報_second_comparison.json | 300 + .../№1_基本情報_word_comparison.json | 1765 ++++ assets/1_processed/translation_cache.json | 12 + .../video_extractions/all_extractions.json | 210 + .../№1_基本情報_extraction.json | 104 + ...–2_ライフイベント_extraction.json | 104 + assets/2_output/.gitkeep | 1 + backend/SUBTITLE_INVESTIGATION_README.md | 60 + backend/__init__.py | 3 + backend/data_builder.py | 199 + backend/extractor.py | 83 + backend/investigate_media_fetch.py | 358 + backend/investigate_subtitle_extraction.py | 412 + backend/investigate_video_extraction.py | 290 + backend/media_fetcher.py | 71 + backend/scripter.py | 68 + backend/video_processor/__init__.py | 59 + backend/video_processor/schemas.py | 90 + backend/video_processor/strategy_audio.py | 186 + backend/video_processor/strategy_direct.py | 57 + backend/video_processor/utils.py | 163 + eslint.config.mjs | 77 +- frontend/src/render-props-types.ts | 250 + main.py | 304 + package-lock.json | 8270 +++++++++++++++++ package.json | 18 +- requirements.txt | 33 + src/CashFlowChart.tsx | 440 + src/DualChartView.tsx | 175 + src/LifePlanBarChart.tsx | 257 + src/LifePlanChart.tsx | 348 + src/Root.tsx | 64 +- src/UnifiedHUD.tsx | 163 + src/index.ts | 1 + src/mock-cashflow-original.json | 908 ++ src/mock-cashflow.json | 908 ++ src/mock-data.json | 61 + src/types.ts | 29 + tests/fixtures/.gitkeep | 1 + tests/fixtures/README.md | 48 + tests/test_video_cli.py | 160 + tests/test_video_processor.py | 142 + tsconfig.json | 4 +- verify_structure.py | 135 + 57 files changed, 20278 insertions(+), 72 deletions(-) create mode 100644 .env.example create mode 100644 .github/copilot-instructions.md create mode 100644 .github/workflows/lint.yml create mode 100644 .prettierignore create mode 100644 PROJECT_README.md delete mode 100644 README.md create mode 100644 assets/0_input/.gitkeep create mode 100644 assets/1_processed/.gitkeep create mode 100644 assets/1_processed/broll_fetch_results.json create mode 100644 assets/1_processed/subtitle_investigation/complete_comparison.json create mode 100644 assets/1_processed/subtitle_investigation/№1_基本情報_movie_comparison.json create mode 100644 assets/1_processed/subtitle_investigation/№1_基本情報_second_comparison.json create mode 100644 assets/1_processed/subtitle_investigation/№1_基本情報_word_comparison.json create mode 100644 assets/1_processed/translation_cache.json create mode 100644 assets/1_processed/video_extractions/all_extractions.json create mode 100644 assets/1_processed/video_extractions/№1_基本情報_extraction.json create mode 100644 assets/1_processed/video_extractions/№2_ライフイベント_extraction.json create mode 100644 assets/2_output/.gitkeep create mode 100644 backend/SUBTITLE_INVESTIGATION_README.md create mode 100644 backend/__init__.py create mode 100644 backend/data_builder.py create mode 100644 backend/extractor.py create mode 100644 backend/investigate_media_fetch.py create mode 100644 backend/investigate_subtitle_extraction.py create mode 100644 backend/investigate_video_extraction.py create mode 100644 backend/media_fetcher.py create mode 100644 backend/scripter.py create mode 100644 backend/video_processor/__init__.py create mode 100644 backend/video_processor/schemas.py create mode 100644 backend/video_processor/strategy_audio.py create mode 100644 backend/video_processor/strategy_direct.py create mode 100644 backend/video_processor/utils.py create mode 100644 frontend/src/render-props-types.ts create mode 100644 main.py create mode 100644 package-lock.json create mode 100644 requirements.txt create mode 100644 src/CashFlowChart.tsx create mode 100644 src/DualChartView.tsx create mode 100644 src/LifePlanBarChart.tsx create mode 100644 src/LifePlanChart.tsx create mode 100644 src/UnifiedHUD.tsx create mode 100644 src/mock-cashflow-original.json create mode 100644 src/mock-cashflow.json create mode 100644 src/mock-data.json create mode 100644 src/types.ts create mode 100644 tests/fixtures/.gitkeep create mode 100644 tests/fixtures/README.md create mode 100644 tests/test_video_cli.py create mode 100644 tests/test_video_processor.py create mode 100644 verify_structure.py diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..69ef702 --- /dev/null +++ b/.env.example @@ -0,0 +1,22 @@ +# ============================================================================= +# Auto Life Plan Video Generator - Environment Variables +# ============================================================================= +# Copy this file to .env and fill in your actual API keys +# DO NOT commit .env to version control! + +# Google Gemini API (for PDF parsing and script generation) +GEMINI_API_KEY=your_gemini_api_key_here + +# OpenAI API (for Whisper transcription) +OPENAI_API_KEY=your_openai_api_key_here + +# Pexels API (for B-Roll footage) +PEXELS_API_KEY=your_pexels_api_key_here + +# Google Cloud TTS (optional, if using TTS) +# GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account-key.json + +# Configuration +DEFAULT_INFLATION_RATE=0.02 +DEFAULT_DEFICIT_INTEREST_RATE=0.15 +DEFAULT_INVESTMENT_RETURN=0.03 diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..11f5d6d --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,275 @@ +# Project Overview: Life Plan Video Generator (PoC) + +## 1\. Ultimate Goal + +To build an automated pipeline that transforms a static **Life Plan Report (PDF)** and raw **Interview Footage** into a **3-5 minute dynamic explanatory video (MP4)**. The system is designed to help insurance consultants visualize complex financial data (e.g., asset depletion, inflation risks) for clients, creating an emotional and logical narrative to support decision-making. + +## 2\. Core Architecture + +The system follows a "Hybrid Local/Cloud" architecture to handle sensitive data and heavy video processing efficiently. + +### **Backend (Python / Logic Layer)** + +- **Role:** The "Brain". Handles data extraction, logic calculation, and asset preparation. +- **Tech Stack:** Python 3.10+, LangChain, Google Gemini 1.5 Pro (via API). +- **Key Responsibilities:** + 1. **Ingestion:** Parse complex Japanese PDFs (Sony Life Reports) using Gemini 1.5 Pro. + 2. **Structured Output:** Convert unstructured text into strict JSON (Zod Schema compliant). + 3. **Simulation Engine:** Calculate future asset projections (inflation, compound interest on deficits) to fill missing data points (Linear Interpolation). + 4. **Asset Prep:** Use `FFmpeg` (stream copy) to slice raw interview videos based on timestamps. + +### **Frontend / Rendering (Remotion / Visual Layer)** + +- **Role:** The "Renderer". Converts JSON data into video frames. +- **Tech Stack:** TypeScript, React, Remotion, Recharts, Zod. +- **Key Responsibilities:** + 1. **Programmatic Video:** Render UI components as video frames. + 2. **Dynamic Charts:** Visualize "Asset Depletion" and "Sufficiency Rates" using `Recharts`. + 3. **Frame Synchronization:** Drive animations strictly via `useCurrentFrame()` (no CSS transitions). + +--- + +## 3\. Remotion Specifics (Copilot Instructions) + +### **What does Remotion do in this project?** + +Remotion is **NOT** just a video editor; it is a **code-based rendering engine**. It treats the video timeline as a function of state `f(frame) = UI`. + +### **Critical Implementation Rules** + +1. **No Internal Animations:** + - When using `Recharts`, always set `isAnimationActive={false}`. + - **Reason:** Remotion renders frame-by-frame. Internal library animations rely on real-time timers, which break during rendering, causing flickering or static frames. + - **Solution:** Drive data slicing using `interpolate(frame, [start, end], [0, dataLength])`. + +2. **Asset Handling:** + - Do **NOT** import huge video files directly into React. Use URL references or local paths managed by the Python backend. + - Use `