|
| 1 | + |
| 2 | +.. _scenedetect-migration-guide: |
| 3 | + |
| 4 | +*********************************************************************** |
| 5 | +Migration Guide: v0.6 to v0.7 |
| 6 | +*********************************************************************** |
| 7 | + |
| 8 | +PySceneDetect v0.7 is a major release that overhauls timestamp handling to support variable framerate (VFR) videos. While the high-level :func:`scenedetect.detect` workflow is largely unchanged, several internal APIs have been restructured. This guide covers the changes needed to update applications from v0.6 to v0.7. |
| 9 | + |
| 10 | +The minimum supported Python version is now **Python 3.10**. |
| 11 | + |
| 12 | + |
| 13 | +======================================================================= |
| 14 | +Quick Check |
| 15 | +======================================================================= |
| 16 | + |
| 17 | +If your code only uses :func:`scenedetect.detect` with a built-in detector, it should work without changes: |
| 18 | + |
| 19 | +.. code:: python |
| 20 | +
|
| 21 | + # This still works in v0.7 |
| 22 | + from scenedetect import detect, ContentDetector |
| 23 | + scenes = detect("video.mp4", ContentDetector()) |
| 24 | +
|
| 25 | +
|
| 26 | +======================================================================= |
| 27 | +Import Changes |
| 28 | +======================================================================= |
| 29 | + |
| 30 | +Several submodules have been reorganized. If you import directly from `scenedetect` you do not need to make any changes. Update imports as follows: |
| 31 | + |
| 32 | +.. list-table:: |
| 33 | + :header-rows: 1 |
| 34 | + :widths: 50 50 |
| 35 | + |
| 36 | + * - v0.6 |
| 37 | + - v0.7 |
| 38 | + * - ``from scenedetect.frame_timecode import FrameTimecode`` |
| 39 | + - ``from scenedetect.common import FrameTimecode`` |
| 40 | + * - ``from scenedetect.scene_detector import SceneDetector`` |
| 41 | + - ``from scenedetect.detector import SceneDetector`` |
| 42 | + * - ``from scenedetect.video_splitter import split_video_ffmpeg`` |
| 43 | + - ``from scenedetect.output import split_video_ffmpeg`` |
| 44 | + * - ``from scenedetect.video_splitter import split_video_mkvmerge`` |
| 45 | + - ``from scenedetect.output import split_video_mkvmerge`` |
| 46 | + * - ``from scenedetect.scene_manager import save_images`` |
| 47 | + - ``from scenedetect.output import save_images`` |
| 48 | + * - ``from scenedetect.scene_manager import write_scene_list`` |
| 49 | + - ``from scenedetect.output import write_scene_list`` |
| 50 | + * - ``from scenedetect.scene_manager import write_scene_list_html`` |
| 51 | + - ``from scenedetect.output import write_scene_list_html`` |
| 52 | + * - ``from scenedetect.video_manager import VideoManager`` |
| 53 | + - Removed. Use :func:`scenedetect.open_video` instead. |
| 54 | + |
| 55 | +.. note:: |
| 56 | + |
| 57 | + Most commonly used types and functions are also available directly from the top-level ``scenedetect`` package (e.g. ``from scenedetect import FrameTimecode``), which has not changed. |
| 58 | + |
| 59 | + |
| 60 | +======================================================================= |
| 61 | +Custom Detector Changes |
| 62 | +======================================================================= |
| 63 | + |
| 64 | +If you have written a custom :class:`SceneDetector <scenedetect.detector.SceneDetector>` subclass, there are several interface changes. |
| 65 | + |
| 66 | +``process_frame`` Signature |
| 67 | +----------------------------------------------------------------------- |
| 68 | + |
| 69 | +The ``frame_num`` parameter (``int``) has been replaced with ``timecode`` (:class:`FrameTimecode <scenedetect.common.FrameTimecode>`): |
| 70 | + |
| 71 | +.. code:: python |
| 72 | +
|
| 73 | + # v0.6 |
| 74 | + class MyDetector(SceneDetector): |
| 75 | + def process_frame(self, frame_num: int, frame_img) -> List[int]: |
| 76 | + ... |
| 77 | +
|
| 78 | + # v0.7 |
| 79 | + class MyDetector(SceneDetector): |
| 80 | + def process_frame(self, timecode: FrameTimecode, frame_img) -> List[FrameTimecode]: |
| 81 | + ... |
| 82 | +
|
| 83 | +The same change applies to ``post_process()``. If you need the frame number, use ``timecode.frame_num``. |
| 84 | + |
| 85 | +``SceneDetector`` is Now Abstract |
| 86 | +----------------------------------------------------------------------- |
| 87 | + |
| 88 | +``SceneDetector`` is now a Python `abstract class <https://docs.python.org/3/library/abc.html>`_. Subclasses **must** implement ``process_frame()``. |
| 89 | + |
| 90 | +Removed Methods and Properties |
| 91 | +----------------------------------------------------------------------- |
| 92 | + |
| 93 | +The following have been removed from the ``SceneDetector`` interface: |
| 94 | + |
| 95 | +- ``is_processing_required()`` - detectors can now assume they always have frame data |
| 96 | +- ``stats_manager_required`` property - no longer needed |
| 97 | +- ``SparseSceneDetector`` interface - removed entirely |
| 98 | + |
| 99 | + |
| 100 | +======================================================================= |
| 101 | +``FrameTimecode`` Changes |
| 102 | +======================================================================= |
| 103 | + |
| 104 | +Read-Only Properties |
| 105 | +----------------------------------------------------------------------- |
| 106 | + |
| 107 | +``frame_num`` and ``framerate`` are now read-only properties. To change them, construct a new ``FrameTimecode``: |
| 108 | + |
| 109 | +.. code:: python |
| 110 | +
|
| 111 | + # v0.6 - direct assignment |
| 112 | + tc.frame_num = 100 # No longer works |
| 113 | +
|
| 114 | + # v0.7 - construct new instance |
| 115 | + tc = FrameTimecode(100, tc.framerate) |
| 116 | +
|
| 117 | +New Properties |
| 118 | +----------------------------------------------------------------------- |
| 119 | + |
| 120 | +Access ``frame_num``, ``framerate``, and ``seconds`` as properties instead of getter methods: |
| 121 | + |
| 122 | +.. code:: python |
| 123 | +
|
| 124 | + tc = FrameTimecode(100, 24.0) |
| 125 | + tc.frame_num # 100 |
| 126 | + tc.framerate # Fraction(24, 1) |
| 127 | + tc.seconds # ~4.167 |
| 128 | +
|
| 129 | +Removed Methods |
| 130 | +----------------------------------------------------------------------- |
| 131 | + |
| 132 | +- ``previous_frame()`` - removed, use ``FrameTimecode(tc.frame_num - 1, tc.framerate)`` instead |
| 133 | + |
| 134 | + |
| 135 | +======================================================================= |
| 136 | +Framerate and Timestamp Changes |
| 137 | +======================================================================= |
| 138 | + |
| 139 | +Rational Framerates |
| 140 | +----------------------------------------------------------------------- |
| 141 | + |
| 142 | +``VideoStream.frame_rate`` now returns a ``Fraction`` instead of ``float``. Common NTSC rates (23.976, 29.97, 59.94) are automatically detected from float values: |
| 143 | + |
| 144 | +.. code:: python |
| 145 | +
|
| 146 | + from fractions import Fraction |
| 147 | + video = open_video("video.mp4") |
| 148 | + assert isinstance(video.frame_rate, Fraction) |
| 149 | + # e.g. Fraction(24000, 1001) instead of 23.976023976... |
| 150 | +
|
| 151 | +PTS-Backed Timestamps |
| 152 | +----------------------------------------------------------------------- |
| 153 | + |
| 154 | +All backends now return presentation timestamp (PTS) backed values from ``VideoStream.position``. This enables correct handling of VFR videos. |
| 155 | + |
| 156 | +``FrameTimecode`` has new ``time_base`` and ``pts`` properties for accessing the underlying timing information. For VFR videos, ``frame_num`` is now an approximation based on PTS-derived time rather than a sequential count. |
| 157 | + |
| 158 | + |
| 159 | +======================================================================= |
| 160 | +``StatsManager`` Changes |
| 161 | +======================================================================= |
| 162 | + |
| 163 | +The ``StatsManager`` methods ``get_metrics()``, ``set_metrics()``, and ``metrics_exist()`` now take a ``FrameTimecode`` instead of ``int`` for the frame identifier, matching the detector interface change. |
| 164 | + |
| 165 | + |
| 166 | +======================================================================= |
| 167 | +Removed APIs |
| 168 | +======================================================================= |
| 169 | + |
| 170 | +The following deprecated APIs have been fully removed in v0.7: |
| 171 | + |
| 172 | +.. list-table:: |
| 173 | + :header-rows: 1 |
| 174 | + :widths: 50 50 |
| 175 | + |
| 176 | + * - Removed |
| 177 | + - Replacement |
| 178 | + * - ``scenedetect.video_manager`` module |
| 179 | + - :func:`scenedetect.open_video` |
| 180 | + * - ``base_timecode`` parameter (various functions) |
| 181 | + - No longer needed, remove the argument |
| 182 | + * - ``video_manager`` parameter (various functions) |
| 183 | + - Use ``video`` parameter instead |
| 184 | + * - ``SceneManager.get_event_list()`` |
| 185 | + - Use ``SceneManager.get_cut_list()`` or ``SceneManager.get_scene_list()`` |
| 186 | + * - ``AdaptiveDetector.get_content_val()`` |
| 187 | + - Use ``StatsManager`` to query metrics |
| 188 | + * - ``AdaptiveDetector(min_delta_hsv=...)`` |
| 189 | + - Use ``min_content_val`` parameter instead |
| 190 | + * - ``VideoStream.read(advance=...)`` |
| 191 | + - Call ``read()`` without the ``advance`` parameter |
| 192 | + * - ``SparseSceneDetector`` |
| 193 | + - No direct replacement, use ``SceneDetector`` |
| 194 | + |
| 195 | +.. note:: |
| 196 | + |
| 197 | + Deprecated v0.6 compatibility shims that still exist now emit warnings using the ``warnings`` module. Address any ``DeprecationWarning`` messages to prepare for future releases. |
| 198 | + |
| 199 | + |
| 200 | +======================================================================= |
| 201 | +CLI Changes |
| 202 | +======================================================================= |
| 203 | + |
| 204 | +- The ``-d``/``--min-delta-hsv`` option on ``detect-adaptive`` has been removed. Use ``-c``/``--min-content-val`` instead. |
| 205 | +- VFR videos now work correctly with both the OpenCV and PyAV backends. |
| 206 | +- New ``save-xml`` command for exporting scenes in Final Cut Pro XML format. |
0 commit comments