인셔셔RSS 관심 있는 블로그, 뉴스, 기술 정보를 효율적으로 추적하고 읽으세요
원문 읽기 InertiaRSS에서 열기

추천 피드

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python)
저는 Cuekiyo를 만들었습니다: React, FastAPI, yt-dlp와 FFmpeg를 사용한 지역 우선 애니메이션 OP/ED 비디오 파이프라인
Looped · 2026-05-24 · via DEV Community

나는 Cuekiyo v1.0.0를 릴리스했습니다. 이것은 애니메이션 오프닝과 엔딩 컴필레이션 비디오를 만들기 위한 오픈 소스 로컬 웹 앱입니다.

아이디어는 간단합니다:

애니메이션 제목을 선택 → OP/ED 노래를 승인 → 유튜브 클립 후보를 검토 → 완성된 MP4를 내보내기

클라우드 편집기가 없습니다. 업로드 단계가 없습니다. 유료 API 의존성이 없습니다. 전체 것이 여러분의 머신에서 실행됩니다.

GitHub: https://github.com/unloopedmido/cuekiyo

이것을 만든 이유는 애니메이션 오프닝/엔딩 컴필레이션을 만드는 수동 작업이 솔직히 고통스러워서입니다. 브라우저 탭이 많아지고, 복사된 타임스탬프, 별도의 다운로드 명령어, 잘라내기 도구, 이름 혼란, 랜덤 폴더, 클립 하나가 변경될 때마다 반복적인 재렌더링을 하게 됩니다.

Cuekiyo는 이를 지도된 지역 파이프라인으로 변환합니다. 지루한 부분을 자동화하지만 여전히 사람이 결정해야 할 순간에 멈춥니다.

문제

컴파일 비디오를 만드는 것은 처음에는 간단해 보이지만 실제로 깨끗하게 해보려고 하면 문제가 발생합니다.

일반적인 수동 워크플로우는 다음과 같습니다.

  1. 포함할 애니메이션을 선택합니다.
  2. 오프닝과 엔딩 테마의 이름을 찾으세요.
  3. 각 노래별로 유튜브를 검색하세요.
  4. 사용 가능한 업로드를 확인하세요.
  5. 링크나 타임스탬프를 어딘가에 복사하세요.
  6. 소스 비디오를 다운로드하세요.
  7. 각 클립을 잘라내세요.
  8. 오디오를 정규화하거나 최소한 극심한 일관성 부족을 피하세요.
  9. 타이틀 오버레이/하프 세컨드를 추가하세요.
  10. 모든 것을 합친다.
  11. 문제가 생기면 다시 렌더링한다.

한 번만 하면 어렵지 않다. 문제는 반복이다.

하나의 클립을 만들고 있다면 일반적인 비디오 편집기가 충분합니다. 여러 애니메이션 제목, 여러 테마 곡, 여러 출처, 일관된 오버레이, 예측 가능한 출력 폴더로 구성된 구조화된 컴파일을 만들고 있다면, 워크플로우는 단발성 편집보다 더 작은 미디어 파이프라인처럼 되는 것입니다.

그것이 저가 해결하고자 했던 실제 문제였습니다.

“비디오 편집기를 대체한다는 것”이 아니었습니다.

더 가까운 것은:

지역 스튜디오를 알려줘서 반복적인 파이프라인 작업을 처리하도록 하고, 여전히 창의적인 선택을 제어할 수 있게 해줘.

Cuekiyo가 하는 일

Cuekiyo는 안내된 프로젝트 흐름을 중심으로 구축되었습니다.

프로젝트를 만들고 애니메이션 제목을 선택하며, 오프닝, 엔딩, 또는 둘 다를 원하는지 선택한 다음, 일련의 승인 단계를 진행합니다.

