Salimshakeel commited on
Commit
9104277
·
1 Parent(s): 0526375
config.py CHANGED
@@ -1,8 +1,6 @@
1
- # config.py
2
- import torch
3
  import os
4
- UPLOAD_DIR = os.path.join(os.getcwd(), "static/uploads")
5
- OUTPUT_DIR = os.path.join(os.getcwd(), "static/outputs")
6
  FRAME_RATE = 15
7
  SCORE_THRESHOLD = 0.4
8
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
 
 
 
1
  import os
2
+ import torch
3
+
4
  FRAME_RATE = 15
5
  SCORE_THRESHOLD = 0.4
6
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
routes/summarize.py CHANGED
@@ -1,9 +1,10 @@
1
  from fastapi import APIRouter, UploadFile, File
2
  from fastapi.responses import JSONResponse
3
- from utils.file_utils import save_uploaded_file
4
  from services.extractor import extract_frames, extract_features
5
  from services.summarizer import get_scores, get_selected_indices, save_summary_video
6
- from config import UPLOAD_DIR, OUTPUT_DIR
 
 
7
 
8
  router = APIRouter()
9
 
@@ -12,11 +13,18 @@ def summarize_video(video: UploadFile = File(...)):
12
  if not video.filename.lower().endswith(('.mp4', '.avi', '.mov', '.mkv')):
13
  return JSONResponse(content={"error": "Unsupported file format"}, status_code=400)
14
 
15
- print("\n-----------> Uploading Video ....")
16
- video_path = save_uploaded_file(video, UPLOAD_DIR)
 
 
 
 
 
 
 
17
 
18
  print("\n-----------> Extracting Frames ....")
19
- frames, picks = extract_frames(video_path)
20
 
21
  print("\n-----------> Extracting Features ....")
22
  features = extract_features(frames)
@@ -26,14 +34,12 @@ def summarize_video(video: UploadFile = File(...)):
26
 
27
  print("\n-----------> Selecting Indices ....")
28
  selected = get_selected_indices(scores, picks)
29
- output_path = f"{OUTPUT_DIR}/summary_{video.filename}"
30
 
31
  print("\n-----------> Saving Video ....")
32
- save_summary_video(video_path, selected, output_path)
33
- summary_url = f"/static/outputs/summary_{video.filename}"
34
 
35
  print("\n-----------> Returning Response ....")
36
  return JSONResponse(content={
37
  "message": "Summarization complete",
38
- "summary_video_url": summary_url
39
  })
 
1
  from fastapi import APIRouter, UploadFile, File
2
  from fastapi.responses import JSONResponse
 
3
  from services.extractor import extract_frames, extract_features
4
  from services.summarizer import get_scores, get_selected_indices, save_summary_video
5
+ from uuid import uuid4
6
+ import time
7
+ import os
8
 
9
  router = APIRouter()
10
 
 
13
  if not video.filename.lower().endswith(('.mp4', '.avi', '.mov', '.mkv')):
14
  return JSONResponse(content={"error": "Unsupported file format"}, status_code=400)
15
 
16
+ extension = video.filename.split('.')[-1].lower()
17
+ id = time.time()
18
+ filename = f"{id}.{extension}"
19
+ filepath = os.path.join(os.getcwd(), "static", filename)
20
+ url = f"/static/{filename}"
21
+
22
+ print("\n-----------> Saving Video Locally ....")
23
+ with open(filepath, "wb") as f:
24
+ f.write(video.file.read())
25
 
26
  print("\n-----------> Extracting Frames ....")
27
+ frames, picks = extract_frames(filepath)
28
 
29
  print("\n-----------> Extracting Features ....")
30
  features = extract_features(frames)
 
34
 
35
  print("\n-----------> Selecting Indices ....")
36
  selected = get_selected_indices(scores, picks)
 
37
 
38
  print("\n-----------> Saving Video ....")
39
+ save_summary_video(filepath, selected, filepath)
 
40
 
41
  print("\n-----------> Returning Response ....")
42
  return JSONResponse(content={
43
  "message": "Summarization complete",
44
+ "summary_video_url": url
45
  })
services/extractor.py CHANGED
@@ -46,7 +46,7 @@ def extract_frames(video_path):
46
  frames = []
47
  indices = []
48
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
49
- total_frames = 100 # TEMP
50
 
51
  for idx in tqdm(range(0, total_frames, FRAME_RATE)):
