scenedetect 0.7__tar.gz → 0.7.1.dev0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. {scenedetect-0.7/scenedetect.egg-info → scenedetect-0.7.1.dev0}/PKG-INFO +4 -12
  2. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/README.md +8 -7
  3. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/api/backends.rst +5 -2
  4. scenedetect-0.7.1.dev0/docs/api/common.rst +9 -0
  5. scenedetect-0.7.1.dev0/docs/api/detector.rst +9 -0
  6. scenedetect-0.7.1.dev0/docs/api/detectors.rst +53 -0
  7. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/api/migration_guide.rst +1 -1
  8. scenedetect-0.7.1.dev0/docs/api/output.rst +9 -0
  9. scenedetect-0.7.1.dev0/docs/api/platform.rst +9 -0
  10. scenedetect-0.7.1.dev0/docs/api/scene_manager.rst +9 -0
  11. scenedetect-0.7.1.dev0/docs/api/stats_manager.rst +9 -0
  12. scenedetect-0.7.1.dev0/docs/api/video_stream.rst +9 -0
  13. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/api.rst +9 -24
  14. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/cli.rst +4 -0
  15. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/conf.py +3 -0
  16. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/index.rst +2 -1
  17. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/packaging/package-info.rst +2 -0
  18. scenedetect-0.7.1.dev0/pyproject.toml +81 -0
  19. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/__init__.py +21 -6
  20. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/_cli/__init__.py +11 -0
  21. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/_cli/commands.py +13 -0
  22. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/_cli/config.py +1 -0
  23. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/backends/__init__.py +9 -0
  24. scenedetect-0.7.1.dev0/scenedetect/backends/concat.py +387 -0
  25. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/backends/opencv.py +4 -3
  26. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/backends/pyav.py +66 -25
  27. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/common.py +60 -3
  28. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/detector.py +2 -2
  29. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/detectors/content_detector.py +1 -1
  30. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/detectors/histogram_detector.py +16 -22
  31. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/detectors/threshold_detector.py +1 -1
  32. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/platform.py +18 -5
  33. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/scene_manager.py +30 -2
  34. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/video_stream.py +10 -0
  35. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect.cfg +5 -0
  36. {scenedetect-0.7 → scenedetect-0.7.1.dev0/scenedetect.egg-info}/PKG-INFO +4 -12
  37. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect.egg-info/SOURCES.txt +3 -0
  38. scenedetect-0.7.1.dev0/scenedetect.egg-info/requires.txt +11 -0
  39. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/tests/test_backend_opencv.py +18 -0
  40. scenedetect-0.7.1.dev0/tests/test_backend_pyav.py +93 -0
  41. scenedetect-0.7.1.dev0/tests/test_benchmark_evaluator.py +322 -0
  42. scenedetect-0.7.1.dev0/tests/test_concat.py +177 -0
  43. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/tests/test_scene_manager.py +52 -1
  44. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/tests/test_timecode.py +57 -0
  45. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/tests/test_vfr.py +20 -9
  46. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/tests/test_video_stream.py +27 -4
  47. scenedetect-0.7/docs/api/common.rst +0 -9
  48. scenedetect-0.7/docs/api/detector.rst +0 -9
  49. scenedetect-0.7/docs/api/detectors.rst +0 -24
  50. scenedetect-0.7/docs/api/output.rst +0 -36
  51. scenedetect-0.7/docs/api/platform.rst +0 -9
  52. scenedetect-0.7/docs/api/scene_manager.rst +0 -9
  53. scenedetect-0.7/docs/api/stats_manager.rst +0 -9
  54. scenedetect-0.7/docs/api/video_stream.rst +0 -9
  55. scenedetect-0.7/pyproject.toml +0 -157
  56. scenedetect-0.7/scenedetect.egg-info/requires.txt +0 -24
  57. scenedetect-0.7/tests/test_backend_pyav.py +0 -31
  58. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/LICENSE +0 -0
  59. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/LATEST_VERSION +0 -0
  60. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/Makefile +0 -0
  61. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/_static/favicon.ico +0 -0
  62. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/_static/pyscenedetect.css +0 -0
  63. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/_static/pyscenedetect_logo.png +0 -0
  64. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/_static/pyscenedetect_logo_small.png +0 -0
  65. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/_templates/navigation.html +0 -0
  66. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/cli/backends.rst +0 -0
  67. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/cli/config_file.rst +0 -0
  68. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/generate_cli_docs.py +0 -0
  69. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/docs/make.bat +0 -0
  70. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/__main__.py +0 -0
  71. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/_cli/context.py +0 -0
  72. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/_cli/controller.py +0 -0
  73. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/_thirdparty/__init__.py +0 -0
  74. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/_thirdparty/simpletable.py +0 -0
  75. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/backends/moviepy.py +0 -0
  76. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/detectors/__init__.py +0 -0
  77. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/detectors/adaptive_detector.py +0 -0
  78. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/detectors/hash_detector.py +0 -0
  79. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/detectors/transnet_v2.py +0 -0
  80. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/frame_timecode.py +0 -0
  81. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/output/__init__.py +0 -0
  82. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/output/image.py +0 -0
  83. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/output/video.py +0 -0
  84. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/scene_detector.py +0 -0
  85. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/stats_manager.py +0 -0
  86. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect/video_splitter.py +0 -0
  87. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect.egg-info/dependency_links.txt +0 -0
  88. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect.egg-info/entry_points.txt +0 -0
  89. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/scenedetect.egg-info/top_level.txt +0 -0
  90. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/setup.cfg +0 -0
  91. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/tests/test_api.py +0 -0
  92. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/tests/test_cli.py +0 -0
  93. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/tests/test_detectors.py +0 -0
  94. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/tests/test_output.py +0 -0
  95. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/tests/test_platform.py +0 -0
  96. {scenedetect-0.7 → scenedetect-0.7.1.dev0}/tests/test_stats_manager.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scenedetect