핵심 흐름은 다음과 같습니다:

  1. 프로젝트를 만들고
    이름을 지어주세요, 애니메이션 제목을 선택하고, 노래 유형을 고르고, 오버레이/렌더 기본 설정을 구성하세요.

  2. 노래를 선택하세요
    Cuekiyo는 테마 데이터를 로드하고 OP/ED 트랙 중 포함될 것을 승인할 수 있게 해줍니다.

  3. 클립 후보를 검토하세요
    유튜브 후보를 앱에서 제공하지만, 실제로 사용되는 것을 여전히 당신이 선택합니다. 자동화가 잘못되었을 때 당신의 링크를 붙여넣을 수도 있습니다.

  4. 클립을 자르고 처리
    Cuekiyo는 로컬에서 클립을 다운로드하고, 탐사하고, 정규화하고, 잘라내고, 오버레이합니다.

  5. 렌더링 순서 확인
    렌더링 전 최종 순서를 선택합니다.

  6. MP4로 내보내기
    최종 컴파일이 당신의 로컬 프로젝트 폴더에 작성되었습니다.

중요한 설계 규칙은 이것이었습니다.

자동화는 노동을 처리해야 하고, 취향은 그렇지 않아야 합니다.

그래서 Cuekiyo는 사용자 게이트에서 잠시 멈춥니다. 적절한 노래, 소스 클립, 잘라내기 지점, 최종 순서를 선택하는 것은 주관적입니다. 파이프라인은 도움이 될 수 있지만, 당신보다 당신의 취향을 더 잘 알아서는 안 됩니다.

로컬 우선인 이유는 무엇인가요?

Cuekiyo를 데스크톱 창의 도구처럼 느끼게 하고 싶었지만, 웹 앱의 개발 속도와 UI 유연성을 가지도록.

그래서 호스팅된 SaaS 제품을 만드는 대신 Cuekiyo는 로컬에서 실행됩니다.

  • 백엔드는 당신의 컴퓨터에서 실행됩니다.
  • 프론트엔드는 당신의 브라우저에서 실행됩니다.
  • 프로젝트 상태는 SQLite에 저장됩니다.
  • 미디어 파일은 data/projects/{id}/ 아래에 있습니다.
  • 로컬 FFmpeg를 통해 렌더링이 이루어집니다.
  • 임의의 클라우드 서비스에 업로드할 필요가 없습니다.

이런 종류의 앱에 중요한 이유는 비디오 파일이 크고, 저작권이 있는 미디어는 법적/서비스 약관 복잡성이 있으며, 창작자들은 자신의 파일에 직접적인 통제를 원하기 때문입니다.

로컬 우선 방식은 프로젝트 운영을 더 간단하게 유지합니다. 사용자 계정 시스템이 없으며, 저장소 청구, 호스팅 렌더링 큐, 클라우드 워커 페어트, 데이터베이스 서버 유지가 필요 없습니다.

이 거래의 대가는 사용자가 로컬 종속성을 설치해야 한다는 것입니다: Python, Node.js, FFmpeg, FFprobe, 및 yt-dlp. v1에서는 이 거래를 받아들였습니다. 그 이유는 핵심 제품을 먼저 출시하고 싶었기 때문입니다.

장기적으로 설치 경험을 “다운로드, 열기, 만들기”에 훨씬 가까워지고 싶습니다.

스택

Cuekiyo는 FastAPI 백엔드와 React 프론트엔드로 나뉩니다.

주 스택은 다음과 같습니다.

  • 백엔드: FastAPI, SQLAlchemy, SQLite
  • 프론트엔드: React 19, Vite, Tailwind CSS, shadcn/ui, React Router
  • 미디어: FFmpeg, FFprobe, yt-dlp
  • 오버레이 렌더링: Satori 기반 HTML-to-PNG 오버레이
  • 메타데이터: Jikan 및 AniList
  • 진행 업데이트: WebSockets
  • 프로젝트 저장소: 로컬 SQLite 데이터베이스 + 로컬 파일 시스템