52
  cap.set(cv2.CAP_PROP_POS_FRAMES, idx)
 
46
  frames = []
47
  indices = []
48
  total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
49
+ total_frames = 300 # TEMP
50
 
51
  for idx in tqdm(range(0, total_frames, FRAME_RATE)):
52
  cap.set(cv2.CAP_PROP_POS_FRAMES, idx)
services/summarizer.py CHANGED
@@ -45,26 +45,8 @@ def save_summary_video(video_path, selected_indices, output_path, fps=15):
45
 
46
  h, w, _ = list(frames.values())[0].shape
47
 
48
- # 1️⃣ Save raw video first
49
- raw_output_path = output_path.replace(".mp4", "_raw.mp4")
50
- writer = cv2.VideoWriter(raw_output_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (w, h))
51
  for fid in sorted(frames.keys()):
52
  writer.write(frames[fid])
53
  writer.release()
54
-
55
- # 2️⃣ Use FFmpeg to fix video (browser-compatible)
56
- try:
57
- subprocess.run([
58
- "ffmpeg",
59
- "-y", # overwrite if file exists
60
- "-i", raw_output_path,
61
- "-vcodec", "libx264",
62
- "-acodec", "aac",
63
- output_path
64
- ], check=True)
65
- os.remove(raw_output_path) # optional: remove raw file
66
- print(f"✅ FFmpeg re-encoded video saved to: {output_path}")
67
- except subprocess.CalledProcessError as e:
68
- print("❌ FFmpeg failed:", e)
69
- print("⚠️ Using raw video instead.")
70
- os.rename(raw_output_path, output_path)
 
45
 
46
  h, w, _ = list(frames.values())[0].shape
47
 
48
+ os.remove(output_path)
49
+ writer = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (w, h))
 
50
  for fid in sorted(frames.keys()):
51
  writer.write(frames[fid])
52
  writer.release()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
static/.gitignore ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # Ignore everything
2
+ *
3
+
4
+ # But not this file
5
+ !README.md
6
+ !.gitignore
static/README.md ADDED
@@ -0,0 +1 @@
 
 
1
+ All uploaded and summarized videos are stored here.
static/uploads/77ea55af6d744160a5c7e8440b294bb6_Paris Saint-Germain vs Atlético de Madrid Highlights | FIFA Club World Cup 2025.mp4 DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:99183f4ca670013008f6a45943bf878532a1db1ad0753f671d289f55f45dac93
3
- size 22890415
 
 
 
 
static/uploads/84daab3df51f418ebff312b2ed129bc1_Paris Saint-Germain vs Atlético de Madrid Highlights | FIFA Club World Cup 2025.mp4 DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:99183f4ca670013008f6a45943bf878532a1db1ad0753f671d289f55f45dac93
3
- size 22890415
 
 
 
 
static/uploads/8ba4aec007f5404db2e9ac9570e59ca6_Paris Saint-Germain vs Atlético de Madrid Highlights | FIFA Club World Cup 2025.mp4 DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:99183f4ca670013008f6a45943bf878532a1db1ad0753f671d289f55f45dac93
3
- size 22890415
 
 
 
 
static/uploads/b0b93f4bcdcb4662865bb4dc26c1b243_Paris Saint-Germain vs Atlético de Madrid Highlights | FIFA Club World Cup 2025.mp4 DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:99183f4ca670013008f6a45943bf878532a1db1ad0753f671d289f55f45dac93
3
- size 22890415
 
 
 
 
static/uploads/e051610a8a634fd9a9de3c016d38ce73_Paris Saint-Germain vs Atlético de Madrid Highlights | FIFA Club World Cup 2025.mp4 DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:99183f4ca670013008f6a45943bf878532a1db1ad0753f671d289f55f45dac93
3
- size 22890415
 
 
 
 
utils/__init__.py DELETED
File without changes
utils/file_utils.py DELETED
@@ -1,10 +0,0 @@
1
- import os
2
- from uuid import uuid4
3
-
4
- def save_uploaded_file(uploaded_file, upload_dir):
5
- os.makedirs(upload_dir, exist_ok=True)
6
- filename = f"{uuid4().hex}_{uploaded_file.filename}"
7
- filepath = os.path.join(upload_dir, filename)
8
- with open(filepath, "wb") as f:
9
- f.write(uploaded_file.file.read())
10
- return filepath