📋 목차
1. 개발 환경 준비
1.1 필수 소프트웨어
- Java JDK 17: Oracle 또는 OpenJDK
- Android Studio: Narwhal 2025.1.1 Patch 1
- Android SDK: API 36
1.2 Android Studio 설정
SDK Manager에서 설치 필요:
- Android 14.0 (API 34)
- Android 13.0 (API 33)
- Android 7.0 (API 24)
- Build Tools 34.0.0
1.3 가상 기기 생성
- Pixel 7, API 34 권장
- RAM 4GB 이상 할당
2. 프로젝트 설정
2.1 Gradle 설정
app/build.gradle.kts 주요 의존성:
Gradle
dependencies {
// 기본 안드로이드
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.appcompat:appcompat:1.6.1")
// 코틀린
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
// ML Kit 얼굴 인식
implementation("com.google.mlkit:face-detection:16.1.5")
// OpenCV (선택사항)
implementation("org.opencv:opencv-android:4.8.0")
}2.2 권한 설정
AndroidManifest.xml:
XML
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />3. 핵심 구조 이해
3.1 아키텍처 개요
MainActivity (UI 컨트롤러)
├── UIManager (화면 관리)
├── PermissionManager (권한 관리)
├── VideoProcessor (동영상 처리)
├── BlurProcessor (블러 처리)
├── FaceDetector (얼굴 감지)
└── BlurAnalyzer (블러 분석)
3.2 주요 클래스별 역할
MainActivity
onCreate(): 앱 초기화, 매니저들 생성previewVideo(): 선택한 동영상 미리보기startProcess(): 동영상 처리 시작onRequestPermissionsResult(): 권한 결과 처리
UIManager
initializeViews(): UI 요소들 연결applyTheme(): 테마 적용log(): 로그 메시지 표시updateProgress(): 진행률 업데이트
PermissionManager
checkAndRequestPermissions(): 필요한 권한 확인 및 요청handlePermissionResult(): 권한 승인/거부 결과 처리
VideoProcessor
processVideo(): 메인 동영상 처리 로직createOutputFormat(): 출력 비디오 포맷 설정processFrames(): 프레임별 처리copyAudioTrack(): 오디오 트랙 복사
BlurProcessor
blurFaces(): 얼굴 영역 블러 처리blurWithAdaptiveRenderScript(): GPU 가속 블러blurWithOpenCV(): OpenCV 블러 (폴백)expandFaceRect(): 얼굴 영역 확장
FaceDetector
detectFaces(): ML Kit으로 얼굴 감지hasSignificantChange(): 얼굴 위치 변화 감지
BlurAnalyzer
calculateAdaptiveBlurRadius(): 해상도별 블러 강도 계산verifyAdaptiveBlurConsistency(): 블러 일관성 검증
3.3 핵심 처리 흐름
flowchart TD
classDef brightBG fill:#ffffff,stroke:#cccccc,color:#222222;
classDef decision fill:#fff3e0,stroke:#ffb74d,color:#222222,font-weight:bold;
classDef process fill:#e1f5fe,stroke:#4fc3f7,color:#222222;
classDef action fill:#e8f5e9,stroke:#81c784,color:#222222;
classDef output fill:#f3e5f5,stroke:#ba68c8,color:#222222;
linkStyle default stroke:#999999, stroke-width:1.5px;
A[사용자가 동영상 선택]:::process --> B[MediaMetadataRetriever]:::process
B --> C{권한 확인}:::decision
C -->|권한 없음| D[PermissionManager<br/>권한 요청]:::action
D --> C
C -->|권한 있음| E[VideoProcessor.processVideo<br/>시작]:::process
E --> F[MediaExtractor<br/>비디오 트랙 추출]:::process
F --> G[MediaCodec Decoder<br/>초기화]:::process
G --> H[MediaCodec Encoder<br/>초기화]:::process
H --> I[MediaMuxer<br/>초기화]:::process
I --> J[프레임 디코딩 루프 시작]:::process
J --> K[MediaCodec.dequeueOutputBuffer]:::process
K --> L{프레임 있음?}:::decision
L -->|없음| K
L -->|있음| M[YUV → RGB 변환]:::process
M --> N[FaceDetector.detectFaces<br/>ML Kit 얼굴 감지]:::process
N --> O{얼굴 발견?}:::decision
O -->|없음| P[원본 프레임 유지]:::process
O -->|있음| Q[BlurProcessor.blurFaces]:::process
Q --> R{RenderScript 사용 가능?}:::decision
R -->|가능| S[GPU 가속 블러 처리]:::process
R -->|불가능| T[OpenCV 블러 처리]:::process
S --> U[블러 처리된 프레임]:::process
T --> U
P --> U
U --> V[Surface에 렌더링]:::process
V --> W[MediaCodec Encoder<br/>프레임 인코딩]:::process
W --> X[MediaMuxer<br/>비디오 샘플 쓰기]:::process
X --> Y{마지막 프레임?}:::decision
Y -->|아니오| K
Y -->|예| Z[오디오 트랙 복사]:::process
Z --> AA[MediaExtractor<br/>오디오 샘플 읽기]:::process
AA --> BB[MediaMuxer<br/>오디오 샘플 쓰기]:::process
BB --> CC{오디오 끝?}:::decision
CC -->|아니오| AA
CC -->|예| DD[MediaMuxer.stop]:::process
DD --> EE[파일 저장 완료]:::output
EE --> FF[갤러리 등록<br/>MediaScannerConnection]:::output
FF --> GG[처리 완료 알림]:::output
class A,B,E,F,G,H,I,J,K,M,N,P,Q,S,T,U,V,W,X,Z,AA,BB,DD brightBG,process;
class C,L,O,R,Y,CC brightBG,decision;
class D brightBG,action;
class EE,FF,GG brightBG,output;
1. 동영상 선택 → MediaMetadataRetriever로 정보 추출
2. 권한 확인 → PermissionManager로 처리
3. 동영상 처리 시작 → VideoProcessor.processVideo()
4. 프레임 디코딩 → MediaCodec 사용
5. 얼굴 감지 → FaceDetector + ML Kit
6. 블러 처리 → BlurProcessor (RenderScript/OpenCV)
7. 프레임 인코딩 → MediaCodec 사용
8. 오디오 복사 → MediaExtractor/MediaMuxer
9. 최종 파일 저장 → 갤러리 등록
4. 빌드 및 테스트
4.1 빌드 과정
Bash
# Gradle 동기화
./gradlew sync
# Clean 빌드
./gradlew clean
# Debug APK 빌드
./gradlew assembleDebug
# Release APK 빌드
./gradlew assembleRelease4.2 테스트 방법
가상 기기 테스트
- AVD Manager에서 가상 기기 실행
- Run 버튼으로 앱 설치 및 실행
- 샘플 동영상으로 기능 테스트
실제 기기 테스트
- 개발자 옵션 → USB 디버깅 활성화
- USB 연결 후 기기 선택
- 실제 동영상으로 성능 테스트
4.3 주요 테스트 항목
- 동영상 선택 및 미리보기
- 권한 요청 및 처리
- 얼굴 감지 정확도
- 블러 처리 품질
- 진행률 표시
- 메모리 사용량
- 배터리 소모량
4.4 문제 해결
빌드 오류
- Gradle 캐시 삭제:
./gradlew clean - SDK 버전 확인: Tools → SDK Manager
- 의존성 충돌:
./gradlew dependencies확인
런타임 오류
- 권한 확인: 설정 → 앱 → 권한
- 메모리 부족: 힙 크기 증가 또는 이미지 크기 축소
- GPU 가속 실패: OpenCV 폴백 동작 확인
성능 최적화
- 프로파일러로 메모리/CPU 사용량 모니터링
- 불필요한 비트맵 생성 최소화
- 백그라운드 스레드에서 무거운 작업 처리
🚀 개발 팁
코드 품질
- KDoc 주석으로 모든 public 메서드 문서화
- 단일 책임 원칙으로 클래스 분리
- 의존성 주입으로 테스트 용이성 확보
성능 최적화
- RenderScript로 GPU 가속 활용
- 적응형 블러로 해상도별 최적화
- 메모리 풀링으로 GC 압박 감소
사용자 경험
- 진행률 표시로 사용자 피드백 제공
- 에러 상황에 대한 명확한 안내
- 다크/라이트 테마 지원
이 가이드를 통해 MoBlur 앱의 핵심 구조를 이해하고 효율적으로 개발할 수 있습니다.
