Skip to content

Commit

Permalink
[bugfix] Fix for circular import errors #350
Browse files Browse the repository at this point in the history
Breakthrough committed Dec 2, 2023
1 parent 9bf4dd9 commit 09caa3c
Showing 7 changed files with 29 additions and 28 deletions.
12 changes: 6 additions & 6 deletions scenedetect/backends/moviepy.py
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@

import cv2
from moviepy.video.io.ffmpeg_reader import FFMPEG_VideoReader
from numpy import ndarray
import numpy as np

from scenedetect.frame_timecode import FrameTimecode
from scenedetect.platform import get_file_name
@@ -63,8 +63,8 @@ def __init__(self, path: AnyStr, framerate: Optional[float] = None, print_infos:
# This will always be one behind self._reader.lastread when we finally call read()
# as MoviePy caches the first frame when opening the video. Thus self._last_frame
# will always be the current frame, and self._reader.lastread will be the next.
self._last_frame: Union[bool, ndarray] = False
self._last_frame_rgb: Optional[ndarray] = None
self._last_frame: Union[bool, np.ndarray] = False
self._last_frame_rgb: Optional[np.ndarray] = None
# Older versions don't track the video position when calling read_frame so we need
# to keep track of the current frame number.
self._frame_number = 0
@@ -193,15 +193,15 @@ def reset(self):
self._frame_number = 0
self._eof = False

def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool]:
"""Read and decode the next frame as a numpy.ndarray. Returns False when video ends.
def read(self, decode: bool = True, advance: bool = True) -> Union[np.ndarray, bool]:
"""Read and decode the next frame as a np.ndarray. Returns False when video ends.
Arguments:
decode: Decode and return the frame.
advance: Seek to the next frame. If False, will return the current (last) frame.
Returns:
If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video.
If decode = True, the decoded frame (np.ndarray), or False (bool) if end of video.
If decode = False, a bool indicating if advancing to the the next frame succeeded.
"""
if not advance:
14 changes: 7 additions & 7 deletions scenedetect/backends/opencv.py
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@
import os.path

import cv2
from numpy import ndarray
import numpy as np

from scenedetect.frame_timecode import FrameTimecode, MAX_FPS_DELTA
from scenedetect.platform import get_file_name
@@ -262,16 +262,16 @@ def reset(self):
self._cap.release()
self._open_capture(self._frame_rate)

def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool]:
"""Read and decode the next frame as a numpy.ndarray. Returns False when video ends,
def read(self, decode: bool = True, advance: bool = True) -> Union[np.ndarray, bool]:
"""Read and decode the next frame as a np.ndarray. Returns False when video ends,
or the maximum number of decode attempts has passed.
Arguments:
decode: Decode and return the frame.
advance: Seek to the next frame. If False, will return the current (last) frame.
Returns:
If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video.
If decode = True, the decoded frame (np.ndarray), or False (bool) if end of video.
If decode = False, a bool indicating if advancing to the the next frame succeeded.
"""
if not self._cap.isOpened():
@@ -497,16 +497,16 @@ def reset(self):
"""Not supported."""
raise NotImplementedError("Reset is not supported.")

def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool]:
"""Read and decode the next frame as a numpy.ndarray. Returns False when video ends,
def read(self, decode: bool = True, advance: bool = True) -> Union[np.ndarray, bool]:
"""Read and decode the next frame as a np.ndarray. Returns False when video ends,
or the maximum number of decode attempts has passed.
Arguments:
decode: Decode and return the frame.
advance: Seek to the next frame. If False, will return the current (last) frame.
Returns:
If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video.
If decode = True, the decoded frame (np.ndarray), or False (bool) if end of video.
If decode = False, a bool indicating if advancing to the the next frame succeeded.
"""
if not self._cap.isOpened():
8 changes: 4 additions & 4 deletions scenedetect/backends/pyav.py
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@

# pylint: disable=c-extension-no-member
import av
from numpy import ndarray
import numpy as np

from scenedetect.frame_timecode import FrameTimecode, MAX_FPS_DELTA
from scenedetect.platform import get_file_name
@@ -261,15 +261,15 @@ def reset(self):
except Exception as ex:
raise VideoOpenFailure() from ex

def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool]:
"""Read and decode the next frame as a numpy.ndarray. Returns False when video ends.
def read(self, decode: bool = True, advance: bool = True) -> Union[np.ndarray, bool]:
"""Read and decode the next frame as a np.ndarray. Returns False when video ends.
Arguments:
decode: Decode and return the frame.
advance: Seek to the next frame. If False, will return the current (last) frame.
Returns:
If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video.
If decode = True, the decoded frame (np.ndarray), or False (bool) if end of video.
If decode = False, a bool indicating if advancing to the the next frame succeeded.
"""
has_advanced = False
6 changes: 3 additions & 3 deletions scenedetect/detectors/adaptive_detector.py
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
from logging import getLogger
from typing import List, Optional

