쇼츠팩토리 제작기(1) - Python에서 Electron으로

"2025년 말, 나도 유튜브를 시작해볼까?"
2025년 말쯤, 오래 미뤄둔 생각을 다시 꺼냈습니다.
"나도 유튜브를 한번 제대로 해볼까?"
아이디어가 없어서 못 한 것은 아니었습니다. 오히려 하고 싶은 이야기는 많았습니다. AI 자동화, 업무 생산성, 제가 직접 만든 도구들, 비개발자가 개발을 시도하며 겪은 시행착오까지 소재는 충분했습니다.
문제는 영상 편집이었습니다. 촬영보다 편집이 더 부담스러웠습니다. 컷을 자르고, 말이 비는 구간을 지우고, 자막을 맞추고, 효과음을 넣고, 세로 화면에 맞게 다시 구성하는 일을 매번 해야 한다고 생각하니 시작하기 전부터 지쳤습니다.
전문 편집툴을 배우는 것도 방법이었습니다. CapCut, Premiere Pro, DaVinci Resolve 같은 도구를 익히면 훨씬 많은 것을 할 수 있습니다. 하지만 제 목표는 전문 편집자가 되는 것이 아니었습니다. 제가 반복해서 만들 쇼츠 형식을 빠르게 뽑아내는 것이 목표였습니다.
그때 생각이 바뀌었습니다.
"편집툴을 배우는 대신, 내 편집 루틴을 프로그램으로 만들면 되지 않을까?"
그렇게 쇼츠팩토리(Shorts Factory)가 시작됐습니다.
범용 편집기가 아니라 내 작업대가 필요했다
처음부터 거창한 서비스를 만들 생각은 아니었습니다. 제가 필요했던 것은 범용 편집기가 아니라 반복 작업을 줄여주는 개인용 작업대였습니다.
제가 반복해서 하게 될 작업은 거의 정해져 있었습니다.
- 긴 원본 영상에서 쓸 만한 구간을 찾습니다.
- 말이 비거나 늘어지는 구간을 줄입니다.
- 핵심 문장을 앞부분에 배치합니다.
- 음성을 자막으로 바꿉니다.
- 세로 화면에 맞게 크롭합니다.
- 결과물을 빠르게 확인하고 다시 뽑습니다.
이 정도라면 모든 편집 기능을 다 만들 필요가 없었습니다. 오히려 기능을 줄여야 했습니다. 범용 편집기처럼 자유도가 높은 도구는 강력하지만, 매번 사람이 판단해야 할 것도 많습니다. 저는 자유도보다 반복 제거가 더 중요했습니다.
그래서 쇼츠팩토리의 첫 목표는 명확했습니다.
"원본을 넣으면, 올릴 만한 쇼츠 후보를 자동으로 뽑아주는 도구."
이 기준이 생기자 기술 선택도 달라졌습니다. 중요한 것은 멋진 기술 스택이 아니라, 매일 써도 귀찮지 않은 흐름이었습니다.
첫 시도: Python과 PyQt6
처음에는 Python으로 시작했습니다. 영상 처리, 음성 인식, 파일 조작은 Python 생태계가 익숙했고, 빠르게 실험하기 좋았습니다. 자연스럽게 UI도 Python에서 만들고 싶었습니다. 그래서 PyQt6로 첫 버전을 구성했습니다.
PyQt6 자체가 부족한 도구라는 뜻은 아닙니다. Qt 계열은 오래된 데스크톱 UI 생태계이고, Python 바인딩을 통해 충분히 안정적인 앱을 만들 수 있습니다. 단순한 설정창, 파일 변환 도구, 내부 관리 프로그램이라면 좋은 선택이 될 수 있습니다.
하지만 쇼츠팩토리는 조금 달랐습니다. 이 앱은 단순한 버튼 몇 개짜리 변환기가 아니었습니다. 원본 영상, 분석 상태, 진행률, 미리보기, 자막 후보, 렌더링 로그, 결과 파일을 한 화면에서 계속 보여줘야 했습니다.
제가 PyQt로 만들면서 불편했던 지점은 크게 네 가지였습니다.
| 문제 | 실제로 불편했던 점 |
|---|---|
| 상태 표현 | 분석 중, 자막 생성 중, 렌더링 중 같은 단계를 자연스럽게 보여주기 어려웠습니다. |
| 레이아웃 실험 | 카드형 UI, 미리보기 패널, 작업 큐 같은 화면을 빠르게 바꾸기 번거로웠습니다. |
| 스타일링 | CSS처럼 세밀하게 톤을 조정하며 시안을 반복하기가 답답했습니다. |
| 프론트/엔진 분리 | 영상 처리 엔진과 조작 화면이 한 덩어리처럼 느껴져 구조가 점점 무거워졌습니다. |
처음에는 "조금 더 다듬으면 되겠지"라고 생각했습니다. 그런데 화면을 고칠 때마다 핵심 기능보다 UI 구현에 시간을 더 쓰고 있었습니다. 제가 만들고 싶은 것은 영상 제작 루틴을 줄여주는 도구였는데, 정작 저는 레이아웃과 위젯 배치에 붙잡혀 있었습니다.
그때 전환을 결정했습니다.
Electron으로 옮긴 이유
Electron으로 옮긴 이유는 단순히 화면을 예쁘게 만들기 위해서가 아니었습니다. 더 정확히 말하면, UI와 영상 처리 엔진을 분리하기 위해서였습니다.
Electron은 데스크톱 앱이지만 화면은 웹 기술로 만듭니다. React를 붙이면 상태 변화가 많은 화면을 구성하기 좋습니다. 원본 파일이 들어오고, 분석 단계가 바뀌고, 자막 후보가 생기고, 렌더링 진행률이 올라가는 흐름을 컴포넌트 단위로 쪼갤 수 있습니다.
저는 구조를 이렇게 잡았습니다.
사용자
↓
Electron + React UI
- 파일 선택
- 작업 상태 표시
- 미리보기
- 결과 확인
↓
IPC 또는 로컬 API
↓
Python 영상 처리 엔진
- 원본 분석
- 음성 인식
- 자막 생성
- 세로 영상 렌더링
↓
출력 폴더
이렇게 나누자 각자의 역할이 선명해졌습니다.
Electron과 React는 사람이 만지는 작업대가 됐습니다. Python은 무거운 계산을 처리하는 엔진으로 남았습니다. 화면은 화면답게 빠르게 바꾸고, 영상 처리는 Python에서 안정적으로 돌리는 구조가 된 것입니다.
중요한 것은 "무거운 작업을 UI에서 떼어내는 것"이었다
Electron으로 바꾼다고 모든 문제가 자동으로 해결되지는 않습니다. 오히려 잘못 만들면 Electron 앱은 쉽게 무거워집니다. 공식 문서에서도 main process와 UI thread를 오래 막지 말라고 강조합니다. 영상 분석이나 렌더링 같은 작업을 UI 흐름 안에서 직접 붙잡고 있으면 앱 전체가 굼떠집니다.
그래서 쇼츠팩토리에서는 UI가 직접 영상을 처리하지 않도록 했습니다. UI는 요청을 보내고, 상태를 받고, 결과를 보여주는 역할에 집중했습니다. 오래 걸리는 작업은 Python 엔진이 맡고, UI는 진행 상황을 계속 표시하는 구조가 더 안전했습니다.
이 구조가 중요한 이유는 사용감 때문입니다.
영상 도구에서 사용자가 가장 불안해지는 순간은 "지금 멈춘 건가?"라는 생각이 들 때입니다. 렌더링이 40초 걸리는 것은 참을 수 있습니다. 하지만 40초 동안 아무 표시도 없으면 실패처럼 느껴집니다.
그래서 v1에서 제가 중요하게 본 것은 속도만이 아니었습니다.
- 지금 어떤 단계인지 보여주는가
- 실패하면 어디서 실패했는지 알 수 있는가
- 결과 파일이 어디에 저장됐는지 바로 알 수 있는가
- 다시 실행할 때 같은 설정을 반복 입력하지 않아도 되는가
- UI가 멈춘 것처럼 보이지 않는가
이 질문에 답하려면 UI와 엔진을 분리해야 했습니다. Electron 전환은 디자인 선택이 아니라 운영 구조 선택에 가까웠습니다.
쇼츠팩토리 v1의 파이프라인
v1에서 목표로 한 파이프라인은 단순했습니다. 다만 그 단순함을 만들기 위해 내부 단계는 꽤 많이 나눠야 했습니다.
- 원본 영상을 선택합니다.
- 영상 길이와 기본 메타데이터를 확인합니다.
- 음성을 분석해 말이 있는 구간을 찾습니다.
- Whisper 기반 전사 결과를 자막 후보로 만듭니다.
- 말의 밀도와 장면 변화를 기준으로 하이라이트 후보를 뽑습니다.
- 앞부분에 후킹이 될 만한 문장을 배치합니다.
- 세로 화면에 맞춰 크롭하고 자막을 합성합니다.
- 최종 결과물을 렌더링합니다.
- 결과 파일을 확인하고 다시 실행할 수 있게 합니다.
원문에서는 이 과정을 "AI 기반 병렬 파이프라인"이라고 짧게 적었지만, 실제로 중요한 것은 병렬이라는 말보다 작업을 끊어낸 방식이었습니다.
예를 들어 자막 생성은 단순히 음성을 글자로 바꾸는 일이 아니었습니다. 자동 전사 결과는 그대로 쓰기 어렵습니다. 문장이 너무 길거나, 줄바꿈이 어색하거나, 말이 겹치는 구간이 생깁니다. 쇼츠에서는 자막이 곧 리듬이기 때문에, 전사 결과를 화면에 맞는 단위로 다시 잘라야 했습니다.
하이라이트 추출도 마찬가지였습니다. 영상에서 "흥미로운 구간"을 찾는다는 말은 멋있지만, 실제 구현에서는 기준이 필요합니다. 말의 밀도가 높은 구간인지, 침묵이 적은 구간인지, 첫 문장이 강한 구간인지, 화면 변화가 있는 구간인지 따져야 합니다.
그래서 v1의 핵심은 AI가 모든 것을 멋지게 판단했다는 데 있지 않았습니다. 사람이 반복해서 하던 판단을 프로그램이 다룰 수 있는 작은 기준으로 쪼갠 데 있었습니다.
PyQt에서 Electron으로 바꾸며 얻은 것
전환 후 가장 크게 달라진 것은 개발 속도보다 피드백 속도였습니다.
PyQt로 만들 때는 화면을 고치는 일이 부담스러웠습니다. 버튼 위치를 바꾸고, 미리보기 영역을 조정하고, 상태 표시 방식을 바꾸는 작은 수정도 마음처럼 빠르게 되지 않았습니다. 반면 React 기반 UI에서는 화면을 컴포넌트로 나누고 상태에 따라 보여줄 내용을 바꾸는 흐름이 훨씬 자연스러웠습니다.
특히 다음 요소들이 좋아졌습니다.
- 작업 단계별 상태 배지를 만들기 쉬워졌습니다.
- 원본, 분석 결과, 출력 파일을 카드 단위로 배치할 수 있었습니다.
- 진행률과 로그를 동시에 보여주는 화면을 구성하기 쉬웠습니다.
- 실패 상태와 재시도 버튼을 한 화면에 묶을 수 있었습니다.
- 나중에 웹 기반 도구로 확장할 가능성도 생겼습니다.
여기서 중요한 점은 "예쁜 UI"가 목적이 아니었다는 것입니다. 영상 제작 도구에서 UI는 단순 장식이 아닙니다. 사용자가 다음 행동을 판단하는 계기판입니다. 지금 분석 중인지, 실패했는지, 결과가 나왔는지, 다시 돌릴 수 있는지 알아야 계속 쓰게 됩니다.
Electron으로 옮긴 뒤 쇼츠팩토리는 단순한 스크립트 묶음에서 작업 흐름을 가진 앱으로 바뀌었습니다.
대신 새로 생긴 숙제
물론 Electron 전환이 항상 정답은 아닙니다. 이 선택으로 새로 생긴 숙제도 있었습니다.
첫째, 앱이 무거워질 수 있습니다. Electron은 Chromium 기반이라 가벼운 네이티브 위젯 앱보다 자원을 더 쓸 수 있습니다. 그래서 화면을 예쁘게 만드는 것보다 렌더러를 막지 않는 구조가 중요했습니다.
둘째, 보안 경계를 신경 써야 합니다. 로컬 앱이라고 해서 renderer에 파일 시스템 접근이나 Node API를 무작정 열어두면 안 됩니다. 필요한 기능만 preload와 IPC를 통해 제한적으로 노출하는 구조가 필요했습니다.
셋째, Python 엔진과 Electron 앱을 함께 배포하는 문제가 생깁니다. 개발 환경에서는 잘 돌아가도, 다른 PC에서 실행하려면 Python 런타임, 모델 파일, FFmpeg 같은 외부 도구, 경로 문제를 정리해야 합니다.
넷째, 실패 로그가 더 중요해졌습니다. UI와 엔진이 분리되면 "화면 문제인지", "Python 처리 문제인지", "입력 파일 문제인지"를 구분해야 합니다. 그래서 단순히 에러를 띄우는 것보다 어느 단계에서 어떤 입력으로 실패했는지 남기는 구조가 필요했습니다.
이 숙제들 때문에 v1은 완성형이라기보다 기반 공사에 가까웠습니다. 하지만 이 기반이 없었다면 다음 단계로 갈 수 없었습니다.
v1의 진짜 성과
v1의 성과는 "멋진 데스크톱 앱을 만들었다"가 아닙니다. 더 정확히는 제 콘텐츠 제작 루틴을 처음으로 코드로 옮긴 것입니다.
이전에는 편집을 시작하려면 마음을 먹어야 했습니다. 이제는 원본을 넣고 결과 후보를 확인하는 흐름까지는 프로그램이 밀어줍니다. 편집이라는 큰 부담이 "후보를 보고 고르는 일"로 줄어든 것입니다.
이 변화는 생각보다 컸습니다.
사람이 가장 미루는 일은 어려운 일이 아니라 시작 비용이 큰 일입니다. 영상 편집도 그랬습니다. 타임라인을 열고, 파일을 불러오고, 어디를 잘라야 할지 보는 순간부터 피로가 생깁니다. 쇼츠팩토리 v1은 그 시작 비용을 낮추기 위한 도구였습니다.
물론 아직 완전 자동화는 아니었습니다. 저는 여전히 원본을 고르고, 결과를 확인하고, 마음에 들지 않으면 다시 실행해야 했습니다. 하지만 적어도 반복 작업의 상당 부분은 프로그램 쪽으로 넘어갔습니다.
그래서 v1은 "쇼츠를 자동으로 만들어주는 최종 제품"이라기보다, 자동화 가능한 작업과 사람이 판단해야 하는 작업을 처음으로 분리한 버전이었습니다.
v2로 이어진 질문
v1을 만들고 나니 다음 질문이 자연스럽게 생겼습니다.
"이제 버튼 누르는 일도 AI에게 맡길 수 있지 않을까?"
v1에서는 제가 앱을 조작했습니다. Electron UI에서 원본을 고르고, 실행 버튼을 누르고, 결과를 확인했습니다. 기능은 자동화됐지만 운영은 여전히 사람이 들고 있었습니다.
이 지점이 v2의 출발점이 됐습니다. v1이 "내가 쓰기 편한 작업대"였다면, v2는 "AI가 호출할 수 있는 제작 파이프라인"을 향했습니다.
그래서 PyQt에서 Electron으로 옮긴 결정은 단순한 기술 변경이 아니었습니다. 나중에 Skill 기반 자동화로 넘어가기 위한 중간 단계였습니다. 먼저 작업 흐름을 앱으로 정리했고, 그다음 그 흐름을 에이전트가 실행할 수 있는 계약으로 바꾼 것입니다.
마치며
쇼츠팩토리 v1을 만들며 가장 크게 배운 것은, 도구의 가치는 기능 목록보다 사용 흐름에서 나온다는 점입니다.
PyQt로 시작한 것은 틀린 선택이 아니었습니다. Python으로 빠르게 실험하고, 영상 처리 엔진의 가능성을 확인하기에는 좋은 출발점이었습니다. 다만 쇼츠팩토리가 진짜 작업 도구가 되려면 미리보기, 상태 표시, 재시도, 결과 확인이 자연스럽게 이어지는 화면이 필요했습니다.
그래서 Electron과 React로 옮겼습니다. 화면은 웹 기술로 빠르게 다듬고, 무거운 영상 처리는 Python 엔진에 맡기는 구조가 이 프로젝트에는 더 맞았습니다.
이 버전 덕분에 편집의 공포는 조금 줄었습니다. 더 정확히 말하면, 막막한 편집 작업이 확인 가능한 제작 흐름으로 바뀌었습니다. v1은 완성된 자동화가 아니라 자동화를 담을 그릇을 만든 작업이었습니다.
그리고 그 그릇이 있었기 때문에, 다음 단계에서 AI에게 실행을 맡기는 실험까지 이어질 수 있었습니다.
참고한 자료
- Electron, Process Model: https://www.electronjs.org/docs/latest/tutorial/process-model
- Electron, Performance: https://www.electronjs.org/docs/latest/tutorial/performance
- Electron, Security: https://www.electronjs.org/docs/latest/tutorial/security
- Electron, Context Isolation: https://www.electronjs.org/docs/latest/tutorial/context-isolation
- Qt for Python 공식 문서: https://doc.qt.io/qtforpython-6/
- OpenAI, Introducing Whisper: https://openai.com/index/whisper/
- OpenAI Whisper GitHub: https://github.com/openai/whisper