You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PySceneDetect 0.7 is a major breaking release which overhauls how timestamps are handled. This allows PySceneDetect to properly process variable framerate (VFR) videos. A significant amount of technical debt has been addressed, including removal of deprecated or overly complicated APIs.
Care was taken to minimize changes for most common API uses, however more advanced use cases may run into breaking changes. Please review the Migration Guide when updating from v0.6. Minimum supported Python version is now Python 3.10.
CLI Changes
[feature] VFR videos are handled correctly by the OpenCV and PyAV backends, and should work correctly with default parameters
[feature] All CLI options which used to accept frame numbers only now accept seconds (e.g. 0.6s) and timecodes (e.g. 00:00:00.600) #531
[feature] New save-fcp command allows exporting in Final Cut Pro format (FCP7/FCPX) #156
[feature] New save-qp command writes a QP file with scene boundary frame numbers, suitable for forcing keyframes at scene cuts in x264/x265 #448
[feature] New save-html command replaces the deprecated export-html; the prior command remains as an alias and emits a deprecation warning #518
[feature] Add save-edl option --start-timecode/-s to providde a custom start timecode for generated EDLs, supports SMPTE HH:MM:SS:FF or 8-digit HHMMSSFF input #515
[bugfix] Fix floating-point precision error in save-otio output where frame values near integer boundaries (e.g. 90.00000000000001) were serialized with spurious precision
[bugfix] Add mitigation for transient OSError in the MoviePy backend as it is susceptible to subprocess pipe races on slow or heavily loaded systems #496
[feature] The MoviePy backend now supports overriding the source frame rate via -f/--frame-rate (and the VideoStreamMoviePy(frame_rate=...) API), bringing it in line with the OpenCV and PyAV backends
[bugfix] detect-threshold cut frame numbers are now backend-deterministic; previously the cut could differ by 1 frame between PyAV and OpenCV when the fade midpoint landed on a .5 rounding boundary (PyAV uses sub-microsecond PTS, OpenCV uses millisecond-truncated CAP_PROP_POS_MSEC)
[breaking] Rename -f/--framerate to -f/--frame-rate as part of VFR overhaul (legacy --framerate form is preserved as a hidden alias but will be removed in v0.8)
[general] Support SCENEDETECT_DEBUG environment variable to control how exceptions and debugging are handled. Unhandled exceptions and Ctrl+C now produce a logger-formatted error message and exit cleanly with code 1 instead of dumping a raw Python traceback. Set SCENEDETECT_DEBUG=1 to ensure all exceptions are re-raised instead of being logged. In both cases, the program will exit with a non-zero exit code.
API Changes
VFR & Timestamp Overhaul:
Add write_scene_list_edl, write_scene_list_fcpx, write_scene_list_fcp7, and write_scene_list_otio to the scenedetect.output module so save-edl, save-fcp, and save-otio can be invoked directly from Python (previously CLI-only)
write_scene_list_edl accepts an optional start_timecode parameter (SMPTE HH:MM:SS:FF or 8-digit HHMMSSFF) that is added to every event's source and record columns #515
Add new Timecode type to represent frame timings in terms of the video's source timebase
Add time_base and pts properties to FrameTimecode for more accurate timing information
All backends (PyAV, OpenCV, MoviePy) now return PTS-backed timestamps from VideoStream.position
VideoStream.frame_rate now returns Fraction instead of float
Framerates are now stored as rational Fraction values (e.g. Fraction(24000, 1001) instead of 23.976) to avoid float precision loss
Common NTSC rates (23.976, 29.97, 59.94) are automatically detected from float values
FrameTimecode.frame_num is now approximate for VFR video (based on PTS-derived time)
Add frame_rate property (returns exact Fraction) as the canonical replacement for framerate (returns float) in FrameTimecode and VideoStream
For CFR sources, both properties represent the same rate, i.e. time_base equals 1 / frame_rate for CFR sources #548
Add frame_rate keyword argument to open_video() and the VideoStreamCv2, VideoCaptureAdapter, VideoStreamAv, and VideoStreamMoviePy constructors as the canonical replacement for framerate#548; accepts float | Fraction | None. The legacy framerate keyword is retained as a deprecated alias and is ignored when frame_rate is provided
Add equal_frame_rate(other) method as the canonical replacement for equal_framerate(fps)
General:
Type hints: audit and overhaul: first-party code is now clean with Pyright basic mode, migrated deprecated type hints to comply with PEP 585
Packaging: modernized to comply with PEP 621, make opencv-python a requirement, add separate scenedetect-headless variant instead
Detector Interface:
Replace frame_num parameter (int) with timecode (FrameTimecode) in SceneDetector interface #168:
The detector interface: SceneDetector.process_frame() and SceneDetector.post_process() (the post_process signature on the abstract base is now consistently typed as FrameTimecode to match its concrete-detector overrides; the prior int annotation did not reflect the actual runtime value)
Statistics: StatsManager.get_metrics(), StatsManager.set_metrics(), and StatsManager.metrics_exist() formally accept either FrameTimecode or int (the int form is retained for compatibility with the deprecated load_from_csv() path, which keys metrics by integer frame number)
StatsManager.load_from_csv() and save_images()output_dir now accept os.PathLike (e.g. pathlib.Path) in addition to str
SceneManager.detect_scenes()duration and end_time formally accept int (frames), float (seconds), str (timecode), or FrameTimecode - matching the documented and runtime-supported behavior
Remove SceneDetector.stats_manager_required property, no longer required
Remove deprecated SparseSceneDetector interface
Detector min_scene_len and save_images()frame_margin arguments now accept seconds (float) and timecode strings (e.g. "0.6s", "00:00:00.600") in addition to a frame count (int); these are evaluated using the source video's timing for correct behavior on VFR videos #531
Module Reorganization:
scenedetect.scene_detector moved to scenedetect.detector
scenedetect.frame_timecode moved to scenedetect.common
Image/HTML/CSV export in scenedetect.scene_manager moved to scenedetect.output#463
scenedetect.video_splitter moved to scenedetect.output.video#463
FrameTimecode:
Add properties to access frame_num, frame_rate, and seconds instead of getter methods
frame_num and frame_rate are now read-only properties (construct a new FrameTimecode to change them)
Remove FrameTimecode.previous_frame() method
Deprecated functionality preserved from v0.6 now uses the warnings module to emit runtime deprecation warnings, these features will be removed in v0.8
Soft-deprecate framerate property and equal_framerate() method via docstring; the legacy forms will continue to work until v0.8 when they will be upgraded to DeprecationWarning before removal in v0.9
[general] Reduced size of Windows distribution without affecting functionality
[bugfix] Pressing Ctrl+C during scene detection in the bundled distribution now exits cleanly instead of surfacing the PyInstaller bootloader traceback
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Release Notes
PySceneDetect 0.7 is a major breaking release which overhauls how timestamps are handled. This allows PySceneDetect to properly process variable framerate (VFR) videos. A significant amount of technical debt has been addressed, including removal of deprecated or overly complicated APIs.
Care was taken to minimize changes for most common API uses, however more advanced use cases may run into breaking changes. Please review the Migration Guide when updating from v0.6. Minimum supported Python version is now Python 3.10.
CLI Changes
0.6s) and timecodes (e.g.00:00:00.600) #531save-fcpcommand allows exporting in Final Cut Pro format (FCP7/FCPX) #156save-qpcommand writes a QP file with scene boundary frame numbers, suitable for forcing keyframes at scene cuts in x264/x265 #448save-htmlcommand replaces the deprecatedexport-html; the prior command remains as an alias and emits a deprecation warning #518save-edloption--start-timecode/-sto providde a custom start timecode for generated EDLs, supports SMPTEHH:MM:SS:FFor 8-digitHHMMSSFFinput #515save-otiooutput where frame values near integer boundaries (e.g.90.00000000000001) were serialized with spurious precisionOSErrorin the MoviePy backend as it is susceptible to subprocess pipe races on slow or heavily loaded systems #496-f/--frame-rate(and theVideoStreamMoviePy(frame_rate=...)API), bringing it in line with the OpenCV and PyAV backendsdetect-thresholdcut frame numbers are now backend-deterministic; previously the cut could differ by 1 frame between PyAV and OpenCV when the fade midpoint landed on a.5rounding boundary (PyAV uses sub-microsecond PTS, OpenCV uses millisecond-truncatedCAP_PROP_POS_MSEC)-d/--min-delta-hsvoption fromdetect-adaptivecommand (use-c/--min-content-valinstead)-f/--framerateto-f/--frame-rateas part of VFR overhaul (legacy--framerateform is preserved as a hidden alias but will be removed in v0.8)SCENEDETECT_DEBUGenvironment variable to control how exceptions and debugging are handled. Unhandled exceptions andCtrl+Cnow produce a logger-formatted error message and exit cleanly with code 1 instead of dumping a raw Python traceback. SetSCENEDETECT_DEBUG=1to ensure all exceptions are re-raised instead of being logged. In both cases, the program will exit with a non-zero exit code.API Changes
VFR & Timestamp Overhaul:
write_scene_list_edl,write_scene_list_fcpx,write_scene_list_fcp7, andwrite_scene_list_otioto thescenedetect.outputmodule sosave-edl,save-fcp, andsave-otiocan be invoked directly from Python (previously CLI-only)write_scene_list_edlaccepts an optionalstart_timecodeparameter (SMPTEHH:MM:SS:FFor 8-digitHHMMSSFF) that is added to every event's source and record columns #515Timecodetype to represent frame timings in terms of the video's source timebasetime_baseandptsproperties toFrameTimecodefor more accurate timing informationVideoStream.positionVideoStream.frame_ratenow returnsFractioninstead offloatFractionvalues (e.g.Fraction(24000, 1001)instead of23.976) to avoid float precision lossFrameTimecode.frame_numis now approximate for VFR video (based on PTS-derived time)frame_rateproperty (returns exactFraction) as the canonical replacement forframerate(returnsfloat) inFrameTimecodeandVideoStreamtime_baseequals1 / frame_ratefor CFR sources #548frame_ratekeyword argument toopen_video()and theVideoStreamCv2,VideoCaptureAdapter,VideoStreamAv, andVideoStreamMoviePyconstructors as the canonical replacement forframerate#548; acceptsfloat | Fraction | None. The legacyframeratekeyword is retained as a deprecated alias and is ignored whenframe_rateis providedequal_frame_rate(other)method as the canonical replacement forequal_framerate(fps)General:
opencv-pythona requirement, add separatescenedetect-headlessvariant insteadDetector Interface:
frame_numparameter (int) withtimecode(FrameTimecode) inSceneDetectorinterface #168:SceneDetector.process_frame()andSceneDetector.post_process()(thepost_processsignature on the abstract base is now consistently typed asFrameTimecodeto match its concrete-detector overrides; the priorintannotation did not reflect the actual runtime value)StatsManager.get_metrics(),StatsManager.set_metrics(), andStatsManager.metrics_exist()formally accept eitherFrameTimecodeorint(theintform is retained for compatibility with the deprecatedload_from_csv()path, which keys metrics by integer frame number)StatsManager.load_from_csv()andsave_images()output_dirnow acceptos.PathLike(e.g.pathlib.Path) in addition tostrSceneManager.detect_scenes()durationandend_timeformally acceptint(frames),float(seconds),str(timecode), orFrameTimecode- matching the documented and runtime-supported behaviorSceneDetectoris now a Python abstract classSceneDetectorinstances can now assume they always have frame data to process whenprocess_frameis calledSceneDetector.is_processing_required()methodSceneDetector.stats_manager_requiredproperty, no longer requiredSparseSceneDetectorinterfacemin_scene_lenandsave_images()frame_marginarguments now accept seconds (float) and timecode strings (e.g."0.6s","00:00:00.600") in addition to a frame count (int); these are evaluated using the source video's timing for correct behavior on VFR videos #531Module Reorganization:
scenedetect.scene_detectormoved toscenedetect.detectorscenedetect.frame_timecodemoved toscenedetect.commonscenedetect.scene_managermoved toscenedetect.output#463scenedetect.video_splittermoved toscenedetect.output.video#463FrameTimecode:
frame_num,frame_rate, andsecondsinstead of getter methodsframe_numandframe_rateare now read-only properties (construct a newFrameTimecodeto change them)FrameTimecode.previous_frame()methodwarningsmodule to emit runtime deprecation warnings, these features will be removed in v0.8framerateproperty andequal_framerate()method via docstring; the legacy forms will continue to work until v0.8 when they will be upgraded toDeprecationWarningbefore removal in v0.9Removals:
scenedetect.video_manager, use thescenedetect.open_video()function insteadbase_timecodeandvideo_managerfrom various functionsSceneManager.get_event_list()methodAdaptiveDetector.get_content_val()method (useStatsManagerinstead)AdaptiveDetectorconstructor argmin_delta_hsv(usemin_content_valinstead)advanceparameter fromVideoStream.read()SceneDetector.stats_manager_requiredproperty, no longer requiredSceneDetectoris now a Python abstract classWindows Distribution
Ctrl+Cduring scene detection in the bundled distribution now exits cleanly instead of surfacing the PyInstaller bootloader tracebackThis discussion was created from the release PySceneDetect v0.7.
All reactions