Pepguy commited on
Commit
fdb06d1
·
verified ·
1 Parent(s): e285d1f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +89 -10
app.py CHANGED
@@ -1,16 +1,95 @@
1
- from fastapi import FastAPI
 
 
2
  import subprocess
 
 
 
 
3
 
4
  app = FastAPI()
5
 
6
- @app.get("/")
7
- def greet_json():
8
- return {"Hello": "World!"}
 
 
9
 
10
- @app.get("/ffmpeg-version")
11
- def get_ffmpeg_version():
 
 
 
 
 
 
 
 
 
 
 
 
12
  try:
13
- result = subprocess.run(["ffmpeg", "-version"], capture_output=True, text=True)
14
- return {"ffmpeg_version": result.stdout.splitlines()[0]} # Return only the first line
15
- except FileNotFoundError:
16
- return {"error": "FFmpeg is not installed or not found in PATH"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # media_server.py
2
+ from fastapi import FastAPI, HTTPException
3
+ from pydantic import BaseModel
4
  import subprocess
5
+ import base64
6
+ import os
7
+ import uuid
8
+ import shutil
9
 
10
  app = FastAPI()
11
 
12
+ class VideoRequest(BaseModel):
13
+ url: str
14
+ platform: str
15
+ is_pro: bool = False
16
+ fps: int = 2 # Default to 2 frames per second
17
 
18
+ def file_to_base64(filepath):
19
+ with open(filepath, "rb") as f:
20
+ return base64.b64encode(f.read()).decode('utf-8')
21
+
22
+ @app.post("/process-video")
23
+ def process_video(req: VideoRequest):
24
+ # 1. Create a dedicated folder for this specific task
25
+ job_id = str(uuid.uuid4())
26
+ work_dir = f"/tmp/viralcat_{job_id}"
27
+ os.makedirs(work_dir, exist_ok=True)
28
+
29
+ video_path = f"{work_dir}/video.mp4"
30
+ audio_path = f"{work_dir}/audio.mp3"
31
+
32
  try:
33
+ # 2. Download the Video
34
+ subprocess.run([
35
+ "yt-dlp",
36
+ "-f", "best[height<=720]",
37
+ "-o", video_path,
38
+ req.url
39
+ ], check=True, capture_output=True)
40
+
41
+ # 3. Check Duration (Limit to 2 minutes / 120 seconds if not Pro)
42
+ probe = subprocess.run([
43
+ "ffprobe", "-v", "error", "-show_entries",
44
+ "format=duration", "-of", "default=noprint_wrappers=1:nokey=1",
45
+ video_path
46
+ ], capture_output=True, text=True, check=True)
47
+
48
+ duration = float(probe.stdout.strip())
49
+
50
+ if duration > 120 and not req.is_pro:
51
+ raise ValueError(f"Video is {duration:.1f}s long. Free users are limited to 120 seconds.")
52
+
53
+ # 4. Dynamic Frame Extraction (e.g., 2 frames per second)
54
+ # This creates files like frame_0001.jpg, frame_0002.jpg inside the work_dir
55
+ subprocess.run([
56
+ "ffmpeg", "-y", "-i", video_path,
57
+ "-vf", f"fps={req.fps}",
58
+ "-q:v", "2", f"{work_dir}/frame_%04d.jpg"
59
+ ], check=True, capture_output=True)
60
+
61
+ # 5. Extract Uncut Audio
62
+ subprocess.run([
63
+ "ffmpeg", "-y", "-i", video_path,
64
+ "-q:a", "0", "-map", "a", "-ac", "1", "-b:a", "64k", audio_path
65
+ ], check=True, capture_output=True)
66
+
67
+ # 6. Gather all extracted frames and convert to Base64
68
+ # Sort them so they are in chronological order for the AI
69
+ frame_files = sorted([f for f in os.listdir(work_dir) if f.startswith("frame_") and f.endswith(".jpg")])
70
+ frames_b64 =[file_to_base64(os.path.join(work_dir, f)) for f in frame_files]
71
+
72
+ # Get audio
73
+ audio_b64 = file_to_base64(audio_path) if os.path.exists(audio_path) else None
74
+
75
+ return {
76
+ "success": True,
77
+ "duration": duration,
78
+ "total_frames_extracted": len(frames_b64),
79
+ "frames": frames_b64,
80
+ "audio": audio_b64,
81
+ "thumbnail_url": "https://placehold.co/400x600/png"
82
+ }
83
+
84
+ except ValueError as ve:
85
+ raise HTTPException(status_code=400, detail=str(ve))
86
+ except subprocess.CalledProcessError as e:
87
+ raise HTTPException(status_code=500, detail=f"Media processing failed: {e.stderr.decode() if e.stderr else str(e)}")
88
+ except Exception as e:
89
+ raise HTTPException(status_code=500, detail=str(e))
90
+
91
+ finally:
92
+ # 🚨 ABSOLUTE CLEANUP: Delete the entire UUID folder and all its contents
93
+ if os.path.exists(work_dir):
94
+ shutil.rmtree(work_dir, ignore_errors=True)
95
+ print(f"[CLEANUP] Deleted temporary folder: {work_dir}")