Opens capture referenced by this object and resets internal state.
(self, frame_rate: FrameRate | None = None)
| 310 | # |
| 311 | |
| 312 | def _open_capture(self, frame_rate: FrameRate | None = None): |
| 313 | """Opens capture referenced by this object and resets internal state.""" |
| 314 | if self._is_device: |
| 315 | assert isinstance(self._path_or_device, int) |
| 316 | if self._path_or_device < 0: |
| 317 | raise ValueError("Invalid/negative device ID specified.") |
| 318 | input_is_video_file = False |
| 319 | else: |
| 320 | assert isinstance(self._path_or_device, str) |
| 321 | input_is_video_file = not any( |
| 322 | identifier in self._path_or_device |
| 323 | for identifier in NON_VIDEO_FILE_INPUT_IDENTIFIERS |
| 324 | ) |
| 325 | # We don't have a way of querying why opening a video fails (errors are logged at |
| 326 | # least), so provide a better error message if we try to open a missing file. |
| 327 | if input_is_video_file and not os.path.exists(self._path_or_device): |
| 328 | raise OSError("Video file not found.") |
| 329 | |
| 330 | cap = cv2.VideoCapture(self._path_or_device) |
| 331 | if not cap.isOpened(): |
| 332 | raise VideoOpenFailure( |
| 333 | "Ensure file is valid video and system dependencies are up to date.\n" |
| 334 | ) |
| 335 | |
| 336 | # Display an error if the video codec type seems unsupported (#86) as this indicates |
| 337 | # potential video corruption, or may explain missing frames. We only perform this check |
| 338 | # for video files on-disk (skipped for devices, image sequences, streams, etc...). |
| 339 | codec_unsupported: bool = int(abs(cap.get(cv2.CAP_PROP_FOURCC))) == 0 |
| 340 | if codec_unsupported and input_is_video_file: |
| 341 | logger.error( |
| 342 | "Video codec detection failed. If output is incorrect:\n" |
| 343 | " - Re-encode the input video with ffmpeg\n" |
| 344 | " - Update OpenCV (pip install --upgrade opencv-python)\n" |
| 345 | " - Use the PyAV backend (--backend pyav)\n" |
| 346 | "For details, see https://github.com/Breakthrough/PySceneDetect/issues/86" |
| 347 | ) |
| 348 | |
| 349 | # Ensure the framerate is correct to avoid potential divide by zero errors. This can be |
| 350 | # addressed in the PyAV backend if required since it supports integer timebases. |
| 351 | assert frame_rate is None or frame_rate > MAX_FPS_DELTA, ( |
| 352 | "Frame rate must be validated if set!" |
| 353 | ) |
| 354 | if frame_rate is None: |
| 355 | frame_rate = cap.get(cv2.CAP_PROP_FPS) |
| 356 | if frame_rate < MAX_FPS_DELTA: |
| 357 | raise FrameRateUnavailable() |
| 358 | |
| 359 | self._cap: cv2.VideoCapture = cap |
| 360 | self._frame_rate: Fraction = framerate_to_fraction(frame_rate) |
| 361 | self._has_grabbed = False |
| 362 | cap.set(cv2.CAP_PROP_ORIENTATION_AUTO, 1.0) # https://github.com/opencv/opencv/issues/26795 |
| 363 | |
| 364 | |
| 365 | class VideoCaptureAdapter(VideoStream): |
no test coverage detected