File size: 4,625 Bytes
37c6d1c
7ba6d3f
37c6d1c
 
 
 
aee4240
37c6d1c
 
 
 
 
 
5b42b75
37c6d1c
 
 
d9d5e33
 
37c6d1c
 
 
1058020
 
 
 
 
 
 
 
 
 
 
 
 
37c6d1c
 
1058020
37c6d1c
 
 
 
 
2fdce4b
 
1058020
 
 
 
 
 
 
 
 
 
 
 
 
 
2fdce4b
1058020
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37c6d1c
1058020
 
 
37c6d1c
 
1058020
37c6d1c
 
 
 
d9d5e33
37c6d1c
 
 
 
 
d9d5e33
 
37c6d1c
 
 
 
 
 
 
 
 
 
 
 
 
 
f6d50b1
 
37c6d1c
 
f6d50b1
 
 
 
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from fastapi import FastAPI, UploadFile, File, Depends, HTTPException, Header, Form
import os
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
from auth import verify_api_key
from audio_processor import process_audio
from real_detector import analyze_audio_real as analyze_audio
from murf_generator import generate_audio_with_murf
from pydantic import BaseModel
from typing import Optional

app = FastAPI()

app.mount("/static", StaticFiles(directory=os.path.join(os.getcwd(), "static")), name="static")

class AnalysisResponse(BaseModel):
    status: str
    classification: Optional[str] = None
    confidence: Optional[float] = None
    analysis: dict
    metadata: dict

import base64
import uuid

class DetectRequest(BaseModel):
    # Support for the Hackathon Tester format
    language: Optional[str] = None
    audio_format: Optional[str] = None
    audio_base64_format: Optional[str] = None # Guessing key based on UI label
    audio_base64: Optional[str] = None # Common alternative
    # Support for our internal tools
    message: Optional[str] = None
    audio_url: Optional[str] = None

@app.post("/detect", response_model=AnalysisResponse)
async def detect_voice(
    request: Optional[DetectRequest] = None,
    file: UploadFile = File(None),
    message: str = Form(None),
    audio_url: str = Form(None),
    x_api_key: str = Depends(verify_api_key)
):
    UPLOAD_DIR = os.path.join(os.getcwd(), "uploads")
    os.makedirs(UPLOAD_DIR, exist_ok=True)

    # Check if we received a JSON body (request is not None)
    if request:
        # Handle Base64 input
        b64_data = request.audio_base64_format or request.audio_base64
        if b64_data:
            try:
                # Handle potential header separation (data:audio/mp3;base64,...)
                if "," in b64_data:
                     b64_data = b64_data.split(",")[1]
                
                decoded_data = base64.b64decode(b64_data)
                # Create a temporary file
                filename = f"upload_{uuid.uuid4()}.{request.audio_format or 'mp3'}"
                file_location = os.path.join(UPLOAD_DIR, filename)
                with open(file_location, "wb") as f:
                    f.write(decoded_data)
                
                # Process
                file_size = os.path.getsize(file_location)
                metadata = {
                    "filename": filename,
                    "size_bytes": file_size,
                    "format": filename.split(".")[-1],
                    "duration_seconds": 0.0
                }
                return {
                    "status": "success",
                    "analysis": analyze_audio(metadata),
                    "metadata": metadata
                }
            except Exception as e:
                raise HTTPException(status_code=400, detail=f"Invalid Base64 audio: {str(e)}")
        
        # Handle audio_url in JSON
        if request.audio_url:
             metadata = await process_audio(audio_url=request.audio_url)
             return {
                "status": "success", 
                "analysis": analyze_audio(metadata),
                "metadata": metadata
             }

    # Handle Form Data (File or URL)
    # validate file type if file is uploaded
    if file:
        if not file.filename.endswith(('.mp3', '.wav', '.m4a')):
             raise HTTPException(status_code=400, detail="Invalid file format. Only audio files allowed.")
    
    if not file and not audio_url:
        raise HTTPException(status_code=400, detail="Either file, audio_url, or base64 audio is required.")
    
    # Process Audio (get metadata)
    metadata = await process_audio(file, audio_url)
    
    # Run Detection
    # Run Detection
    result = analyze_audio(metadata)
    
    return {
        "status": "success",
        "classification": result.get("classification"),
        "confidence": result.get("confidence"),
        "analysis": result,
        "metadata": metadata
    }

class GenerateRequest(BaseModel):
    text: str
    murf_api_key: str
    voice_id: Optional[str] = "en-US-marcus"

@app.post("/generate")
def generate_speech(request: GenerateRequest):
    audio_url = generate_audio_with_murf(request.text, request.murf_api_key, request.voice_id)
    return {"status": "success", "audio_url": audio_url}

import os

@app.get("/")
def read_root():
    file_path = os.path.join(os.getcwd(), 'static', 'tester.html')
    if not os.path.exists(file_path):
        return {"error": "File not found", "path": file_path, "cwd": os.getcwd()}
    return FileResponse(file_path)