3
- Version: 0.7
4
- Summary: Video scene cut/shot detection program and Python library.
3
+ Version: 0.7.1.dev0
4
+ Summary: Video scene cut/shot detection program and Python library (bundles the opencv-python OpenCV variant and the scenedetect CLI).
5
5
  Author-email: Brandon Castellano <brandon248@gmail.com>
6
6
  License-Expression: BSD-3-Clause
7
7
  Project-URL: Homepage, https://www.scenedetect.com
@@ -37,16 +37,6 @@ Provides-Extra: pyav
37
37
  Requires-Dist: av>=9.2; extra == "pyav"
38
38
  Provides-Extra: moviepy
39
39
  Requires-Dist: moviepy; extra == "moviepy"
40
- Provides-Extra: dev
41
- Requires-Dist: av>=9.2; extra == "dev"
42
- Requires-Dist: moviepy; extra == "dev"
43
- Requires-Dist: pytest>=7.0; extra == "dev"
44
- Provides-Extra: docs
45
- Requires-Dist: Sphinx==7.0.1; extra == "docs"
46
- Requires-Dist: sphinx-copybutton==0.5.2; extra == "docs"
47
- Provides-Extra: website
48
- Requires-Dist: mkdocs==1.5.2; extra == "website"
49
- Requires-Dist: jinja2>=3.1.6; extra == "website"
50
40
  Dynamic: license-file
51
41
 
52
42
 
@@ -76,6 +66,8 @@ Github Repo: https://github.com/Breakthrough/PySceneDetect/
76
66
 
77
67
  Install: ``pip install --upgrade scenedetect`` (or ``scenedetect-headless`` for servers)
78
68
 
69
+ Packages: `scenedetect <https://pypi.org/project/scenedetect/>`_ (CLI + ``opencv-python``), `scenedetect-headless <https://pypi.org/project/scenedetect-headless/>`_ (CLI + ``opencv-python-headless``), and `scenedetect-core <https://pypi.org/project/scenedetect-core/>`_ (library only, minimal dependencies, bring your own OpenCV variant). All provide the same ``scenedetect`` module -- install only one.
70
+
79
71
  ----------------------------------------------------------
80
72
 
81
73
  **PySceneDetect** is a tool for detecting shot changes in videos, and can automatically split videos into separate clips. PySceneDetect is free and open-source software, and has several detection methods to find fast-cuts and threshold-based fades.
@@ -1,8 +1,10 @@
1
1
 