from numpy import ndarray
import numpy as np

from scenedetect.detectors import ContentDetector

@@ -114,14 +114,14 @@ def stats_manager_required(self) -> bool:
"""Not required for AdaptiveDetector."""
return False

def process_frame(self, frame_num: int, frame_img: Optional[ndarray]) -> List[int]:
def process_frame(self, frame_num: int, frame_img: Optional[np.ndarray]) -> List[int]:
""" Similar to ThresholdDetector, but using the HSV colour space DIFFERENCE instead
of single-frame RGB/grayscale intensity (thus cannot detect slow fades with this method).
Arguments:
frame_num: Frame number of frame that is being passed.
frame_img: Decoded frame image (numpy.ndarray) to perform scene
frame_img: Decoded frame image (np.ndarray) to perform scene
detection on. Can be None *only* if the self.is_processing_required() method
(inhereted from the base SceneDetector class) returns True.
8 changes: 4 additions & 4 deletions scenedetect/video_manager.py
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@
from logging import getLogger

from typing import Iterable, List, Optional, Tuple, Union
from numpy import ndarray
import numpy as np
import cv2

from scenedetect.platform import get_file_name
@@ -630,14 +630,14 @@ def grab(self) -> bool:
self._correct_frame_length()
return grabbed

def retrieve(self) -> Tuple[bool, Optional[ndarray]]:
def retrieve(self) -> Tuple[bool, Optional[np.ndarray]]:
""" Retrieve (cv2.VideoCapture method) - retrieves and returns a frame.
Frame returned corresponds to last call to :meth:`grab()`.
Returns:
Tuple of (True, frame_image) if a frame was grabbed during the last call to grab(),
and where frame_image is a numpy ndarray of the decoded frame. Otherwise (False, None).
and where frame_image is a numpy np.ndarray of the decoded frame. Otherwise (False, None).
"""
if not self._started:
self.start()
@@ -653,7 +653,7 @@ def retrieve(self) -> Tuple[bool, Optional[ndarray]]:
self._last_frame = None
return (retrieved, self._last_frame)

def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool]:
def read(self, decode: bool = True, advance: bool = True) -> Union[np.ndarray, bool]:
""" Return next frame (or current if advance = False), or False if end of video.
Arguments:
8 changes: 4 additions & 4 deletions scenedetect/video_stream.py
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@
from logging import getLogger
from typing import Tuple, Optional, Union

from numpy import ndarray
import numpy as np

from scenedetect.frame_timecode import FrameTimecode

@@ -178,15 +178,15 @@ def frame_number(self) -> int:
#

@abstractmethod
def read(self, decode: bool = True, advance: bool = True) -> Union[ndarray, bool]:
"""Read and decode the next frame as a numpy.ndarray. Returns False when video ends.
def read(self, decode: bool = True, advance: bool = True) -> Union[np.ndarray, bool]:
"""Read and decode the next frame as a np.ndarray. Returns False when video ends.
Arguments:
decode: Decode and return the frame.
advance: Seek to the next frame. If False, will return the current (last) frame.
Returns:
If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video.
If decode = True, the decoded frame (np.ndarray), or False (bool) if end of video.
If decode = False, a bool indicating if advancing to the the next frame succeeded.
"""
raise NotImplementedError
1 change: 1 addition & 0 deletions website/pages/changelog.md
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ Releases
**API Changes:**

- [bugfix] Fix `AttributeError` thrown when accessing `aspect_ratio` on certain videos using `VideoStreamAv` [#355](https://github.com/Breakthrough/PySceneDetect/issues/355)
- [bugfix] Fix circular imports due to partially initialized module for some development environments [#350](https://github.com/Breakthrough/PySceneDetect/issues/350)


### 0.6.2 (July 23, 2023)

0 comments on commit 09caa3c

Please sign in to comment.