프론트엔드는 지도형 워크플로우와 리뷰 화면을 처리합니다. 백엔드는 파이프라인, 상태 전환, 미디어 처리 및 파일시스템 안전을 소유합니다.

아키텍처

고수준으로 보면, Cuekiyo는 미디어 파이프라인을 감싼 상태 머신입니다.

파이프라인은 다음과 같은 단계를 거칩니다.

DRAFT
→ LOAD_THEMES
→ SONG_SELECTION
→ SOURCING
→ AWAITING_CANDIDATES
→ DOWNLOADING
→ PROBING_NORMALIZING
→ CUTTING
→ OVERLAYING
→ AWAITING_RENDER_ORDER
→ RENDERING
→ COMPLETED

전체 화면 모드 진입 전체 화면 모드 종료

일부 단계는 자동으로 실행됩니다. 다른 것들은 사용자 게이트입니다.

사용자 게이트가 중요한 부분입니다:

  • 노래 선택
  • 후보자 검토
  • 선택적 잘라내기/검토 결정
  • 최종 렌더링 순서

그 외의 모든 것은 자동화할 수 있습니다.

하나의 FastAPI 프로세스가 파이프라인을 소유합니다. 작업은 백그라운드 스레드에서 실행되며, 진행 상황은 WebSockets를 통해 프론트엔드로 전송됩니다. SQLite는 프로젝트 상태, 작업 상태, 활성 파이프라인 잠금의 심박수를 저장합니다.

v1에서 Cuekiyo는 하나의 글로벌 파이프라인 잠금을 사용합니다. 이는 한 번에 하나의 프로젝트를 렌더링/처리한다는 의미입니다. 이는 의도적으로 간단합니다. 여러 프로젝트 간의 복잡한 동시성 버그를 피하면서도, 크래시 복구를 이해하기 쉽게 유지합니다.

영원한 최종 아키텍처입니까? 아니요.

하지만 v1 로컬 앱을 위해서는 솔직하고 유지보수 가능합니다.

미디어 파이프라인

Cuekiyo의 가장 어려운 부분은 좋은 UI를 만드는 것이 아니었습니다.

가장 어려운 부분은 실제 세계의 이상한 상황에서 즉시 무너지지 않는 미디어 파이프라인을 만드는 것이었습니다.

외부 미디어 도구는 강력하지만, 많은 방식으로 실패합니다:

  • 원본 비디오가 사라집니다.
  • yt-dlp은 예상치 못한 메타데이터를 반환합니다.
  • FFmpeg은 인코더 문제로 실패합니다.
  • 클립의 지속 시간이나 스트림 데이터가 이상합니다.
  • 경로에 처리해야 할 문자가 포함되어 있습니다.
  • GPU 인코딩은 당신의 기기에서 작동하지만 다른 사람의 기기에서는 작동하지 않습니다.
  • 다운로드된 파일이 존재하지만 나중에 처리된 잔여물이 존재하지 않습니다.

Cuekiyo는 각 단계를 별도의 파이프라인 단계로 취급하여 그 문제들을 관리 가능하게 시도합니다.

다운로드, 탐사, 정규화, 잘라내기, 오버레이, 렌더링은 구별된 작업입니다. 이는 흐름을 검사하기 쉽게, 다시 시도하기 쉽게, UI에서 설명하기 쉽게 만듭니다.

나는 또한 서브프로세스 인자를 셸 문자열 대신 인자 배열로 전달하는 것을 강조했다. 로컬 미디어 도구는 사용자가 제공한 링크와 파일 시스템 경로를 조작하므로, 그것은 선택적 완성도가 아니다. 그것은 기본 안전이다.

GPU 인코딩 및 대체

나는 초기에 원했던 기능 중 하나는 NVIDIA NVENC 지원이었다.