2
- ![PySceneDetect](https://raw.githubusercontent.com/Breakthrough/PySceneDetect/main/website/pages/img/pyscenedetect_logo_small.png)
3
- ==========================================================
4
- Video Cut Detection and Analysis Tool
5
- ----------------------------------------------------------
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/Breakthrough/PySceneDetect/main/website/pages/img/pyscenedetect_logo_small_darkmode.png">
4
+ <img alt="PySceneDetect" src="https://raw.githubusercontent.com/Breakthrough/PySceneDetect/main/website/pages/img/pyscenedetect_logo_small.png">
5
+ </picture>
6
+
7
+ # Video Cut Detection and Analysis Tool
6
8
 
7
9
  [![Build Status](https://img.shields.io/github/actions/workflow/status/Breakthrough/PySceneDetect/build.yml)](https://github.com/Breakthrough/PySceneDetect/actions)
8
10
  [![PyPI Status](https://img.shields.io/pypi/status/scenedetect.svg)](https://pypi.python.org/pypi/scenedetect/)
@@ -25,8 +27,7 @@ Video Cut Detection and Analysis Tool
25
27
 
26
28
  **Quick Install**:
27
29
 
28
- pip install scenedetect --upgrade # standard (depends on opencv-python)
29
- pip install scenedetect-headless --upgrade # headless servers (depends on opencv-python-headless)
30
+ pip install scenedetect --upgrade
30
31
 
31
32
  Requires ffmpeg/mkvmerge for video splitting support. Windows builds (MSI installer/portable ZIP) can be found on [the download page](https://scenedetect.com/download/).
32
33
 
@@ -114,7 +115,7 @@ We evaluate the performance of different detectors in terms of accuracy and proc
114
115
  Please submit any bugs/issues or feature requests to [the Issue Tracker](https://github.com/Breakthrough/PySceneDetect/issues). Before submission, ensure you search through existing issues (both open and closed) to avoid creating duplicate entries.
115
116
  Pull requests are welcome and encouraged. PySceneDetect is released under the BSD 3-Clause license, and submitted code should be compliant.
116
117
 
117
- For help or other issues, you can join [the official PySceneDetect Discord Server](https://discord.gg/H83HbJngk7), submit an issue/bug report [here on Github](https://github.com/Breakthrough/PySceneDetect/issues), or contact me via [my website](http://www.bcastell.com/about/).
118
+ For help or other issues, you can join [the official PySceneDetect Discord Server](https://discord.gg/H83HbJngk7), submit an issue/bug report [here on Github](https://github.com/Breakthrough/PySceneDetect/issues), or contact me via [my website](https://bcastell.com/about/).
118
119
 
119
120
  ## Code Signing
120
121
 
@@ -1,9 +1,9 @@
1
1
 
2
2
  .. _scenedetect-backends:
3
3
 
4
- ----------------------------------------
4
+ --------------
5
5
  Video Backends
6
- ----------------------------------------
6
+ --------------
7
7
 
8
8
  .. automodule:: scenedetect.backends
9
9
  :members:
@@ -16,3 +16,6 @@ Video Backends
16
16
 
17
17
  .. automodule:: scenedetect.backends.moviepy
18
18
  :members:
19
+
20
+ .. automodule:: scenedetect.backends.concat
21
+ :members:
@@ -0,0 +1,9 @@
1
+
2
+ .. _scenedetect-common:
3
+
4
+ ------
5
+ Common
6
+ ------
7
+
8
+ .. automodule:: scenedetect.common
9
+ :members:
@@ -0,0 +1,9 @@
1
+
2
+ .. _scenedetect-detector:
3
+
4
+ ------------------
5
+ Detector Interface
6
+ ------------------
7
+
8
+ .. automodule:: scenedetect.detector
9
+ :members:
@@ -0,0 +1,53 @@
1
+
2
+ .. _scenedetect-detectors:
3
+
4
+ ---------
5
+ Detectors
6
+ ---------
7
+
8
+ .. automodule:: scenedetect.detectors
9
+
10
+ AdaptiveDetector
11
+ ================
12
+
13
+ .. automodule:: scenedetect.detectors.adaptive_detector
14
+ :no-members:
15
+
16
+ .. autoclass:: scenedetect.detectors.adaptive_detector.AdaptiveDetector
17
+ :members:
18
+
19
+ ContentDetector
20
+ ===============
21
+
22
+ .. automodule:: scenedetect.detectors.content_detector
23
+ :no-members:
24
+
25
+ .. autoclass:: scenedetect.detectors.content_detector.ContentDetector
26
+ :members:
27
+
28
+ HashDetector
29
+ ============
30
+
31
+ .. automodule:: scenedetect.detectors.hash_detector
32
+ :no-members:
33
+
34
+ .. autoclass:: scenedetect.detectors.hash_detector.HashDetector
35
+ :members:
36
+
37
+ HistogramDetector
38
+ =================
39
+
40
+ .. automodule:: scenedetect.detectors.histogram_detector
41
+ :no-members:
42
+
43
+ .. autoclass:: scenedetect.detectors.histogram_detector.HistogramDetector
44
+ :members:
45
+
46
+ ThresholdDetector
47
+ =================
48
+
49
+ .. automodule:: scenedetect.detectors.threshold_detector
50
+ :no-members:
51
+
52
+ .. autoclass:: scenedetect.detectors.threshold_detector.ThresholdDetector
53
+ :members:
@@ -2,7 +2,7 @@
2
2
  .. _scenedetect-migration-guide:
3
3
 
4
4
  ***********************************************************************
5
- Migration Guide: v0.6 to v0.7
5
+ Migration Guide (v0.7)
6
6
  ***********************************************************************
7
7
 
8
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.
@@ -0,0 +1,9 @@
1
+
2
+ .. _scenedetect-output:
3
+
4
+ ------
5
+ Output
6
+ ------
7
+
8
+ .. automodule:: scenedetect.output
9
+ :members:
@@ -0,0 +1,9 @@
1
+
2
+ .. _scenedetect-platform:
3
+
4
+ ------------------
5
+ Platform & Logging
6
+ ------------------
7
+
8
+ .. automodule:: scenedetect.platform
9
+ :members:
@@ -0,0 +1,9 @@
1
+
2
+ .. _scenedetect-scene_manager:
3
+
4
+ -------------
5
+ Scene Manager
6
+ -------------
7
+
8
+ .. automodule:: scenedetect.scene_manager
9
+ :members:
@@ -0,0 +1,9 @@
1
+
2
+ .. _scenedetect-stats_manager:
3
+
4
+ -------------
5
+ Stats Manager
6
+ -------------
7
+
8
+ .. automodule:: scenedetect.stats_manager
9
+ :members:
@@ -0,0 +1,9 @@
1
+
2
+ .. _scenedetect-video_stream:
3
+
4
+ ----------------
5
+ Stream Interface
6
+ ----------------
7
+
8
+ .. automodule:: scenedetect.video_stream
9
+ :members:
@@ -9,15 +9,15 @@ The `scenedetect` API is easy to integrate with most application workflows, whil
9
9
 
10
10
  * :ref:`scenedetect.detectors 🕵️ <scenedetect-detectors>`: detection algorithms:
11
11
 
12
- * :mod:`AdaptiveDetector <scenedetect.detectors.adaptive_detector>` finds fast cuts using rolling average of HSL changes
12
+ * :class:`AdaptiveDetector <scenedetect.detectors.adaptive_detector.AdaptiveDetector>`: finds fast cuts using rolling average of HSL changes
13
13
 
14
- * :mod:`ContentDetector <scenedetect.detectors.content_detector>`: detects fast cuts using weighted average of HSV changes
14
+ * :class:`ContentDetector <scenedetect.detectors.content_detector.ContentDetector>`: detects fast cuts using weighted average of HSV changes
15
15
 
16
- * :mod:`ThresholdDetector <scenedetect.detectors.threshold_detector>`: finds fades in/out using average pixel intensity changes in RGB
16
+ * :class:`ThresholdDetector <scenedetect.detectors.threshold_detector.ThresholdDetector>`: finds fades in/out using average pixel intensity changes in RGB
17
17
 
18
- * :mod:`HistogramDetector <scenedetect.detectors.histogram_detector>` finds fast cuts using HSV histogram changes
18
+ * :class:`HistogramDetector <scenedetect.detectors.histogram_detector.HistogramDetector>`: finds fast cuts using HSV histogram changes
19
19
 
20
- * :mod:`HashDetector <scenedetect.detectors.hash_detector>`: finds fast cuts using perceptual image hashing
20
+ * :class:`HashDetector <scenedetect.detectors.hash_detector.HashDetector>`: finds fast cuts using perceptual image hashing
21
21
 
22
22
  * :ref:`scenedetect.output ✂️ <scenedetect-output>`: Output formats:
23
23
 
@@ -29,19 +29,21 @@ The `scenedetect` API is easy to integrate with most application workflows, whil
29
29
 
30
30
  * :ref:`scenedetect.backends 🎥 <scenedetect-backends>`: PySceneDetect supports multiple libraries as an input backend:
31
31
 
32
- * OpenCV: :class:`VideoStreamCv2 <scenedetect.backends.opencv.ideoStreamCv2>`
32
+ * OpenCV: :class:`VideoStreamCv2 <scenedetect.backends.opencv.VideoStreamCv2>`
33
33
 
34
34
  * PyAV: :class:`VideoStreamAv <scenedetect.backends.pyav.VideoStreamAv>`
35
35
 
36
36
  * MoviePy: :class:`VideoStreamMoviePy <scenedetect.backends.moviepy.VideoStreamMoviePy>`
37
37
 
38
+ * Multiple videos can be treated as a single continuous stream using :class:`VideoStreamConcat <scenedetect.backends.concat.VideoStreamConcat>` (e.g. ``open_video(["part1.mp4", "part2.mp4"])``)
39
+
38
40
  * :ref:`scenedetect.common ⏱️ <scenedetect-common>`: common functionality such as :class:`FrameTimecode <scenedetect.common.FrameTimecode>` for timecode handling
39
41
 
40
42
  * :ref:`scenedetect.scene_manager 🎞️ <scenedetect-scene_manager>`: the :class:`SceneManager <scenedetect.scene_manager.SceneManager>` coordinates performing scene detection on a video with one or more detectors
41
43
 
42
44
  * :ref:`scenedetect.detector 🌐 <scenedetect-detector>`: the interface (:class:`SceneDetector <scenedetect.detector.SceneDetector>`) that detectors must implement to be compatible with PySceneDetect
43
45
 
44
- * :ref:`scenedetect.video_stream <scenedetect-video_stream>`: the interface (:class:`VideoStream <scenedetect.video_stream.VideoStream>`) that detectors must implement to be compatible with PySceneDetect
46
+ * :ref:`scenedetect.video_stream 📹 <scenedetect-video_stream>`: the interface (:class:`VideoStream <scenedetect.video_stream.VideoStream>`) that video backends must implement to be compatible with PySceneDetect
45
47
 
46
48
  * :ref:`scenedetect.stats_manager 🧮 <scenedetect-stats_manager>`: the :class:`StatsManager <scenedetect.stats_manager.StatsManager>` allows you to store detection metrics for each frame and save them to CSV for further analysis
47
49
 
@@ -96,23 +98,6 @@ Functions
96
98
  .. automodule:: scenedetect
97
99
  :members:
98
100
 
99
- .. toctree::
100
- :maxdepth: 3
101
- :caption: PySceneDetect Module Documentation
102
- :name: fullapitoc
103
- :hidden:
104
-
105
- api/migration_guide
106
- api/detectors
107
- api/scene_manager
108
- api/common
109
- api/output
110
- api/backends
111
- api/stats_manager
112
- api/detector
113
- api/video_stream
114
- api/platform
115
-
116
101
 
117
102
  =======================================================================
118
103
  Logging
@@ -857,6 +857,10 @@ Options
857
857
 
858
858
  Split video using mkvmerge. Faster than re-encoding, but less precise. If set, options other than :option:`-f/--filename <-f>`, :option:`-q/--quiet <-q>` and :option:`-o/--output <-o>` will be ignored. Note that mkvmerge automatically appends the $SCENE_NUMBER suffix.
859
859
 
860
+ .. option:: --expand
861
+
862
+ Extend the first/last output clips to cover the full input video, even if the :ref:`time <command-time>` command's ``--start``/``--end`` limited the analysis window. Useful for keeping content outside the analyzed region attached to the adjacent split.
863
+
860
864
 
861
865
  .. _command-time:
862
866
 
@@ -45,6 +45,9 @@ autodoc_member_order = "groupwise"
45
45
  autodoc_typehints = "description"
46
46
  autodoc_typehints_format = "short"
47
47
 
48
+ add_module_names = False
49
+ python_use_unqualified_type_names = True
50
+
48
51
  # Add any paths that contain templates here, relative to this directory.
49
52
  templates_path = ["_templates"]
50
53
 
@@ -8,7 +8,7 @@ PySceneDetect Documentation
8
8
 
9
9
  Welcome to the PySceneDetect docs. The docs are split into two separate parts: one for the command-line interface (the `scenedetect` command) and another for the Python API (the `scenedetect` module).
10
10
 
11
- You can install the latest release of PySceneDetect by running `pip install scenedetect` (or `pip install scenedetect-headless` on servers without GUI libraries), or by downloading the Windows build from `scenedetect.com/download <http://www.scenedetect.com/download/>`_. PySceneDetect requires `ffmpeg` or `mkvmerge` for video splitting support.
11
+ You can install the latest release of PySceneDetect by running `pip install scenedetect` (or `pip install scenedetect-headless` on servers without GUI libraries), or by downloading the Windows build from `scenedetect.com/download <http://www.scenedetect.com/download/>`_. Library-only installs that need a specific OpenCV variant (e.g. `opencv-contrib-python`) can use `pip install scenedetect-core`, which has no CLI dependencies and lets you supply any OpenCV package. PySceneDetect requires `ffmpeg` or `mkvmerge` for video splitting support.
12
12
 
13
13
  .. note::
14
14
 
@@ -54,6 +54,7 @@ Table of Contents
54
54
  api/video_stream
55
55
  api/stats_manager
56
56
  api/platform
57
+ api/migration_guide
57
58
 
58
59
  =======================================================================
59
60
  Indices and Tables
@@ -25,6 +25,8 @@ Github Repo: https://github.com/Breakthrough/PySceneDetect/
25
25
 
26
26
  Install: ``pip install --upgrade scenedetect`` (or ``scenedetect-headless`` for servers)
27
27
 
28
+ Packages: `scenedetect <https://pypi.org/project/scenedetect/>`_ (CLI + ``opencv-python``), `scenedetect-headless <https://pypi.org/project/scenedetect-headless/>`_ (CLI + ``opencv-python-headless``), and `scenedetect-core <https://pypi.org/project/scenedetect-core/>`_ (library only, minimal dependencies, bring your own OpenCV variant). All provide the same ``scenedetect`` module -- install only one.
29
+
28
30
  ----------------------------------------------------------
29
31
 
30
32
  **PySceneDetect** is a tool for detecting shot changes in videos, and can automatically split videos into separate clips. PySceneDetect is free and open-source software, and has several detection methods to find fast-cuts and threshold-based fades.
@@ -0,0 +1,81 @@
1
+ #
2
+ # PySceneDetect: Python-Based Video Scene Detector
3
+ # ---------------------------------------------------------------
4
+ # [ Site: http://www.bcastell.com/projects/PySceneDetect/ ]
5
+ # [ Github: https://github.com/Breakthrough/PySceneDetect/ ]
6
+ # [ Documentation: http://www.scenedetect.com/docs/ ]
7
+ #
8
+ # Copyright (C) 2014 Brandon Castellano <http://www.bcastell.com>.
9
+ #
10
+ # pyproject.toml for the `scenedetect` package: the same code as scenedetect-core,
11
+ # but bundling the opencv-python (GUI-capable) OpenCV variant, the CLI dependencies,
12
+ # and the `scenedetect` console script. packaging/build_all.py temporarily swaps
13
+ # this file into the repo root and builds from there, so the code, readme, and
14
+ # dynamic version are shared with the other variants.
15
+ #
16
+ # Keep [project] metadata (classifiers, requires-python, etc.) in sync with the
17
+ # root pyproject.toml and pyproject-scenedetect-headless.toml. Only the name,
18
+ # description, dependencies, extras, and console script differ between variants.
19
+
20
+ [build-system]
21
+ requires = ["setuptools>=77"]
22
+ build-backend = "setuptools.build_meta"
23
+
24
+ [project]
25
+ name = "scenedetect"
26
+ dynamic = ["version"]
27
+ description = "Video scene cut/shot detection program and Python library (bundles the opencv-python OpenCV variant and the scenedetect CLI)."
28
+ readme = { file = "packaging/package-info.rst", content-type = "text/x-rst" }
29
+ license = "BSD-3-Clause"
30
+ license-files = ["LICENSE"]
31
+ requires-python = ">=3.10"
32
+ authors = [{ name = "Brandon Castellano", email = "brandon248@gmail.com" }]
33
+ keywords = ["video", "computer-vision", "analysis"]
34
+ classifiers = [
35
+ "Development Status :: 5 - Production/Stable",
36
+ "Environment :: Console",
37
+ "Environment :: Console :: Curses",
38
+ "Intended Audience :: Developers",
39
+ "Intended Audience :: End Users/Desktop",
40
+ "Intended Audience :: System Administrators",
41
+ "Operating System :: OS Independent",
42
+ "Programming Language :: Python :: 3",
43
+ "Programming Language :: Python :: 3.10",
44
+ "Programming Language :: Python :: 3.11",
45
+ "Programming Language :: Python :: 3.12",
46
+ "Programming Language :: Python :: 3.13",
47
+ "Topic :: Multimedia :: Video",
48
+ "Topic :: Multimedia :: Video :: Conversion",
49
+ "Topic :: Multimedia :: Video :: Non-Linear Editor",
50
+ "Topic :: Utilities",
51
+ ]
52
+ dependencies = [
53
+ # click 8.3.0 specifically is excluded per https://scenedetect.com/issues/521; 8.3.1+ are fine.
54
+ "click~=8.0,!=8.3.0",
55
+ "numpy",
56
+ "opencv-python",
57
+ "platformdirs",
58
+ "tqdm",
59
+ ]
60
+
61
+ [project.optional-dependencies]
62
+ pyav = ["av>=9.2"]
63
+ moviepy = ["moviepy"]
64
+
65
+ [project.urls]
66
+ Homepage = "https://www.scenedetect.com"
67
+ Documentation = "https://www.scenedetect.com/docs/"
68
+ Source = "https://github.com/Breakthrough/PySceneDetect"
69
+ Issues = "https://github.com/Breakthrough/PySceneDetect/issues"
70
+
71
+ [project.scripts]
72
+ scenedetect = "scenedetect.__main__:main"
73
+
74
+ [tool.setuptools]
75
+ include-package-data = true
76
+
77
+ [tool.setuptools.packages.find]
78
+ include = ["scenedetect*"]
79
+
80
+ [tool.setuptools.dynamic]
81
+ version = { attr = "scenedetect.__version__" }
@@ -69,20 +69,22 @@ from scenedetect.backends import (
69
69
  VideoStreamAv,
70
70
  VideoStreamMoviePy,
71
71
  VideoCaptureAdapter,
72
+ VideoStreamConcat,
73
+ SourceSpan,
72
74
  )
73
75
  from scenedetect.stats_manager import StatsManager, StatsFileCorrupt
74
76
  from scenedetect.scene_manager import SceneManager
75
77
 
76
78
  # Used for module identification and when printing version & about info
77
79
  # (e.g. calling `scenedetect version` or `scenedetect about`).
78
- __version__ = "0.7"
80
+ __version__ = "0.7.1-dev0"
79
81
 
80
82
  init_logger()
81
83
  logger = getLogger("pyscenedetect")
82
84
 
83
85
 
84
86
  def open_video(
85
- path: StrPath,
87
+ path: "StrPath | list[StrPath] | tuple[StrPath, ...]",
86
88
  frame_rate: FrameRate | None = None,
87
89
  backend: str = "opencv",
88
90
  framerate: float | None = None,
@@ -92,7 +94,9 @@ def open_video(
92
94
  system, OpenCV (`VideoStreamCv2`) will be used as a fallback.
93
95
 
94
96
  Arguments:
95
- path: Path to video file to open.
97
+ path: Path to video file to open. May also be a list of paths, in which case the videos
98
+ are concatenated and treated as a single continuous stream
99
+ (see :class:`VideoStreamConcat <scenedetect.backends.concat.VideoStreamConcat>`).
96
100
  frame_rate: Overrides detected frame rate if set. Takes precedence over `framerate`.
97
101
  backend: Name of specific backend to use, if possible. See
98
102
  :data:`scenedetect.backends.AVAILABLE_BACKENDS` for backends available on the current
@@ -113,6 +117,10 @@ def open_video(
113
117
  # used, once internal callers and downstream users have had a release to migrate.
114
118
  if frame_rate is None:
115
119
  frame_rate = framerate
120
+ # A list of paths is opened as a single concatenated stream. VideoStreamConcat handles
121
+ # backend selection/fallback internally, so this must come before the lookup below.
122
+ if isinstance(path, (list, tuple)):
123
+ return VideoStreamConcat(path, frame_rate, backend=backend, **kwargs)
116
124
  last_error: Exception | None = None
117
125
  # If `backend` is available, try to open the video at `path` using it.
118
126
  if backend in AVAILABLE_BACKENDS:
@@ -142,18 +150,21 @@ def open_video(
142
150
 
143
151
 
144
152
  def detect(
145
- video_path: StrPath,
153
+ video_path: "StrPath | list[StrPath] | tuple[StrPath, ...]",
146
154
  detector: SceneDetector,
147
155
  stats_file_path: StrPath | None = None,
148
156
  show_progress: bool = False,
149
157
  start_time: TimecodeLike | None = None,
150
158
  end_time: TimecodeLike | None = None,
151
159
  start_in_scene: bool = False,
160
+ backend: str = "opencv",
152
161
  ) -> SceneList:
153
162
  """Perform scene detection on a given video `path` using the specified `detector`.
154
163
 
155
164
  Arguments:
156
- video_path: Path to input video (absolute or relative to working directory).
165
+ video_path: Path to input video (absolute or relative to working directory). May also
166
+ be a list of paths, in which case the videos are concatenated and treated as a
167
+ single continuous stream.
157
168
  detector: A `SceneDetector` instance (see :mod:`scenedetect.detectors` for a full list
158
169
  of detectors).
159
170
  stats_file_path: Path to save per-frame metrics to for statistical analysis or to
@@ -168,6 +179,10 @@ def detect(
168
179
  will contain a single scene spanning the entire video (instead of no scenes).
169
180
  When detecting fades with `ThresholdDetector`, the beginning portion of the video
170
181
  will always be included until the first fade-out event is detected.
182
+ backend: Name of the backend to use for video decoding. See
183
+ :data:`scenedetect.backends.AVAILABLE_BACKENDS` for backends available on the
184
+ current system. Defaults to OpenCV; falls back to OpenCV if the requested backend
185
+ is unavailable or fails to open the video.
171
186
 
172
187
  Returns:
173
188
  List of scenes as pairs of (start, end) :class:`FrameTimecode` objects.
@@ -178,7 +193,7 @@ def detect(
178
193
  ValueError: `start_time` or `end_time` are incorrectly formatted.
179
194
  TypeError: `start_time` or `end_time` are invalid types.
180
195
  """
181
- video = open_video(video_path)
196
+ video = open_video(video_path, backend=backend)
182
197
  if start_time is not None:
183
198
  video.seek(FrameTimecode(start_time, video.frame_rate))
184
199
  end_timecode = FrameTimecode(end_time, video.frame_rate) if end_time is not None else None
@@ -1294,6 +1294,15 @@ Customized filenames:
1294
1294
  USER_CONFIG.get_help_string("split-video", "mkvmerge")
1295
1295
  ),
1296
1296
  )
1297
+ @click.option(
1298
+ "--expand",
1299
+ is_flag=True,
1300
+ flag_value=True,
1301
+ default=False,
1302
+ help="Extend the first/last output clips to cover the full input video, even if `time -s/-e` limited the analysis window. Useful for keeping content outside the analyzed region attached to the adjacent split.{}".format(
1303
+ USER_CONFIG.get_help_string("split-video", "expand")
1304
+ ),
1305
+ )
1297
1306
  @click.pass_context
1298
1307
  def split_video_command(
1299
1308
  ctx: click.Context,
@@ -1306,6 +1315,7 @@ def split_video_command(
1306
1315
  preset: str | None,
1307
1316
  args: str | None,
1308
1317
  mkvmerge: bool,
1318
+ expand: bool,
1309
1319
  ):
1310
1320
  ctx = ctx.obj
1311
1321
  assert isinstance(ctx, CliContext)
@@ -1372,6 +1382,7 @@ def split_video_command(
1372
1382
  "output": ctx.config.get_value("split-video", "output", output),
1373
1383
  "show_output": not ctx.config.get_value("split-video", "quiet", quiet),
1374
1384
  "ffmpeg_args": args,
1385
+ "expand": ctx.config.get_value("split-video", "expand", expand),
1375
1386
  }
1376
1387
  ctx.add_command(cli_commands.split_video, split_video_args)
1377
1388
 
@@ -37,6 +37,7 @@ from scenedetect.scene_manager import (
37
37
  CutList,
38
38
  Interpolation,
39
39
  SceneList,
40
+ expand_scenes_to_bounds,
40
41
  )
41
42
 
42
43
  logger = logging.getLogger("pyscenedetect")
@@ -216,11 +217,23 @@ def split_video(
216
217
  output: str,
217
218
  show_output: bool,
218
219
  ffmpeg_args: str,
220
+ expand: bool,
219
221
  ):
220
222
  """Handles the `split-video` command."""
221
223
  del cuts # split-video only uses scenes.
222
224
  assert context.video_stream is not None
223
225
 
226
+ if expand and scenes:
227
+ video_duration = context.video_stream.duration
228
+ if video_duration is None:
229
+ logger.warning("Cannot --expand: video duration is unavailable for this stream.")
230
+ else:
231
+ scenes = expand_scenes_to_bounds(
232
+ scenes,
233
+ start=context.video_stream.base_timecode,
234
+ end=video_duration,
235
+ )
236
+
224
237
  if use_mkvmerge:
225
238
  name_format = name_format.removesuffix("-$SCENE_NUMBER")
226
239
 
@@ -468,6 +468,7 @@ CONFIG_MAP: ConfigDict = {
468
468
  "split-video": {
469
469
  "args": _DEFAULT_FFMPEG_ARGS,
470
470
  "copy": False,
471
+ "expand": False,
471
472
  "filename": "$VIDEO_NAME-Scene-$SCENE_NUMBER",
472
473
  "high-quality": False,
473
474
  "mkvmerge": False,
@@ -50,6 +50,14 @@ Lastly, to use a specific backend directly:
50
50
  In both examples above, the resulting ``video`` can be used with
51
51
  :meth:`SceneManager.detect_scenes() <scenedetect.scene_manager.SceneManager.detect_scenes>`.
52
52
 
53
+ Multiple videos can be opened as one continuous stream by passing a list of paths to
54
+ :func:`open_video`, which returns a
55
+ :class:`VideoStreamConcat <scenedetect.backends.concat.VideoStreamConcat>`:
56
+
57
+ .. code:: python
58
+
59
+ video = open_video(["part1.mp4", "part2.mp4"])
60
+
53
61
  ===============================================================
54
62
  Devices / Cameras / Pipes
55
63
  ===============================================================
@@ -84,6 +92,7 @@ examples for details.
84
92
  # - Nvidia VPF: https://developer.nvidia.com/blog/vpf-hardware-accelerated-video-processing-framework-in-python/
85
93
 
86
94
  # OpenCV must be available at minimum.
95
+ from scenedetect.backends.concat import SourceSpan, VideoStreamConcat
87
96
  from scenedetect.backends.opencv import VideoCaptureAdapter, VideoStreamCv2
88
97
 
89
98
  try: