Repository navigation
Expand file tree
/
Copy pathserver.py
More file actions
108 lines (85 loc) · 3.44 KB
/
Copy pathserver.py
File metadata and controls
108 lines (85 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import uvicorn
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import base64
import numpy as np
import io
import soundfile as sf
from inference_engine import DeepfakeDetector
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Initialize App
app = FastAPI(title="Deepfake Detection API")
# Global variables
detector = None
class AudioRequest(BaseModel):
audio_base64: str
timestamp: float
class AnalysisResponse(BaseModel):
timestamp: float
fakeProbability: int
confidence: str
reasoning: str
@app.on_event("startup")
def load_model():
global detector
logger.info("Loading Deepfake Detection Model...")
try:
detector = DeepfakeDetector()
logger.info("Model loaded successfully.")
except Exception as e:
logger.error(f"Failed to load model: {e}")
@app.post("/api/analyze", response_model=AnalysisResponse)
async def analyze_audio(request: AudioRequest):
global detector
if not detector:
raise HTTPException(status_code=503, detail="Model not initialized")
try:
# Decode Base64
# Remove header if present (e.g., "data:audio/wav;base64,")
b64_string = request.audio_base64
if "base64," in b64_string:
b64_string = b64_string.split("base64,")[1]
audio_bytes = base64.b64decode(b64_string)
# Load audio using soundfile (librosa load from bytes is tricky, sf is easier with io.BytesIO)
# We need numpy array for the detector
data, samplerate = sf.read(io.BytesIO(audio_bytes))
# Ensure correct shape/channels. If stereo, mix to mono?
# Detector expects [samples]
if len(data.shape) > 1:
data = np.mean(data, axis=1) # Convert to mono
# Resample if needed? Detector assumes a certain rate (16k in inference_engine).
# For simplicity, assuming existing `predict` handles standard input or raw bytes,
# but let's check `inference_engine.py`.
# `inference_engine.py` uses `AutoFeatureExtractor` which handles resampling if we pass raw array with sampling_rate argument,
# BUT `predict` takes `audio_chunk`.
# Let's assume input matches or is close enough, or `inference_engine` handles it.
# Ideally we verify sample rate. `sf.read` gives us `samplerate`.
# Run Inference
prob = detector.predict(data) # returns float 0.0-1.0
fake_prob_percent = int(prob * 100)
# Reasoning Logic (Mocked based on Score)
reasoning = "Normal speech patterns detected."
confidence = "High"
if fake_prob_percent > 80:
reasoning = "High-frequency artifacts and unnatural prosody detected."
confidence = "High"
elif fake_prob_percent > 50:
reasoning = "Some inconsistent background noise observed."
confidence = "Medium"
elif fake_prob_percent < 20:
reasoning = "Clear natural breathing and organic pauses."
confidence = "High"
return AnalysisResponse(
timestamp=request.timestamp,
fakeProbability=fake_prob_percent,
confidence=confidence,
reasoning=reasoning,
)
except Exception as e:
logger.error(f"Error processing request: {e}")
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)