Spaces:
Sleeping
Sleeping
Update services/video_service.py
Browse files- services/video_service.py +77 -58
services/video_service.py
CHANGED
@@ -9,79 +9,98 @@ logging.basicConfig(
|
|
9 |
format="%(asctime)s - %(levelname)s - %(message)s"
|
10 |
)
|
11 |
|
12 |
-
# Global
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
15 |
|
16 |
-
def
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
|
|
|
|
|
|
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
except Exception as e:
|
38 |
logging.error(f"Error preloading video: {str(e)}")
|
39 |
-
|
40 |
|
41 |
def get_next_video_frame():
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
|
|
|
|
51 |
|
52 |
try:
|
53 |
-
|
54 |
-
|
55 |
-
ret, frame = video_cap.read()
|
56 |
-
if not ret:
|
57 |
-
# Loop back to the start
|
58 |
-
current_frame_index = 0
|
59 |
-
video_cap.set(cv2.CAP_PROP_POS_FRAMES, current_frame_index)
|
60 |
-
ret, frame = video_cap.read()
|
61 |
if not ret:
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
|
|
|
|
|
|
|
|
|
|
66 |
return frame
|
67 |
except Exception as e:
|
68 |
logging.error(f"Error retrieving frame: {str(e)}")
|
69 |
-
|
70 |
|
71 |
def reset_video_index():
|
72 |
-
|
73 |
-
|
74 |
-
""
|
75 |
-
global current_frame_index
|
76 |
-
current_frame_index = 0
|
77 |
-
logging.info("Reset video frame index to 0.")
|
78 |
|
79 |
def release_video():
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
if video_cap is not None:
|
85 |
-
video_cap.release()
|
86 |
-
video_cap = None
|
87 |
logging.info("Released video capture object.")
|
|
|
9 |
format="%(asctime)s - %(levelname)s - %(message)s"
|
10 |
)
|
11 |
|
12 |
+
# Global state
|
13 |
+
VIDEO_DIR = "data"
|
14 |
+
video_files = []
|
15 |
+
video_index = 0
|
16 |
+
cap = None
|
17 |
+
FRAME_SKIP = 3
|
18 |
+
PRELOADED_FRAMES = []
|
19 |
|
20 |
+
def update_video_files(video_path: str = None):
|
21 |
+
global video_files
|
22 |
+
if video_path and os.path.exists(video_path) and video_path.endswith((".mp4", ".avi")):
|
23 |
+
video_files = [video_path]
|
24 |
+
else:
|
25 |
+
if os.path.exists(VIDEO_DIR):
|
26 |
+
video_files = [
|
27 |
+
os.path.join(VIDEO_DIR, file)
|
28 |
+
for file in sorted(os.listdir(VIDEO_DIR))
|
29 |
+
if file.endswith((".mp4", ".avi"))
|
30 |
+
]
|
31 |
+
else:
|
32 |
+
video_files = []
|
33 |
+
if not video_files:
|
34 |
+
logging.warning("No video files found.")
|
35 |
+
else:
|
36 |
+
logging.info(f"Found video files: {video_files}")
|
37 |
|
38 |
+
def preload_video(video_path: str = None):
|
39 |
+
global cap, video_index, PRELOADED_FRAMES, video_files
|
40 |
+
update_video_files(video_path)
|
41 |
+
if not video_files:
|
42 |
+
logging.error("No video files available to preload.")
|
43 |
+
raise RuntimeError("No video files found in the 'data' directory or provided path.")
|
44 |
|
45 |
+
try:
|
46 |
+
video_index = 0
|
47 |
+
cap = cv2.VideoCapture(video_files[video_index])
|
48 |
+
if not cap.isOpened():
|
49 |
+
raise RuntimeError(f"Failed to open video {video_files[video_index]}")
|
50 |
+
PRELOADED_FRAMES = []
|
51 |
+
for _ in range(5):
|
52 |
+
ret, frame = cap.read()
|
53 |
+
if ret:
|
54 |
+
frame = cv2.resize(frame, (320, 240))
|
55 |
+
PRELOADED_FRAMES.append(frame)
|
56 |
+
else:
|
57 |
+
break
|
58 |
+
cap.release()
|
59 |
+
cap = None
|
60 |
+
logging.info(f"Preloaded {len(PRELOADED_FRAMES)} frames from {video_files[video_index]}")
|
61 |
except Exception as e:
|
62 |
logging.error(f"Error preloading video: {str(e)}")
|
63 |
+
raise RuntimeError(f"Failed to preload video: {str(e)}")
|
64 |
|
65 |
def get_next_video_frame():
|
66 |
+
global cap, video_index, PRELOADED_FRAMES
|
67 |
+
if not video_files:
|
68 |
+
raise RuntimeError("No video files found.")
|
69 |
+
|
70 |
+
if PRELOADED_FRAMES:
|
71 |
+
frame = PRELOADED_FRAMES.pop(0)
|
72 |
+
logging.debug(f"Retrieved preloaded frame {len(PRELOADED_FRAMES) + 1}")
|
73 |
+
return frame
|
74 |
+
|
75 |
+
if cap is None or not cap.isOpened():
|
76 |
+
cap = cv2.VideoCapture(video_files[video_index])
|
77 |
|
78 |
try:
|
79 |
+
for _ in range(FRAME_SKIP):
|
80 |
+
ret, frame = cap.read()
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
if not ret:
|
82 |
+
cap.release()
|
83 |
+
video_index = (video_index + 1) % len(video_files)
|
84 |
+
cap = cv2.VideoCapture(video_files[video_index])
|
85 |
+
ret, frame = cap.read()
|
86 |
+
if not ret:
|
87 |
+
raise RuntimeError(f"Cannot read video {video_files[video_index]}")
|
88 |
+
break
|
89 |
+
frame = cv2.resize(frame, (320, 240))
|
90 |
+
logging.debug(f"Retrieved frame from {video_files[video_index]}")
|
91 |
return frame
|
92 |
except Exception as e:
|
93 |
logging.error(f"Error retrieving frame: {str(e)}")
|
94 |
+
raise RuntimeError(f"Failed to retrieve frame: {str(e)}")
|
95 |
|
96 |
def reset_video_index():
|
97 |
+
global video_index
|
98 |
+
video_index = 0
|
99 |
+
logging.info("Reset video index to 0.")
|
|
|
|
|
|
|
100 |
|
101 |
def release_video():
|
102 |
+
global cap
|
103 |
+
if cap is not None:
|
104 |
+
cap.release()
|
105 |
+
cap = None
|
|
|
|
|
|
|
106 |
logging.info("Released video capture object.")
|