음악을 만지는 사람들에게 "스템 분리(stem separation)"는 오래된 꿈입니다. 완성된 노래 한 곡은 보컬·드럼·베이스 같은 여러 소리가 이미 한 덩어리로 합쳐진 상태인데, 이걸 다시 악기별로 떼어내는 작업이죠. 노래방 반주를 만들거나, 베이스 라인을 귀로 따려고(채보) 하거나, 리믹스를 할 때 꼭 필요합니다. 그동안은 Moises나 LALAL.AI 같은 클라우드 유료 서비스에 파일을 올려야 했는데, StemDeck은 그 일을 내 노트북 안에서 공짜로 해냅니다.
당신이 좋아하는 노래 MP3를 책상 위 작은 기계에 넣습니다. 잠시 윙― 돌아가더니, 한 곡이었던 소리가 보컬 칸, 드럼 칸, 베이스 칸… 이렇게 여러 줄(레인)로 나뉘어 모니터에 펼쳐집니다. 각 칸에는 볼륨 손잡이와 음소거 버튼이 달려 있어서, 드럼만 끄고 들어 보거나 보컬만 솔로로 들어 볼 수 있죠. 마음에 드는 조합이 나오면 그 믹스를 WAV 파일로 뽑아 갑니다. 중요한 건 이 스튜디오가 인터넷에 연결돼 있지 않다는 점 — 당신의 노래는 이 방을 절대 떠나지 않습니다.
기술적으로 풀면, StemDeck은 웹 기술로 만든 데스크톱 앱입니다. 안에는 작은 웹 서버(FastAPI)가 돌고, 실제 분리는 Meta(페이스북)가 공개한 인공지능 모델 Demucs가 담당합니다. 화면(파형·믹서)은 브라우저 기술로 그리고, 그 브라우저를 통째로 감싸 진짜 프로그램처럼 만들어주는 껍데기가 Tauri입니다. 이 세 조각의 조합이 이 프로젝트의 전부이자 가장 배울 점이 많은 부분입니다.
StemDeck이 TrendShift 상위권에 오른 이유는 단순히 "또 하나의 AI 도구"여서가 아닙니다. 요즘 개발자·창작자 사이에서 커지는 두 흐름에 정확히 올라탔기 때문입니다: ① 내 데이터를 남의 서버에 올리기 싫다는 프라이버시·로컬 우선(local-first) 욕구, ② 구독료 대신 한 번 받아 평생 쓰는 셀프호스팅(self-hosted) 선호.
경쟁자인 클라우드 서비스와의 차이를 저장소가 아주 정직하게 표로 정리해 둔 점도 인상적입니다. "우리가 더 좋다"가 아니라 "우리는 여기까지만 잘하고, 나머지는 유료 서비스가 낫다"고 먼저 인정하죠. 핵심 비교를 추려 보면:
| 항목 | StemDeck | Moises · LALAL.AI (클라우드 유료) |
|---|---|---|
| 가격 | 완전 무료, 영구 | 무료체험 후 크레딧·구독 필요 |
| 처리 위치 | 내 컴퓨터 안에서만 | 파일을 그들의 서버로 업로드 |
| 계정 | 필요 없음 | 필수 |
| 프라이버시 | 오디오가 기기를 떠나지 않음 | 업로드 후 제3자 서버에서 처리 |
| 분리 모델 | Demucs htdemucs_6s (오픈소스) | 비공개 자체 모델 (대체로 더 고품질) |
| 스템 수 | 6개 | 최대 10개 (플랜별) |
| 속도 | 내 하드웨어에 좌우 (GPU면 빠름) | 하드웨어 무관 빠름 (서버가 처리) |
| 소스 공개 | 오픈소스, 포크·셀프호스팅 가능 | 비공개 |
오픈소스 프로젝트가 상용 제품과 경쟁할 때, 단점을 숨기지 않고 "속도·품질·모바일 앱이 필요하면 유료가 낫다"고 먼저 말하면 오히려 신뢰를 얻습니다. 사용자가 "써 보고 나서 빈틈을 발견"하는 대신 "처음부터 알고 선택"하게 만드는 것 — README가 직접 밝힌 의도입니다.
또 하나 주목할 점은 "다운로더가 아니라 분리 도구"라는 선 긋기입니다. 유튜브 URL을 받긴 하지만, 저장소는 "본래 용도는 당신이 이미 가진 오디오 파일을 처리하는 것"이라고 못 박고, 다운로드한 콘텐츠를 저장·캐시·재배포하지 않는다고 명시합니다. 법적 리스크가 큰 영역에서 의도와 책임 소재를 분명히 하는 방식도 오픈소스 운영의 교과서적 사례입니다.
StemDeck은 한 가지 언어로 된 단일 프로그램이 아니라, 역할이 다른 세 개의 층이 맞물린 구조입니다. 깃허브 언어 통계(JavaScript 30% · CSS 27% · Python 18% · Rust 11% · HTML 7% · Shell 4%)가 이 다층 구조를 그대로 보여줍니다. 하나씩 뜯어봅시다.
실제 "무거운 일"을 하는 층입니다. 작은 웹 서버를 띄워 두고, 프론트엔드가 보낸 요청(이 노래를 분리해 줘)을 받아 인공지능 파이프라인을 돌립니다.
| 도구 | 역할 | 한 줄 풀이 |
|---|---|---|
| Python 3.10+ | 백엔드 언어 | AI·오디오 라이브러리가 가장 풍부한 언어 |
| FastAPI | 웹 서버 프레임워크 | 요청을 받고 응답하는 "접수 창구" |
| Uvicorn | 서버 실행기(ASGI) | FastAPI 앱을 실제로 켜 두는 엔진 |
| Demucs (htdemucs_6s) | 스템 분리 AI | 노래를 6트랙으로 쪼개는 Meta의 신경망 |
| PyTorch / torchaudio | AI 실행 엔진 | Demucs가 올라타 도는 딥러닝 토대 |
| yt-dlp | 유튜브 오디오 받기 | URL에서 음원만 떼어 오는 도구 |
| FFmpeg | 오디오 변환·믹싱 | 포맷 변환과 트랙 합치기 만능 칼 |
| librosa | 음악 분석 | BPM(빠르기)·키(조성) 자동 추출 |
| pyloudnorm | 음량 측정 | 방송 표준(BS.1770)으로 체감 음량 계산 |
| uv | 패키지 관리자 | 파이썬 라이브러리를 빠르게 설치·고정 |
요즘 웹 앱이 거의 다 React·Vue 같은 프레임워크를 쓰는 것과 정반대로, StemDeck의 화면은 순수 바닐라 JavaScript + Web Audio API로만 짜였습니다. 빌드 단계(컴파일)조차 없어서, static/ 폴더의 .js 파일이 곧 브라우저가 실행하는 코드 그 자체입니다.
"빌드 단계가 없다"는 건, 가구를 살 때 조립이 필요한 이케아 가구(빌드 필요)가 아니라 완성된 채로 배송 오는 가구(빌드 없음)와 같습니다. 코드를 고치면 변환·번들링 과정 없이 새로고침만으로 바로 화면에 반영되죠. 배우기엔 더없이 투명하지만, 규모가 커지면 관리가 힘들어지는 트레이드오프가 있습니다.
| 도구 | 역할 | 한 줄 풀이 |
|---|---|---|
| Vanilla JS | 화면 로직 | 프레임워크 없이 순수 자바스크립트로 직접 제어 |
| Web Audio API | 브라우저 내 오디오 처리 | 볼륨·음소거·VU 미터를 브라우저가 직접 계산 |
| Canvas | 파형 그리기 | min/max 샘플 렌더링으로 파형을 그림판처럼 직접 그림 |
| multitrack.js (vendor) | 멀티트랙 표시 | 여러 트랙을 가지런히 정렬해 보여주는 보조 라이브러리 |
위의 웹 서버 + 웹 화면을 그냥 브라우저로 열어도 동작하지만(localhost:8000), 일반 사용자에게는 "진짜 설치되는 앱"이 필요합니다. 그 껍데기를 만드는 게 Tauri입니다. macOS·Windows용 .dmg/.exe를 만들어, 사용자는 파이썬이나 명령어를 전혀 몰라도 더블클릭만으로 쓸 수 있죠.
desktop/src-tauri/src/main.rs가 바로 이 껍데기 + 내장 파이썬 서버를 띄우고 관리하는 러스트 코드입니다.서버로 띄우고 싶은 사람을 위해 Docker 구성(build/Dockerfile, docker-compose.yml)이 준비돼 있고, 코드가 바뀔 때마다 자동으로 테스트·빌드하는 CI(지속적 통합)는 흔한 GitHub Actions가 아니라 Woodpecker CI를 씁니다 — 이것 자체가 셀프호스팅이 가능한 오픈소스 CI라, 프로젝트의 "셀프호스팅 철학"과 일관됩니다.
StemDeck의 심장은 app/pipeline/ 폴더에 있는 잡 파이프라인(job pipeline)입니다. 사용자가 노래를 넣으면 하나의 "잡(작업 건)"이 만들어지고, 이 잡이 정해진 5단계 컨베이어 벨트를 순서대로 지나갑니다. 전체 흐름을 그림으로 보면:
Demucs는 GPU·CPU를 통째로 잡아먹는 무거운 작업입니다. 두 곡을 동시에 돌리면 둘 다 느려지거나 메모리가 터지죠. 그래서 runner.py는 세마포어(Semaphore)를 1로 걸어 둡니다 — "이 문은 한 번에 한 사람만 통과"라는 신호등입니다. 여러 요청이 와도 무거운 분리 작업은 줄을 서서 차례로 처리됩니다(대기 잡이 3개를 넘으면 503으로 거절).
분리 단계(separate.py)는 Demucs를 같은 프로세스 안에서 부르지 않고, 별도 프로그램(서브프로세스)으로 띄웁니다. 이렇게 하면 두 가지 이득이 있습니다: ① 사용자가 "취소"를 누르면 그 프로세스만 즉시 죽일 수 있고(메인 서버는 멀쩡), ② AI가 멈춰 버려도(GPU 데드락 등) 서버 전체가 같이 죽지 않습니다.
여기에 워치독(watchdog, 감시견) 스레드를 붙인 게 인상적입니다. Demucs는 진행 상황을 stderr(오류 출력 통로)에 23%처럼 찍는데, 코드는 이걸 한 글자씩 읽으며 \r(같은 줄 다시 그리기) 문자를 기준으로 잘라 진행률을 뽑아냅니다. 그리고 감시견은 "30초마다 깨어나, 마지막 출력 이후 너무 오래(설정값) 조용하면 잡이 멈춘 것으로 보고 프로세스를 종료"합니다.
POST /cancel이 호출되면 코드는 Demucs 프로세스에 terminate()를 보냅니다. 그러면 출력 통로가 끊겨(EOF) 읽기 루프가 자연스럽게 끝나고, proc.wait()가 0이 아닌 종료코드를 돌려줍니다. 코드는 이 상황을 "에러"가 아니라 "사용자 취소(JobCancelled)"로 먼저 해석해, 부분 결과 폴더를 지우고 깔끔히 "취소됨" 상태로 돌아갑니다. 실패와 취소를 구분하는 이런 디테일이 견고한 서버 코드의 핵심입니다.
runner.py의 _prepare_local_source()는 작지만 중요한 함정을 막습니다. 사용자가 24비트·32비트 실수·고샘플레이트·다채널 WAV를 올리면 Demucs가 조용히 무음(silence)을 뱉는 버그가 있는데, 이를 피하려고 모든 업로드를 먼저 FFmpeg로 16비트·44.1kHz·스테레오 WAV라는 단일 규격으로 변환한 뒤 AI에 넘깁니다. "들어오는 데이터를 일단 표준화하고 일을 시작한다"는 방어적 설계의 모범입니다.
사용자가 6개 중 일부 스템만 고르면(예: 보컬·드럼만), collect.py는 고르지 않은 나머지를 모두 합친 7번째 트랙 "Original"을 만들어 줍니다. 이건 A/B 비교(내가 고른 것 vs 나머지 전부)를 노래를 두 번 트는 것 없이 가능하게 하는 영리한 장치입니다. 또 선택한 스템만 FFmpeg의 amix로 합쳐 mix.wav 한 파일로 내려받게 해 줍니다.
잡의 진행 상태(어디까지 처리됐나)는 서버 메모리에 두고, 실제 결과물(스템 WAV)은 jobs/<job_id>/ 디스크에 저장합니다. 서버를 재시작하면 잡 목록은 초기화되지만 파일은 남고, 오래된 폴더는 백그라운드 청소 루프가 24시간 뒤(설정 가능) 자동으로 쓸어 담습니다(sweep_old_jobs). 메모리는 가볍게, 디스크는 정리되게 — 서버 자원을 오래 깨끗이 유지하는 패턴입니다.
저장소를 처음 열면 폴더가 많아 막막할 수 있지만, 역할별로 묶어 보면 의외로 단순합니다. 핵심만 추려 트리로 보면:
이 구조를 식당에 빗대면, app/은 주방(실제 요리=AI 처리), static/은 손님이 보는 홀과 메뉴판(화면), desktop/은 식당 건물 외관과 간판(설치 가능한 앱 껍데기)입니다. 주방에서 일하는 사람(파이썬)과 손님 응대(자바스크립트), 건물 관리(러스트)가 각자 다른 전문가인 셈이죠. 이렇게 층이 또렷이 갈려 있으면, 한 층만 공부해도 다른 층을 망칠 걱정 없이 손댈 수 있습니다.
흥미로운 디테일 하나: desktop/src-tauri/src/main.rs가 무려 81KB로 저장소에서 가장 큰 소스 파일입니다. 단순한 껍데기가 아니라, 내장 파이썬 서버를 띄우고·포트를 잡고·부모 프로세스가 죽으면 백엔드도 같이 정리하는 등 "앱 생명주기 관리"의 복잡함이 전부 여기 들어 있다는 뜻입니다.
StemDeck이 공부 자료로 훌륭한 이유는, 한 가지 기술만 깊게 파는 게 아니라 실전 제품을 이루는 여러 조각을 작고 읽기 좋은 크기로 보여주기 때문입니다. 기술별로 "무엇을 배울 수 있고, 무엇을 직접 해 보면 좋은지" 정리합니다.
배울 것: Demucs의 htdemucs_6s가 어떻게 한 파형을 6개로 가르는지, "소스 분리(source separation)"라는 문제 자체가 무엇인지. 모델을 직접 학습시킬 필요 없이 python -m demucs ... 한 줄로 불러 쓰는 추론(inference) 사용법.
실습 아이디어: 같은 노래를 htdemucs(4스템)와 htdemucs_6s(6스템)로 각각 돌려, 기타·피아노 분리 품질이 어떻게 다른지 귀로 비교해 보기.
배울 것: 응답을 곧장 못 주는 무거운 작업을, 잡으로 만들어 백그라운드로 넘기고 → SSE로 진행률을 흘려보내고 → 세마포어로 동시성을 막는 전형적 패턴. asyncio.to_thread로 블로킹 작업을 스레드에 떠넘기는 기법도.
실습 아이디어: app/main.py의 /api/health를 흉내 내, 내 FastAPI 앱에 "현재 디바이스가 CUDA인지 CPU인지" 반환하는 엔드포인트를 직접 추가해 보기.
배울 것: 여러 오디오 트랙을 동기화해 재생하고, 트랙별 볼륨·음소거·솔로를 거는 오디오 그래프 구성. VU 미터(음량 막대)를 분석기(analyser) 노드의 RMS로 그리는 법. 파형을 Canvas에 min/max 샘플로 직접 그리는 시각화.
실습 아이디어: 두 개의 오디오 파일을 동시에 재생하면서 한쪽 볼륨만 슬라이더로 조절하는 30줄짜리 Web Audio 데모 페이지를 만들어 보기.
배울 것: librosa의 비트 추적으로 빠르기(BPM)를, 크로마(chroma) 분석 + Albrecht-Shanahan 키 프로파일로 조성(key)을 추정하는 알고리즘. analyze.py는 단순히 라이브러리를 부르는 데 그치지 않고, 팝/록은 자연단음계를 쓴다는 점을 반영해 "장조 대신 단조를 살짝 우대"하는 보정까지 손수 구현해 둔, 보기 드문 교육용 코드입니다.
실습 아이디어: 내가 키를 아는 노래 5곡을 넣어, analyze.py가 맞히는 정확도를 표로 정리해 보기.
배울 것: 웹 서버 + 화면을 .dmg/.exe로 묶는 과정, "첫 실행 시 런타임·모델을 내려받는" 설치 마법사 설계(desktop/ui/setup.js), 부모 앱이 종료되면 내장 서버도 함께 정리하는 워치독 패턴(main.py의 _desktop_parent_watchdog).
실습 아이디어: Tauri 공식 튜토리얼로 "Hello World" 데스크톱 앱을 빌드해, Electron 대비 결과물 용량이 얼마나 작은지 확인해 보기.
배울 것: pyproject.toml의 의존성 핀(pin)마다 달린 긴 주석은 그 자체로 한 편의 교과서입니다 — "torchaudio 2.7이 내장 오디오 라이터를 없애서 Demucs가 깨지므로 2.6에 고정", "인텔 맥은 휠이 없어 torch 2.2로", "보안 취약점(CVE) 때문에 urllib3 하한선 상향" 등. 실무에서 라이브러리 버전을 왜·어떻게 고정하는지 살아 있는 사례.
실습 아이디어: 주석들을 읽고 "이 핀이 없으면 어떤 증상이 나는가"를 한 줄씩 내 말로 풀어 적어 보기.
StemDeck은 클라우드가 아니라 내 컴퓨터에서 AI를 돌리므로, 속도가 전적으로 내 하드웨어에 달려 있습니다. 코드는 켜질 때 가장 빠른 연산 장치를 자동으로 골라잡습니다(config.py의 디바이스 자동 감지).
| 구분 | 요구·권장 |
|---|---|
| 운영체제 | macOS · Windows · Linux (데스크톱 앱은 macOS·Windows 빌드 제공) |
| 연산 장치 | NVIDIA GPU(CUDA) ≫ Apple Silicon(MPS) ≫ CPU 폴백 순으로 빠름 |
| 디스크 | Demucs 모델 ~170MB + 데스크톱 런타임(파이썬 ~500MB 등). Windows NVIDIA 빌드는 ~1.6GB |
| 인터넷 | 유튜브 다운로드 + 첫 모델 내려받기에만 필요. 그 뒤로는 오프라인 가능 |
| 입력 길이 제한 | 기본 1200초(20분) 초과 오디오는 거절 (STEMDECK_MAX_DURATION_SEC로 조정) |
STEMDECK_DEMUCS_DEVICE 환경변수로 강제 지정도 가능합니다.주요 설정값(환경변수)을 알아 두면 셀프호스팅 시 유용합니다: STEMDECK_MAX_PENDING_JOBS(대기 잡 한도, 기본 3) · STEMDECK_JOB_TTL_SECONDS(결과 보관 시간, 기본 24시간) · STEMDECK_JOBS_DIR(결과 저장 위치) 등이 있습니다.
데스크톱 앱 대신 소스에서 직접 띄워 봅니다. git clone → uv sync → uv run uvicorn app.main:app --reload 후 localhost:8000 접속. 짧은 노래 한 곡을 넣어 "다운로드 → 분석 → 분리" 단계가 화면에 어떻게 흘러가는지 관찰합니다. (FFmpeg가 PATH에 있어야 함.)
화면 없이 터미널에서 curl로 POST /api/jobs에 유튜브 URL을 보내 job_id를 받고, GET /api/jobs/{id}로 상태를 폴링해 봅니다. SSE 스트림(/events)도 curl로 받아 보며 "서버가 한 방향으로 진행률을 밀어 보낸다"를 체감합니다.
STEMDECK_DEMUCS_DEVICE=cpu로 강제하고 처리 시간을 재 본 뒤, GPU/MPS와 비교합니다. STEMDECK_MAX_DURATION_SEC를 짧게 줄여 "긴 파일 거절" 동작을, STEMDECK_MAX_PENDING_JOBS=1로 줄여 "대기 한도 초과 시 503"을 직접 재현해 봅니다.
app/pipeline/analyze.py를 읽고, 기존 BPM·키·LUFS 외에 "곡 길이를 분:초로 표기" 같은 새 메타데이터를 계산해 metadata.json에 추가해 봅니다. 파이프라인의 어디에 끼워 넣어야 하는지(runner.py의 _write_metadata) 흐름을 따라가는 게 핵심.
docker compose -f build/docker-compose.yml up --build로 컨테이너를 띄우고, 모델 가중치가 명명 볼륨에 캐시돼 재빌드 때 다시 안 받는지 확인합니다. 그다음 같은 네트워크의 다른 기기(휴대폰 등)에서 접속해, "내 PC를 작은 스템 분리 서버로" 바꿔 봅니다. (GPU 패스스루는 OS별 제약 확인.)
이 레포가 건드리는 기술을 체계적으로 익히고 싶다면, 아래 순서를 권합니다. 각 주차는 StemDeck의 특정 폴더·파일과 연결돼 있어, 배운 걸 곧바로 실물 코드에서 확인할 수 있습니다.
| 주차 | 주제 · 목표 | StemDeck 연결고리 |
|---|---|---|
| 1주차 | 파이썬 비동기·FastAPI 기초 — 라우터, 의존성 주입, 백그라운드 작업 | app/api/, app/main.py |
| 2주차 | 오디오 기본기 — 샘플레이트·비트심도·채널, FFmpeg로 변환·믹싱 | collect.py, _prepare_local_source |
| 3주차 | 딥러닝 추론 — PyTorch로 사전학습 모델 불러 쓰기, Demucs 소스 분리 | separate.py |
| 4주차 | 음악 정보 검색(MIR) — librosa로 BPM·키·크로마, LUFS 음량 측정 | analyze.py, pyloudnorm |
| 5주차 | Web Audio & Canvas — 오디오 그래프, 멀티트랙 동기 재생, 파형 시각화 | static/js/player.js, mixer.js |
| 6주차 | 데스크톱 패키징 — Tauri로 웹 앱을 설치 파일로, CI로 자동 빌드 | desktop/, .woodpecker/ |
이 로드맵은 요리를 거꾸로 배우는 것과 같습니다. 완성된 요리(StemDeck)를 먼저 맛본 뒤, "이 소스는 어떻게 만들었지?"(FFmpeg) → "이 고기는 어떻게 익혔지?"(Demucs) → "간은 어떻게 맞췄지?"(LUFS) 식으로 하나씩 거슬러 올라갑니다. 전체 그림을 먼저 본 다음 부품을 파고드는 방식이라, 길을 잃지 않습니다.
| 용어 | 풀이 (+ 비유) |
|---|---|
| 스템 (Stem) | 악기별로 분리된 개별 오디오 트랙. 미숫가루에서 다시 골라낸 콩가루 한 봉지. |
| 스템 분리 (Source Separation) | 합쳐진 완성곡을 AI로 다시 악기별로 가르는 작업. |
| Demucs / htdemucs_6s | Meta가 공개한 오픈소스 스템 분리 신경망. 6스템 버전이 보컬·드럼·베이스·기타·피아노·기타등등을 나눔. |
| DAW | Digital Audio Workstation. 음악을 녹음·편집·믹싱하는 전문 프로그램. StemDeck의 화면이 이걸 흉내 냄. |
| FastAPI | 파이썬으로 웹 API를 빠르게 만드는 프레임워크. 요청을 받는 "접수 창구". |
| SSE (Server-Sent Events) | 서버가 브라우저로 한 방향 실시간 소식을 흘려보내는 기술. 라디오 생중계. |
| 세마포어 (Semaphore) | 동시 사용 인원을 제한하는 신호등. StemDeck은 무거운 잡을 "한 번에 하나만" 통과시킴. |
| 서브프로세스 (Subprocess) | 메인 프로그램이 띄우는 별도 프로그램. 취소·충돌 시 그것만 따로 죽일 수 있음. |
| 워치독 (Watchdog) | "너무 오래 조용하면 멈춘 것"으로 보고 작업을 정리하는 감시견 스레드. |
| Tauri | 웹 화면을 러스트 껍데기로 감싸 가벼운 데스크톱 앱으로 만드는 도구. Electron보다 가벼움. |
| WebView | 주소창·탭이 없는 "알맹이 브라우저". OS에 이미 깔린 걸 빌려 씀. |
| Web Audio API | 브라우저가 직접 오디오를 처리·분석하는 기술. 볼륨·VU 미터·믹싱을 담당. |
| VU 미터 | 소리 크기를 실시간 막대로 보여주는 계기. 분석기 노드의 RMS로 계산. |
| BPM | Beats Per Minute. 1분당 박자 수 = 곡의 빠르기. librosa가 자동 추정. |
| LUFS | Loudness Units Full Scale. 사람이 느끼는 체감 음량의 방송 표준(BS.1770) 단위. |
| uv | 러스트로 만든 초고속 파이썬 패키지 관리자. pip·가상환경을 대체. |
| yt-dlp | 유튜브 등에서 음원·영상을 받아 오는 커맨드라인 도구. |
| FFmpeg | 오디오·영상 포맷 변환과 믹싱의 만능 도구. amix로 여러 트랙을 한 파일로 합침. |
| CUDA / MPS | 각각 NVIDIA GPU·애플 실리콘으로 AI 연산을 가속하는 기술. 없으면 CPU로 폴백(느림). |
| 로컬 우선 (Local-first) | 클라우드 대신 내 기기에서 데이터·처리를 먼저 한다는 설계 철학. |
| CI (Woodpecker) | 코드가 바뀔 때마다 자동으로 테스트·빌드하는 시스템. Woodpecker는 셀프호스팅 가능한 오픈소스 CI. |