지역 비디오 작업을 하는 많은 사람들이 NVIDIA GPU를 사용하며, 하드웨어 인코딩은 렌더링을 훨씬 빠르게 할 수 있습니다. 하지만 NVENC을 강제로 요구하는 것은 나쁜 생각입니다. 모든 기기가 이를 지원하지 않고 FFmpeg 빌드는 다양하기 때문입니다.

그래서 Cuekiyo는 NVENC 지원을 확인하고 필요할 때는 libx264로 CPU 인코딩으로 되돌아갑니다.

그런 백업 방식은 중요합니다. 로컬 우선 소프트웨어는 다양한 사용자 머신을 부드럽게 처리해야 합니다. 환경이 당신과 정확히 같다고 가정할 수는 없습니다.

프론트엔드

프론트엔드는 React 19, Vite, Tailwind CSS, shadcn/ui, 그리고 React Router로 구축되었습니다.

UI 목표는 원시 관리 대시보드처럼 보이지 않도록 했습니다. 더 창의적인 도구처럼 느껴지도록 하고 싶었습니다:

  • 프로젝트 카드
  • 지도된 단계
  • 명확한 상태 상태
  • 클립 후보 검토
  • 보이는 진행 상황
  • 파이프라인에 영향을 미치는 설정이지만 공포스럽지 않은 설정

프론트엔드는 API 경로와 WebSocket 진행 이벤트를 통해 백엔드와 통신합니다. 실시간 진행 피드백은 중요합니다. 미디어 작업은 시간이 걸릴 수 있기 때문입니다. FFmpeg가 실행되는 동안 UI가 침묵적으로 있으면 사용자는 무언가 문제가 발생했다고 생각합니다.

백엔드가 무거운 작업을 하고 있더라도 프론트엔드는 파이프라인이 이해하기 쉽게 느껴져야 합니다.

가장 큰 디자인 결정: 사용자가 선택해야 할 때만 일시 중지합니다

많은 자동화 도구들은 두 가지 중 하나의 실수를 합니다.

  1. 너무 적게 자동화하여 사용자가 여전히 지루한 일을 모두 해야 하거나.
  2. 너무 많이 자동화하여 사용자가 나중에 잘못된 결정을 정리해야 합니다.

Cuekiyo의 중간 지점은 사용자 게이트 모델입니다.

앱이 매우 작은 기술적 단계마다 확인을 요청해서는 안 됩니다. 그럴 것은 짜증나죠.

하지만 모든 유튜브 소스와 최종 명령을 검토 없이 조용히 선택해서는 안 됩니다. 그럴 경우 위험합니다.

따라서 파이프라인은 기계적 단계를 통해 자동으로 진행되며, 취향 기반의 결정에서 멈춥니다.

그 모델은 제품이 훨씬 더 좋은 느낌을 주었습니다. 또한 백엔드를 이해하기 쉽게 만들었으며, 게이트드 상태가 상태 머신의 명확한 부분이 되어서 무작위 UI 조건이 아닌 것입니다.

알려진 v1 트레이드오프

Cuekiyo v1.0.0은 완벽하지 않으며, 그것이 완벽하다고 속이고 싶지 않습니다.

가장 큰 v1 트레이드오프는 다음과 같습니다:

한 번에 하나의 파이프라인 작업

전역 잠금은 작업 실행기를 단순화시키고 여러 프로젝트가 지역 자원을 놓고 싸우는 것을 방지합니다. 단점은 프로젝트 간의 병렬성을 지원하지 않는다는 것입니다.

지역 v1 릴리스를 위해 이것은 수용 가능하다고 생각합니다. 병렬 작업은 로드맵에 있습니다.

간소화된 concat/crossfade 그래프

현재 렌더링 경로는 컴파일 흐름을 지원하지만, FFmpeg 필터 그래프는 더 복잡해질 수 있습니다. 풍부한 렌더링 그래프는 향후 전환 및 다중 클립 레이아웃을 쉽게 만들게 됩니다.

재시도는 더 현명할 수 있습니다

