← 목록
기타 2026-07-12 4KB 읽기 5분

crowny-class CVF 자동인코딩 라이브 E2E 검증 (2026-07-12)

개요

class.crowny.org:9864의 영상 업로드 → CVF 자동인코딩 파이프라인(2026-07-12 배선)을 실업로드로 전수 실증. 도중 launchd PATH 함정을 실측·수정·재검증까지 완료.

무엇을 했는지

  1. node --check 전체 통과(server.js, modules//routes.js, lib/.js) 확인 후
launchctl kickstart -k gui/$(id -u)/com.crowny.class → 모듈 5개 로드 로그 확인.
  1. 실업로드: 작은 소스(o4-1.mp4, 13.6MB)로 /api/video/upload admin POST.
- 응답시간 ~52-60ms — 완전 비동기(블로킹 아님) 확인. cvfStatus:"encoding" 즉시 반환.
  1. 1차 시도 실패 발견: encode-status가 cvfStatus:"error", cvfError:"프레임추출실패"로 귀결.
- 원인 조사: encode-upload.sh를 수동 실행하면 ffmpeg 정상 동작(2016프레임 추출 성공). - env -i PATH=/usr/bin:/bin:/usr/sbin:/sbin bash -c 'which ffmpeg' → exit 1로 재현. - 근본원인: com.crowny.class.plistEnvironmentVariables에 PATH 키가 없어 launchd 기본 PATH(/usr/bin:/bin:/usr/sbin:/sbin)만 적용됨. node의 spawn('bash', [ENCODE_SCRIPT,...])가 이 PATH를 그대로 상속 → 서브셸의 ffmpeg bare 호출이 미발견.
  1. 수정(이중 방어):
- ~/Library/LaunchAgents/com.crowny.class.plist: EnvironmentVariables에 PATH=/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin 추가. - /Users/ef/crowny-class/scripts/encode-upload.sh: 스크립트 상단에서 export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:$PATH" + command -v ffmpeg 사전가드(없으면 즉시 ENCODE_ERROR ffmpeg없음 반환, 무한 대기/조용한 실패 방지). - launchctl unload && launchctl load로 plist 재적용(kickstart -k만으론 plist 변경 미반영 확인), ps eww -p <pid> | grep PATH=로 실제 프로세스 환경변수에 반영됨을 실측 확인.
  1. 2차 시도 — 전 구간 성공: 업로드→인코딩→ready까지 약 30초(13.6MB 소스).
- 인코딩 중 /api/video/cvf/<id>: admin bearer 409("인코딩 중"), 무로그인 401. - 완료 후: 무로그인 401, admin+Range 206(cvf, cvfaudio 둘 다), admin no-Range 200.
  1. 산출물 검증(전부 통과):
- 데이터/영상/cvf/class_<id>.cvf 존재, 매직바이트 CVF! 확인. - class_<id>.cvf.mp3 존재, ID3v2.4 MPEG ADTS layer III 64kbps 44.1kHz 확인. - 데이터/영상/cvf-archive/class_<id>.cvf.ccp 존재. - 페이월 안전성: /Users/ef/crowny-video/output에 해당 id 파일 없음(class-private 격리 확인).
  1. 캔버스 재생(puppeteer) 테스트: puppeteer 미설치로 스킵 — Range 206 확인으로 갈음(지시사항 반영).
  2. 정리: 테스트 업로드 산출물(데이터/영상/<id>.json, 파일/<id>.mp4, cvf/class_<id>., cvf-archive/class_<id>.)
전부 삭제, find로 잔존 없음 확인. video/list 기존 23클립 그대로(count=23).
  1. 회귀 확인: enroll/status 200, lesson/curriculum 200, showcase.html 200, community/portfolios 200 — 전부 정상.

관련 파일

  • /Users/ef/crowny-class/modules/video/routes.js — 업로드/인코딩잡/게이트 라우트
  • /Users/ef/crowny-class/scripts/encode-upload.sh — 인코딩 파이프라인(오늘 PATH 이중방어 추가)
  • /Users/ef/Library/LaunchAgents/com.crowny.class.plist — 오늘 PATH 키 추가
  • /Users/ef/crowny-class/API-CONTRACT.md — 계약 SSOT

잔여 이슈

  • launchd 기반 다른 서비스(.plist)들도 동일 PATH 누락 함정 가능성 있음 — 이번 세션은 crowny-class만
수정. 다른 서비스에서 spawn/체계()로 brew 바이너리(ffmpeg, ccp 외 도구) 호출 시 동일 증상 재발 가능. (이 함정을 한선씨-가드레일.md/MEMORY에 별도 feedback로 남기는 건 다음 세션 권장.)
  • puppeteer 캔버스 재생 실측은 미실시(환경 미설치) — 필요시 npm install puppeteer 후 재검증.
  • 대용량 소스(예: o3-1.mp4 270MB)는 이번엔 테스트 안 함 — 인코딩 시간/메모리(NODE_OPTIONS 8GB 힙) 스케일 별도 확인 권장.