์ค๋งํธํฐ ์์ํตํ๊ฐ ์ผ์ํ๋๋ฉด์ ์์ฑํ AI ๊ธฐ๋ฐ ๋ฅํ์ดํฌ ๊ธฐ์ ์ ์ ์ฉํ ๋ณด์ด์คํผ์ฑ ๋ฒ์ฃ๊ฐ ๊ธ์ฆํ๊ณ ์์ต๋๋ค. ๊ณต๊ฒฉ์๋ ์ง์ธ์ ์ผ๊ตด์ ์ค์๊ฐ์ผ๋ก ํฉ์ฑํ์ฌ ์์ํตํ๋ฅผ ์๋ํ๋ฉฐ, ํผํด์ ์ ์ฅ์์๋ ์์์ ๋ณด๊ณ ๋ ๊ฐ์ง์์ ์ธ์งํ๊ธฐ๊ฐ ์ฌ์ค์ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
| ๋ฌธ์ | OnGuard์ ํด๊ฒฐ ๋ฐฉ๋ฒ |
|---|---|
| ์์ํตํ ์ค ๋ฅํ์ดํฌ๋ฅผ ์ค์๊ฐ์ผ๋ก ๊ฐ์งํ ์ ์์ | ์จ๋๋ฐ์ด์ค AI ๋ชจ๋ธ(ForensicAdapter)๋ก ํตํ ํ๋ฉด์ ์ค์๊ฐ ๋ถ์, ์ด์ ๊ฐ์ง ์ฆ์ ๊ฒฝ๊ณ ์ค๋ฒ๋ ์ด ํ์ |
| ๋ฅํ์ดํฌ ๊ฐ์ง ์ ๋ณดํธ์์๊ฒ ์๋ฆด ์๋จ ์์ | ๊ฐ์ง ์ฆ์ ๋ฑ๋ก๋ ๋ณดํธ์์๊ฒ FCM ํธ์ ์๋ฆผ + GPS ์์น ์๋ ๊ณต์ |
| ํตํ ์๋๋ฐฉ์ ์ค์ ์์น ํ์ธ ๋ถ๊ฐ | ์๋๋ฐฉ IP ๊ธฐ๋ฐ ๊ตญ๊ฐ ์์น๋ฅผ ์ง๋์ ์๊ฐํํ์ฌ ํ์ |
| ํตํ ์ค ๋ํ ๋ด์ฉ ์ค์๊ฐ ๋ถ์ ๋๊ตฌ ์์ | ์จ๋๋ฐ์ด์ค Whisper STT + GPT-4o-mini ์ํ ํค์๋ ์๋ ํ๊น |
| ํผํด ๋ฐ์ ํ ๋์ ์๋จ ๋ถ์ฌ | ๊ธ์ต ๊ฑฐ๋ ์ฐจ๋จ ๊ฐ์ด๋ ์ค๋ฒ๋ ์ด, ์ต๊ทผ ๊ฐ์ง ๊ธฐ๋ก ํ์๋ผ์ธ ์ ๊ณต |
| ๋ชจ๋ | ๋งํฌ |
|---|---|
| Android ์ฑ (Frontend) | frontend/shutter-android/README.md |
| ์จ๋๋ฐ์ด์ค AI ๋ชจ๋ธ | frontend/shutter-android/app/src/main/cpp/AI_README.md |
| ๋ฅํ์ดํฌ ๋ฐ์ ์ ์๋ฎฌ๋ ์ดํฐ (Demo) | frontend/shutter-android/demo/README.md |
| ๋ฐฑ์๋ ์๋ฒ (Backend) | shutter-BE/README.md |
| ํฌํ ๋งค๋ด์ผ | exec/ํฌํ ๋งค๋ด์ผ.md |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ OnGuard Android App โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Vision Pipeline โ โ Audio Pipeline โ โ
โ โ MediaProjection ์บก์ฒ โ โ Agora ์ค๋์ค ์คํธ๋ฆผ (PCM) โ โ
โ โ OpenCV ์ผ๊ตด ๊ฒ์ถ โ โ Whisper BASE STT (์จ๋๋ฐ์ด์ค)โ โ
โ โ ForensicAdapter ONNX โ โ GPT-4o-mini ์ํ ํ๊ทธ ๋ถ๋ฅ โ โ
โ โ (INT8 + NNAPI/QNN) โ โ โ โ
โ โโโโโโโโโโโโโโฌโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโ โ
โ โผ โ
โ ๋ฅํ์ดํฌ ๊ฐ์ง ๊ฒฝ๊ณ ์ค๋ฒ๋ ์ด ํ์ โ
โ ๊ธ์ต ์ฑ ์ฐจ๋จ ๊ฐ์ด๋ + ์ํ ํ๊ทธ ํ์ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ REST API + WebSocket + FCM
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Spring Boot Backend (Java 21) โ
โ โ
โ OAuth2 (Kakao) โ JWT ์ธ์ฆ โ Agora RTC ํ ํฐ โ FCM ํธ์ ์๋ฆผ โ
โ ์ค์๊ฐ GPS WebSocket (STOMP) โ AI ํ
๋ ๋ฉํธ๋ฆฌ ์์ง โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโผโโโโโโโโโโโโ
โผ โผ โผ
MySQL Redis Grafana
(์๊ตฌ ๋ฐ์ดํฐ) (GPSยท์บ์) (๋ชจ๋ํฐ๋ง)
| ๊ธฐ๋ฅ | ์ค๋ช |
|---|---|
| ์ค์๊ฐ ๋ฅํ์ดํฌ ๊ฐ์ง | ForensicAdapter ONNX ๋ชจ๋ธ(INT8 ์์ํ + NNAPI/QNN ๊ฐ์)๋ก ์์ํตํ ํ๋ฉด์ 1fps ๋ถ์, 10ํ๋ ์ ํ๊ท ํ๋ฅ ๋ก ํ์ |
| ์จ๋๋ฐ์ด์ค STT + LLM ์ํ ๋ถ๋ฅ | Agora ์ค๋์ค ์คํธ๋ฆผ์ Whisper BASE๋ก ์ ์ฌ โ GPT-4o-mini๋ก #๊ธ์ต๊ฑฐ๋ #๊ฐ์ธ์ ๋ณด์๊ตฌ #ํน์ ์ฅ์์ ์ธ #์ผ์๋ํ ํ๊ทธ ๋ถ๋ฅ |
| ๊ฒฝ๊ณ ์ค๋ฒ๋ ์ด | ๋ฅํ์ดํฌ ๊ฐ์ง ์ ์๋๋ฐฉ ์์น โ ๋ณดํธ์ ์๋ฆผ โ GPS ๊ณต์ โ ๊ธ์ต ์ฐจ๋จ ๊ฐ์ด๋๋ฅผ 5๋จ๊ณ ์ ๋๋ฉ์ด์ ์ผ๋ก ๋ ธ์ถ |
| Agora ์์ํตํ | ์นด์นด์ค ์น๊ตฌ ๋ชฉ๋ก์์ ์์ ์ ์ ํ, FCM ๊ธฐ๋ฐ ์์ ์ ํ ์๋ฆผ(์ ๊ธํ๋ฉด/๋ฐฑ๊ทธ๋ผ์ด๋ ํฌํจ) |
| ์ค์๊ฐ GPS ์ถ์ | STOMP over WebSocket์ผ๋ก ํผ๋ณดํธ์ ์์น๋ฅผ ๋ณดํธ์ ํ๋ฉด์ ์ค์๊ฐ ๋ธ๋ก๋์บ์คํ |
| ๋ณดํธ์ ๊ด๋ฆฌ | ์นด์นด์ค ์น๊ตฌ ๋ชฉ๋ก์์ ๋ณดํธ์/ํผ๋ณดํธ์ ๊ด๊ณ ๋ฑ๋กยท์ญ์ |
| ์ต๊ทผ ๊ฐ์ง ๊ธฐ๋ก | ๋ฅํ์ดํฌ ๊ฐ์ง ์ด๋ ฅ ํ์๋ผ์ธ (๋ ์ง๋ณ ์ธ์ ์นด๋, ๋/๋ณดํธ์ ํํฐ) |
| ์์ญ | ๊ธฐ์ |
|---|---|
| Android | Kotlin, Jetpack Compose, MVVM + Clean Architecture |
| ์จ๋๋ฐ์ด์ค AI | ONNX Runtime, PyTorch Android, Whisper BASE (WhisperKit), OpenCV, Qualcomm QNN, NNAPI |
| ์์ํตํ | Agora RTC SDK 4.3.0 |
| ์ธ์ฆ | Kakao OAuth2, JWT (์๋ ๊ฐฑ์ ) |
| ํธ์ ์๋ฆผ | Firebase Cloud Messaging (FCM) |
| Backend | Java 21, Spring Boot 3.5.11, Spring Security, Spring WebSocket (STOMP) |
| Database | MySQL 8+ (์๊ตฌ ๋ฐ์ดํฐ), Redis (GPSยท์ธ์ ์บ์) |
| ์ธํ๋ผ | Docker, Docker Compose, Jenkins CI/CD, Nginx, Grafana |
S14P21A404/
โโโ frontend/
โ โโโ shutter-android/ # Android ์ฑ (Kotlin + Jetpack Compose)
โ โโโ app/
โ โ โโโ src/main/
โ โ โ โโโ java/com/s14p21a404/shutter/
โ โ โ โ โโโ data/ # Repository ๊ตฌํ์ฒด, ๋ฅํ์ดํฌ ํ์ง๊ธฐ, ํ ํฐ ๊ด๋ฆฌ
โ โ โ โ โโโ domain/ # UseCase, Repository ์ธํฐํ์ด์ค, ๋ชจ๋ธ
โ โ โ โ โโโ network/ # Retrofit, OkHttp, WebSocket ํด๋ผ์ด์ธํธ
โ โ โ โ โโโ presentation/ # Compose ํ๋ฉด, ViewModel, ์ค๋ฒ๋ ์ด ๊ด๋ฆฌ์
โ โ โ โ โโโ push/ # FCM ์๋น์ค, ํตํ ์ด๋ฒคํธ ๋ฒ์ค
โ โ โ โ โโโ di/ # ServiceLocator (์๋ DI)
โ โ โ โโโ cpp/ # NDK C++ ์ถ๋ก ์ฝ๋ (AI_README.md ์ฐธ๊ณ )
โ โ โ โโโ jniLibs/ # ํ๋ฆฌ์ปดํ์ผ ๋ค์ดํฐ๋ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ (arm64-v8a)
โ โ โ โโโ assets/ # AI ๋ชจ๋ธ ํ์ผ (face_deepfake_v6.onnx)
โ โ โโโ build.gradle.kts
โ โโโ demo/ # ๋ฅํ์ดํฌ ๋ฐ์ ์ ์๋ฎฌ๋ ์ดํฐ (โ 5. App Test ์ฐธ๊ณ )
โโโ shutter-BE/ # Spring Boot ๋ฐฑ์๋
โ โโโ src/main/java/com/shutter/api/
โ โ โโโ global/ # JWT, Security, Redis ์ค์
โ โ โโโ user/ # ๋ก๊ทธ์ธ, ๋ณดํธ์-ํผ๋ณดํธ์ ๊ด๊ณ
โ โ โโโ rtc/ # Agora ํ ํฐ ๋ฐ๊ธ, ํตํ ์ธ์
์ ์ด
โ โ โโโ gps/ # WebSocket ์ค์๊ฐ ์์น ๋ธ๋ก๋์บ์คํ
โ โ โโโ notification/ # FCM ํธ์ ์๋ฆผ ์ ์ก
โ โโโ docker-compose.yml
โ โโโ Jenkinsfile
โ โโโ README.md
โโโ convention/ # GitยทJira ํ์
๊ท์น
โโโ docs/
โโโ images/ # README ์ด๋ฏธ์ง ๋ฆฌ์์ค
| ํญ๋ชฉ | ๋ฒ์ |
|---|---|
| Android Studio | Ladybug ์ด์ |
| Kotlin | 2.0+ |
| minSdk / targetSdk | 33 / 36 |
| NDK | 21.4.7075529 |
| JDK | 17 |
frontend/shutter-android/local.properties์ ์๋ ํค๋ฅผ ์ค์ ํฉ๋๋ค.
kakao.native.app.key=YOUR_KAKAO_NATIVE_APP_KEY
server.base.url=https://your-server.com/
agora.app.id=YOUR_AGORA_APP_ID
GMS_API_TOKEN=YOUR_GMS_API_TOKENapp/google-services.json์ Firebase ์ฝ์์์ ๋ค์ด๋ก๋ํ์ฌ app/ ๋๋ ํฐ๋ฆฌ์ ๋ฐฐ์นํฉ๋๋ค.
๋ฅํ์ดํฌ ๊ฐ์ง ๋ชจ๋ธ(face_deepfake_v6.onnx)์ Google Drive์์ ๋ค์ด๋ก๋ํ์ฌ app/src/main/assets/์ ๋ฐฐ์นํฉ๋๋ค.
์์ธํ ๋ด์ฉ์ Frontend README๋ฅผ ์ฐธ๊ณ ํ์ธ์.
| ํญ๋ชฉ | ๋ฒ์ |
|---|---|
| Java | 21 LTS |
| Spring Boot | 3.5.11 |
| MySQL | 8+ |
| Redis | ์ต์ ์์ ๋ฒ์ |
shutter-BE/.env ํ์ผ์ ์์ฑํ์ฌ ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํฉ๋๋ค.
DB_HOST=localhost
DB_PORT=3307
DB_NAME=shutter
DB_USERNAME=your_db_username
DB_PASSWORD=your_db_password
REDIS_HOST=localhost
REDIS_PORT=6379
KAKAO_REST_API_KEY=your_kakao_rest_api_key
JWT_SECRET=your_jwt_secret_key_at_least_32_chars์์ธํ ๋ด์ฉ์ Backend README๋ฅผ ์ฐธ๊ณ ํ์ธ์.
cd frontend/shutter-android
# CLI ๋น๋
./gradlew assembleDebug
# ๋๋ Android Studio์์ ํ๋ก์ ํธ ์ด๊ณ Runcd shutter-BE
# ๋ก์ปฌ ์ธํ๋ผ(MySQL, Redis) ์ปจํ
์ด๋ ๊ตฌ๋
docker-compose -f docker-compose.local.yml up -d
# Spring Boot ์คํ
./gradlew bootRunAPI ๋ช
์ธ: http://localhost:8080/swagger-ui.html
OnGuard์ ๋ฅํ์ดํฌ ๊ฐ์ง ๊ธฐ๋ฅ์ ์ค์ ๋ก ๊ฒ์ฆํ๋ ค๋ฉด ๋ฅํ์ดํฌ ์์์ ์ก์ถํ๋ ๊ณต๊ฒฉ์ ํ๊ฒฝ์ด ํ์ํฉ๋๋ค. demo/ ํด๋์๋ ์น์บ ์์์ ์ค์๊ฐ ํ์ด์ค์ค์์ ์ ์ฉํ์ฌ Agora ์ฑ๋๋ก ์ก์ถํ๋ ์๋ฎฌ๋ ์ดํฐ๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ์ด๋ฅผ ํตํด OnGuard ์ฑ์ด ์ค์ ๋ฅํ์ดํฌ ํตํ๋ฅผ ์์ ํ์ ๋ ๊ฐ์ง ๋ฐ ๊ฒฝ๊ณ ์ค๋ฒ๋ ์ด๊ฐ ์ ์ ๋์ํ๋์ง end-to-end๋ก ์์ฐํ ์ ์์ต๋๋ค.
์์ธํ ๋ด์ฉ์ Demo README๋ฅผ ์ฐธ๊ณ ํ์ธ์.
| ํญ๋ชฉ | ๊ถ์ฅ ์ฌ์ |
|---|---|
| Python | 3.10 ~ 3.12 |
| GPU | NVIDIA (CUDA 12.x, cuDNN 9.x) ๊ถ์ฅ |
cd frontend/shutter-android/demo
python -m venv venv
# Windows
venv\Scripts\activate
# macOS / Linux
source venv/bin/activate
pip install fastapi "uvicorn[standard]" opencv-python insightface pillow "numpy<2"
# GPU ์ฌ์ฉ ์
pip install onnxruntime-gpuinswapper_128.onnx ๋ชจ๋ธ์ HuggingFace์์ ๋ค์ด๋ก๋ํ์ฌ demo/ ๋๋ ํฐ๋ฆฌ์ ๋ฐฐ์นํฉ๋๋ค.
deepfake-caller.html ์๋จ์ ์์๋ฅผ ํ๊ฒฝ์ ๋ง๊ฒ ์์ ํฉ๋๋ค.
const APP_ID = 'YOUR_AGORA_APP_ID';
const WS_URL = 'ws://localhost:8765';# 1. ํ์ด์ค์ค์ ์๋ฒ ์คํ
# Windows (GPU ์ฌ์ฉ ์ cuDNN ๊ฒฝ๋ก ์ถ๊ฐ)
set PATH=venv\Lib\site-packages\nvidia\cudnn\bin;%PATH%
python server.py
# 2. ๋ธ๋ผ์ฐ์ ํด๋ผ์ด์ธํธ ์๋น
python -m http.server 8080
# โ http://localhost:8080/deepfake-caller.html์์ฐ ์์
- ๋ธ๋ผ์ฐ์ ์์ ์นด์นด์ค ๋ก๊ทธ์ธ
- ์์ค ์ผ๊ตด ์ด๋ฏธ์ง ์ ๋ก๋ โ ํ์ด์ค์ค์ ON
- ํผํด์(OnGuard ์ฑ ์ค์น ๊ธฐ๊ธฐ) ์นด์นด์ค ID ์ ๋ ฅ โ ํตํ ์์
- OnGuard ์ฑ์์ ํตํ ์๋ฝ โ ๋ฅํ์ดํฌ ๊ฐ์ง ๊ฒฝ๊ณ ์ค๋ฒ๋ ์ด ํ์ธ
| ์ด๋ฆ | ์ญํ | ๋ด๋น |
|---|---|---|
| ์ค์ํ | Backend / Infra | ์นด์นด์ค OAuth2ยทJWT ์ธ์ฆ ์ฒด๊ณ, ๋ณดํธ์-ํผ๋ณดํธ์ DB ์ค๊ณ, Agora RTC ์ธ์ ์ ์ด, WebSocket GPS ๋ธ๋ก๋์บ์คํ , FCM ์๋ฆผ, Redis ๋ถ์ฐ ๋ฝ, DockerยทJenkins CI/CD |
| ๋ฐ์๋ฏผ | Frontend / Backend | ์ ์ฒด ํ๋ฉด ๊ตฌํ, GPS ์์น ์ถ์ , ์นด์นด์คํก ์ฐ๋, ๋ณดํธ์ ๋ฑ๋กยท๊ด๋ฆฌ, ์ต๊ทผ ๊ธฐ๋ก ํ์๋ผ์ธ, ์๋ฒ ์ฐ๋, Demo ๋ฐ์ ์ ์๋ฎฌ๋ ์ดํฐ, Grafana ํ ๋ ๋ฉํธ๋ฆฌ ํ์ดํ๋ผ์ธ |
| ์ด์ธ์ | Frontend | UI/UX ๋์์ธ, ๋ฅํ์ดํฌ ๊ฐ์ง ๊ฒฝ๊ณ ์ค๋ฒ๋ ์ด, ์์ํตํ ํ์ง ์ฐ๋, ๊ธ์ต ์ฑ ์ฐจ๋จ ์ค๋ฒ๋ ์ด |
| ์ ๋ค์ง | Frontend / AI | Agora ์์ํตํ(์์ฒญยท์๋ฝยท๊ฑฐ์ ), NDK, ์จ๋๋ฐ์ด์ค ๋ฅํ์ดํฌ ํ์ง, ์์ ์ ์ฒ๋ฆฌ, ํ์ง ๊ฒฐ๊ณผ ์ง๊ณ |
| ์ฑ์ฃผํฌ | Frontend / AI | ๋ฅํ์ดํฌ ๊ฒฝ๊ณ ์ฐฝยทํ์ง ์์ญ ํ์, NDK, ์จ๋๋ฐ์ด์ค STT/LLM ๋ํ ๋ถ์, OpenCV ์ผ๊ตด ํ์ง, HTPโGPUโCPU ํด๋ฐฑ, QNN/NNAPI ์ต์ ํ, INT8 ์์ํ, ํ์ง ๊ฒฐ๊ณผ ์๋ฒ ์ ์ก |
| ์ฅ์ ์ง | AI | NDK, ์จ๋๋ฐ์ด์ค ๋ฅํ์ดํฌ ํ์ง, ๋ชจ๋ธ ์ฑ๋ฅ ํฅ์, CAM ๊ธฐ๋ฐ ROI ์ถ์ถ, PyTorchโONNX ๋ณํ |