현재 재시도 흐름은 v1 모델에 충분하지만, 더 내구성 있는 단계별 커서가 더 좋을 것입니다. 그렇게 하면 앱이 정확한 실패 경계에서 재개할 수 있게 됩니다.

이것들은 숨겨진 문제가 아닙니다. 이것들은 문서화되었기 때문에 아키텍처에 대해 솔직하기를 선호하기 때문입니다. v1의 모든 결정이 최종적인 것처럼 가장하기보다는.

나가 배운 것

큐키요가 저에게 몇 가지를 가르쳐주었습니다.

1. 로컬 우선 앱도 제품 사고가 필요합니다

“로컬 도구”라고 생각하기 쉽지만, 큐키요는 단순히 UI가 있는 스크립트가 아닙니다. 온보딩, 명확한 상태, 유용한 오류, 비작가도 이해할 수 있는 워크플로우가 필요합니다.

로컬에서 실행된다는 사실은 제품 설계의 필요성을 제거하지 않습니다.

2. 워크플로우가 많은 앱에서는 상태 기계가 가치가 있습니다

앱에 긴급 실행 작업, 사용자 게이트, 재시도, 실패, 취소 및 진행 이벤트가 있으면, 암시된 상태는 매우 빨리 고통스러워집니다.

파이프라인 상태를 명시적으로 만들어서 많은 도움이 되었습니다.

3. FFmpeg은 강력하지만, 래퍼 코드가 중요합니다

FFmpeg는 거의 모든 일을 할 수 있지만, 사용자는 명령 그래프에 신경 쓰지 않아야 합니다. 실제 작업은 이를 둘러싼 안전하고 검토 가능한 레이어를 구축하는 것입니다.

4. "모든 것을 자동화한다"는 항상 올바른 제품은 아닙니다

Cuekiyo의 최고 버전은 盲目하게 영상을 만드는 봇이 아닙니다. 반복적인 노동을 제거하면서도 인간의 선택을 포함하는 스튜디오입니다.

그 구분은 전체 앱 설계 방식을 바꾸었습니다.

다음은 무엇인가

v1.0.0이 공개되었으니, 다음 집중점은 Cuekiyo를 더 쉽게 시도할 수 있도록 만드는 것입니다.

가장 큰 우선순위는 다음과 같습니다:

  • 더 나은 초기 실행 경험
  • 가볍게 전용 데스크톱 형식 릴리스
  • 더 나은 설치/의존성 검사
  • 더 현명한 재시도 동작
  • 병렬 프로젝트 작업
  • 더 풍부한 렌더링/크로스페이드 옵션
  • 더 창작자 중심의 문서와 데모

핵심 파이프라인은 작동하지만, 발견 가능성과 설치 마찰이 오픈 소스 프로젝트에 매우 중요합니다. 관심이 있는 사람은 빠르게 프로젝트를 이해하고 시도할 수 있어야 합니다.

마지막 생각

Cuekiyo는 전문적인 아이디어로 시작했지만, 지금까지 제가 만든 프로젝트 중 가장 완전한 프로젝트 중 하나가 되었습니다.

이 프로젝트는 전체 스택 앱 개발, 로컬 우선 아키텍처, 미디어 처리, 백그라운드 작업, WebSocket 진행률, UI/UX 디자인, 릴리스 엔지니어링을 하나의 프로젝트로 통합했습니다.

그것이 바로 제 포트폴리오에 원했던 종류의 프로젝트입니다: 데모만이 아니라 제품 결정, 트레이드오프, 실제 워크플로우를 가진 실제 도구입니다.

로컬 우선 도구, 미디어 자동화, React/FastAPI 앱, 혹은 그냥 이상하게 구체적인 오픈 소스 소프트웨어에 관심이 있다면 자유롭게 확인해 보세요.

GitHub: https://github.com/unloopedmido/cuekiyo

별과 피드백은 진심으로 감사드립니다.