Skip to content

Commit

Permalink
[build] Enable Moviepy tests for builds and document workarounds for #…
Browse files Browse the repository at this point in the history
  • Loading branch information
Breakthrough committed Nov 23, 2024
1 parent 0e1df2b commit 10fba27
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 9 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ jobs:
pip install av opencv-python-headless --only-binary :all:
pip install -r requirements_headless.txt
- name: Install MoviePy
# TODO: We can only run MoviePy tests on systems that have ffmpeg.
if: ${{ runner.arch == 'X64' }}
run: |
pip install moviepy
- name: Checkout test resources
run: |
git fetch --depth=1 https://github.com/Breakthrough/PySceneDetect.git refs/heads/resources:refs/remotes/origin/resources
Expand Down
9 changes: 5 additions & 4 deletions scenedetect/_cli/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ def run_scenedetect(context: CliContext):
logger.debug("No input specified.")
return

# Suppress warnings when reading past EOF in MoviePy.
is_debug = context.config.get_value("global", "verbosity") != "debug"
if isinstance(context.video_stream, VideoStreamMoviePy) and not is_debug:
warnings.filterwarnings("ignore", module="moviepy")
# Suppress warnings when reading past EOF in MoviePy (#461).
if VideoStreamMoviePy and isinstance(context.video_stream, VideoStreamMoviePy):
is_debug = context.config.get_value("global", "verbosity") != "debug"
if not is_debug:
warnings.filterwarnings("ignore", module="moviepy")

if context.load_scenes_input:
# Skip detection if load-scenes was used.
Expand Down
3 changes: 2 additions & 1 deletion scenedetect/backends/moviepy.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def seek(self, target: Union[FrameTimecode, float, int]):
try:
self._last_frame = self._reader.get_frame(target.get_seconds())
if hasattr(self._reader, "last_read") and target >= self.duration:
raise SeekError("MoviePy > 2.0 does not have proper EOF semantics.")
raise SeekError("MoviePy > 2.0 does not have proper EOF semantics (#461).")
self._frame_number = min(
target.frame_num,
FrameTimecode(self._reader.infos["duration"], self.frame_rate).frame_num - 1,
Expand Down Expand Up @@ -228,6 +228,7 @@ def read(self, decode: bool = True, advance: bool = True) -> Union[np.ndarray, b
if not hasattr(self._reader, "lastread") or self._eof:
return False
has_last_read = hasattr(self._reader, "last_read")
# In MoviePy 2.0 there is a separate property we need to read named differently (#461).
self._last_frame = self._reader.last_read if has_last_read else self._reader.lastread
# Read the *next* frame for the following call to read, and to check for EOF.
frame = self._reader.read_frame()
Expand Down
11 changes: 7 additions & 4 deletions tests/test_video_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
from dataclasses import dataclass
from typing import List, Type

import moviepy
import numpy
import pytest

Expand All @@ -42,7 +41,11 @@
# The warning occurs when reading the last frame, which VideoStreamMoviePy handles gracefully.
MOVIEPY_WARNING_FILTER = "ignore:.*Using the last valid frame instead.:UserWarning"

MOVIEPY_MAJOR_VERSION = int(moviepy.__version__.split(".")[0])

def get_moviepy_major_version() -> int:
import moviepy

return int(moviepy.__version__.split(".")[0])


def calculate_frame_delta(frame_a, frame_b, roi=None) -> float:
Expand Down Expand Up @@ -357,8 +360,8 @@ def test_corrupt_video(vs_type: Type[VideoStream], corrupt_video_file: str):
"""Test that backend handles video with corrupt frame gracefully with defaults."""
if vs_type == VideoManager:
pytest.skip(reason="VideoManager does not support handling corrupt videos.")
if vs_type == VideoStreamMoviePy and MOVIEPY_MAJOR_VERSION >= 2:
# Due to changes in MoviePy 2.0, loading this file causes an exception to be thrown.
if vs_type == VideoStreamMoviePy and get_moviepy_major_version() >= 2:
# Due to changes in MoviePy 2.0 (#461), loading this file causes an exception to be thrown.
# See https://github.com/Zulko/moviepy/pull/2253 for a PR that attempts to more gracefully
# handle this case, however even once that is fixed, we will be unable to run this test
# on certain versions of MoviePy.
Expand Down

0 comments on commit 10fba27

Please sign in to comment.