Skip to content

Commit

Permalink
Reduce strictness of file path validation (#64)
Browse files Browse the repository at this point in the history
* Reduce strictness of file path validation

* Bump version

* Cleanup error handling
  • Loading branch information
tyler-romero authored Dec 18, 2024
1 parent 3b59435 commit ce6a462
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 31 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "framegrab"
version = "0.9.0"
version = "0.9.1"
description = "Easily grab frames from cameras or streams"
authors = ["Groundlight <[email protected]>"]
license = "MIT"
Expand Down
46 changes: 17 additions & 29 deletions src/framegrab/grabber.py
Original file line number Diff line number Diff line change
Expand Up @@ -1263,10 +1263,6 @@ def __init__(self, config: dict):
if not filename:
raise ValueError("No filename provided in config under id.filename")

self.filepath = Path(filename).resolve()
if not self.filepath.is_file():
raise OSError(f"File does not exist: {self.filepath}")

self.fps_target = config.get("options", {}).get(
"max_fps",
0, # 0 means no dropping of frames
Expand All @@ -1275,32 +1271,24 @@ def __init__(self, config: dict):
raise ValueError(f"Target FPS cannot be negative: {self.fps_target}")
self.remainder = 0.0

try:
self.capture = cv2.VideoCapture(filename)
try:
backend = self.capture.getBackendName()
except cv2.error:
raise ValueError(f"Could not open file {filename}. Is it a valid video file?")
logger.debug(f"Initialized video capture with {backend=}")

ret, _ = self.capture.read()
if not ret:
raise RuntimeError("Could not read first frame")

self.fps_source = round(self.capture.get(cv2.CAP_PROP_FPS), 2)
if self.fps_source <= 0.1:
logger.warning(f"Captured framerate is very low or zero: {self.fps_source} FPS")
self.should_drop_frames = self.fps_target > 0 and self.fps_target < self.fps_source
logger.debug(
f"Source FPS: {self.fps_source}, Target FPS: {self.fps_target}, Drop Frames: {self.should_drop_frames}"
)
self.capture = cv2.VideoCapture(filename)
if not self.capture.isOpened():
raise ValueError(f"Could not open file {filename}. Is it a valid video file?")
backend = self.capture.getBackendName()
logger.debug(f"Initialized video capture with {backend=}")

except (cv2.error, RuntimeError) as e:
logger.error(f"Could not initialize FileStreamFrameGrabber: {filename} is invalid or read error: {str(e)}")
raise
except OSError as e:
logger.error(f"Could not open file {filename}: {str(e)}")
raise
ret, _ = self.capture.read()
if not ret:
self.capture.release()
raise ValueError(f"Could not read first frame of file {filename}. Is it a valid video file?")

self.fps_source = round(self.capture.get(cv2.CAP_PROP_FPS), 2)
if self.fps_source <= 0.1:
logger.warning(f"Captured framerate is very low or zero: {self.fps_source} FPS")
self.should_drop_frames = self.fps_target > 0 and self.fps_target < self.fps_source
logger.debug(
f"Source FPS: {self.fps_source}, Target FPS: {self.fps_target}, Drop Frames: {self.should_drop_frames}"
)

def _grab_implementation(self) -> np.ndarray:
"""Grab a frame from the video file, decimating if needed to match target FPS.
Expand Down
2 changes: 1 addition & 1 deletion test/test_framegrab_with_filestream.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def test_invalid_file(self):
config = self.base_config_mp4.copy()
config["id"]["filename"] = "nonexistent.mp4"

with self.assertRaises(OSError):
with self.assertRaises(ValueError):
FileStreamFrameGrabber(config)

def test_invalid_resolution_option(self):
Expand Down

0 comments on commit ce6a462

Please sign in to comment.