MeFit 면접 영상·음성 후처리 AWS Lambda 함수 모음.
인터뷰 세션 중 녹화된 영상을 변환, 분리, 추출하여 분석에 활용할 수 있는 형태로 가공한다.
pj-kmucd1-04-mefit-video-files (원본 .webm 업로드)
│
└─ S3 이벤트 → SNS (video-uploaded) ─┬→ video-converter → scaled-video-files (.mp4)
├→ frame-extractor → video-frame-files (.jpg)
│ └─ SQS (face-trigger) → face-analyzer worker
└→ audio-extractor → audio-files (.wav 원본) + scaled-audio-files (.wav 16kHz)
각 Lambda 완료 시 → SQS (step-complete) → Django Celery Worker
S3 이벤트 알림은 동일 버킷·이벤트 유형·접미사에 대해 여러 대상을 지정할 수 없으므로 SNS fan-out 패턴으로 3개 Lambda를 동시에 호출한다.
frame_extractor는 프레임 추출 완료 후 step-complete SQS 발행과 함께
face-trigger SQS에도 메시지를 발행한다. 메시지에는 frameBucket, framePrefix,
sessionUuid, turnId, sourceKey가 포함되며, face-analyzer 워커가 이를 수신해
얼굴 표정 분석을 시작한다.
analysis-video/
├── layers/
│ └── common/python/mefit_video_common/ # Lambda Layer (공통 패키지)
│ ├── config.py # 환경변수 (S3 버킷명, SNS ARN 등)
│ ├── s3_client.py # boto3 S3 헬퍼 (download/upload)
│ ├── ffmpeg_runner.py # ffmpeg subprocess 래퍼
│ ├── logger.py # 구조화 JSON 로거
│ └── event_parser.py # SNS→S3 이벤트 파서
│
├── functions/ # Lambda 핸들러
│ ├── video_converter/ # WebM → MP4 (H.264, max 720p)
│ ├── frame_extractor/ # 1FPS JPEG 프레임 추출
│ ├── audio_extractor/ # 영상 → WAV (16kHz mono) 추출+다운샘플링
│ └── voice_analyzer/ # 음성 분석 (pydub, 온디맨드)
│
├── local/ # 로컬 개발 환경
│ ├── docker-compose.yml # LocalStack (S3, Lambda, SNS, SQS)
│ ├── localstack_init.sh # 버킷·토픽·큐 초기화 스크립트
│ └── invoke_local.py # Lambda 핸들러 로컬 실행 스크립트
│
├── pyproject.toml
├── .gitignore
└── README.md
| 함수 | 트리거 | 입력 | 출력 | 타임아웃 | 메모리 |
|---|---|---|---|---|---|
video-converter |
SNS: video-uploaded | 원본 WebM | MP4 (720p H.264) | 5분 | 1024MB |
frame-extractor |
SNS: video-uploaded | 원본 WebM | JPEG 프레임 (1FPS) | 3분 | 512MB |
audio-extractor |
SNS: video-uploaded | 원본 WebM | WAV 원본 (audio-files) + WAV 16kHz mono (scaled-audio) | 2분 | 512MB |
voice-analyzer |
온디맨드 (boto3.invoke) | WAV (scaled-audio) | JSON (summary + timeline) | 2분 | 1024MB |
| 버킷 | 용도 |
|---|---|
pj-kmucd1-04-mefit-video-files |
원본 영상 (.webm) |
pj-kmucd1-04-mefit-scaled-video-files |
다운스케일 영상 (.mp4) |
pj-kmucd1-04-mefit-video-frame-files |
1FPS 프레임 이미지 (.jpg) |
pj-kmucd1-04-mefit-audio-files |
분리된 음성 (.wav) |
pj-kmucd1-04-mefit-scaled-audio-files |
다운스케일 음성 (.wav) |
- Docker, Docker Compose
- Python 3.14+
- ffmpeg (로컬 테스트용)
cd local
docker compose up -d5개 S3 버킷 + SNS 토픽 + SQS 큐 5개 + Lambda 4개(3 pipeline + 1 voice-analyzer)가 자동 생성됩니다.
| SQS 큐 | 용도 |
|---|---|
mefit-video-step-complete |
Lambda 완료 → Django Celery Worker |
mefit-face-trigger |
frame_extractor → face-analyzer 워커 |
mefit-video-converter-queue |
SNS fan-out → video-converter Lambda |
mefit-frame-extractor-queue |
SNS fan-out → frame-extractor Lambda |
mefit-audio-extractor-queue |
SNS fan-out → audio-extractor Lambda |
LocalStack Community 에디션에서는 Lambda Layer와 Lambda 컨테이너 볼륨 마운트가 제한적입니다. 따라서 ffmpeg를 사용하는 Lambda 함수(video_converter, frame_extractor, audio_extractor, audio_scaler)는 로컬에서 정상 실행되지 않습니다.
| 환경 | Lambda 후처리 | 영상 재생 |
|---|---|---|
| 로컬 (LocalStack) | S3 이벤트 트리거됨, ffmpeg 미동작 | 원본 .webm 직접 재생 |
| 프로덕션 (AWS) | Lambda Layer로 ffmpeg 제공, 정상 동작 | 다운스케일 .mp4 재생 (원본 .webm fallback) |
로컬에서 녹화 → S3 업로드 → 리포트 페이지 재생까지의 흐름은 정상 동작합니다. Lambda 후처리 파이프라인은 AWS 배포 후 검증합니다.
cd local
./s3_browser.sh# 공통 Layer를 PYTHONPATH에 추가하여 실행
python local/invoke_local.py video_converter pj-kmucd1-04-mefit-video-files test/sample.webm
python local/invoke_local.py frame_extractor pj-kmucd1-04-mefit-video-files test/sample.webm
python local/invoke_local.py audio_extractor pj-kmucd1-04-mefit-video-files test/sample.webm
python local/invoke_local.py audio_scaler pj-kmucd1-04-mefit-audio-files test/sample.wav
공통 유틸리티 패키지. 모든 Lambda 함수에서 공유.
config.py— 환경변수에서 버킷명, SNS ARN, ffmpeg 경로 로드s3_client.py—download_to_tmp(),upload_from_tmp(),get_s3_client()ffmpeg_runner.py—run_ffmpeg(args, description)— subprocess 래퍼, 타임아웃 280초logger.py—get_logger(name)— 구조화 JSON 로깅event_parser.py—parse_s3_records(event)— SNS 래핑/직접 S3 이벤트 자동 판별 파서
정적 빌드 ffmpeg 바이너리. /opt/bin/ffmpeg 경로로 마운트.
AWS 콘솔 또는 EC2 CLI를 통해 배포. 상세 절차:
TODO_INFRA/PHASE4_LAMBDA.md
| 변수 | 설명 | 기본값 |
|---|---|---|
VIDEO_BUCKET |
원본 영상 버킷 | pj-kmucd1-04-mefit-video-files |
SCALED_VIDEO_BUCKET |
스케일 영상 버킷 | pj-kmucd1-04-mefit-scaled-video-files |
FRAME_BUCKET |
프레임 버킷 | pj-kmucd1-04-mefit-video-frame-files |
AUDIO_BUCKET |
음성 버킷 | pj-kmucd1-04-mefit-audio-files |
SCALED_AUDIO_BUCKET |
스케일 음성 버킷 | pj-kmucd1-04-mefit-scaled-audio-files |
STEP_COMPLETE_SQS_URL |
step-complete SQS URL | — |
FACE_TRIGGER_SQS_URL |
face-trigger SQS URL (frame_extractor에서 발행) |
— |
REGION |
AWS 리전 | us-east-1 |
FFMPEG_PATH |
ffmpeg 바이너리 경로 | /opt/bin/ffmpeg |
- Runtime: Python 3.14 (AWS Lambda)
- 영상 처리: ffmpeg (static build, Lambda Layer)
- 스토리지: AWS S3
- 메시징: AWS SNS → SQS → Django backend
- 로컬 개발: LocalStack (Docker)