From 0514dfe146810ad1ecaacd4e07fd3e9c3bc5f491 Mon Sep 17 00:00:00 2001 From: Sara Veldhoen Date: Fri, 26 Apr 2024 16:47:05 +0200 Subject: [PATCH 01/11] Added TIMESTAMP_MS to file_path substitutions --- scenedetect/scene_manager.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scenedetect/scene_manager.py b/scenedetect/scene_manager.py index 3d3bd435..ae6a236e 100644 --- a/scenedetect/scene_manager.py +++ b/scenedetect/scene_manager.py @@ -493,7 +493,10 @@ def save_images(scene_list: List[Tuple[FrameTimecode, FrameTimecode]], VIDEO_NAME=video.name, SCENE_NUMBER=scene_num_format % (i + 1), IMAGE_NUMBER=image_num_format % (j + 1), - FRAME_NUMBER=image_timecode.get_frames()), image_extension) + FRAME_NUMBER=image_timecode.get_frames(), + FRAME_TIMESTAMP_MS=int(image_timecode.get_seconds()*1000)), + image_extension, + ) image_filenames[i].append(file_path) # TODO: Combine this resize with the ones below. if aspect_ratio is not None: From c208a736058706c0e5a2dec4d3c2655be2c2227c Mon Sep 17 00:00:00 2001 From: Sara Veldhoen Date: Fri, 26 Apr 2024 17:05:15 +0200 Subject: [PATCH 02/11] Added $TIMESTAMP to image_name_template in test --- tests/test_scene_manager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_scene_manager.py b/tests/test_scene_manager.py index 20ef4677..05ab03c7 100644 --- a/tests/test_scene_manager.py +++ b/tests/test_scene_manager.py @@ -94,7 +94,8 @@ def test_save_images(test_video_file): sm.add_detector(ContentDetector()) image_name_glob = 'scenedetect.tempfile.*.jpg' - image_name_template = 'scenedetect.tempfile.$SCENE_NUMBER.$IMAGE_NUMBER' + image_name_template = 'scenedetect.tempfile.$SCENE_NUMBER\ + .$IMAGE_NUMBER.$TIMESTAMP_MS' try: video_fps = video.frame_rate From cc2cae3610c359dad88210d8ce9689bae454dbf8 Mon Sep 17 00:00:00 2001 From: Sara Veldhoen Date: Fri, 26 Apr 2024 17:07:18 +0200 Subject: [PATCH 03/11] Improved variable name --- scenedetect/scene_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scenedetect/scene_manager.py b/scenedetect/scene_manager.py index ae6a236e..96af9f4b 100644 --- a/scenedetect/scene_manager.py +++ b/scenedetect/scene_manager.py @@ -494,7 +494,7 @@ def save_images(scene_list: List[Tuple[FrameTimecode, FrameTimecode]], SCENE_NUMBER=scene_num_format % (i + 1), IMAGE_NUMBER=image_num_format % (j + 1), FRAME_NUMBER=image_timecode.get_frames(), - FRAME_TIMESTAMP_MS=int(image_timecode.get_seconds()*1000)), + TIMESTAMP_MS=int(image_timecode.get_seconds()*1000)), image_extension, ) image_filenames[i].append(file_path) From 384e7f257acf16c8c268b59b9ec093d9d5474497 Mon Sep 17 00:00:00 2001 From: Sara Veldhoen Date: Tue, 30 Apr 2024 10:01:40 +0200 Subject: [PATCH 04/11] Added $TIMECODE to image name template options (also added $FRAME_NUMBER to test) --- scenedetect/scene_manager.py | 16 +++++++++------- tests/test_scene_manager.py | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/scenedetect/scene_manager.py b/scenedetect/scene_manager.py index 96af9f4b..bda97686 100644 --- a/scenedetect/scene_manager.py +++ b/scenedetect/scene_manager.py @@ -489,14 +489,16 @@ def save_images(scene_list: List[Tuple[FrameTimecode, FrameTimecode]], frame_im = video.read() if frame_im is not None: # TODO: Allow NUM to be a valid suffix in addition to NUMBER. - file_path = '%s.%s' % (filename_template.safe_substitute( - VIDEO_NAME=video.name, - SCENE_NUMBER=scene_num_format % (i + 1), - IMAGE_NUMBER=image_num_format % (j + 1), - FRAME_NUMBER=image_timecode.get_frames(), - TIMESTAMP_MS=int(image_timecode.get_seconds()*1000)), + file_path = '%s.%s' % ( + filename_template.safe_substitute( + VIDEO_NAME=video.name, + SCENE_NUMBER=scene_num_format % (i + 1), + IMAGE_NUMBER=image_num_format % (j + 1), + FRAME_NUMBER=image_timecode.get_frames(), + TIMESTAMP_MS=int(image_timecode.get_seconds() * 1000), + TIMECODE=image_timecode.get_timecode()), image_extension, - ) + ) image_filenames[i].append(file_path) # TODO: Combine this resize with the ones below. if aspect_ratio is not None: diff --git a/tests/test_scene_manager.py b/tests/test_scene_manager.py index 05ab03c7..0779ae2d 100644 --- a/tests/test_scene_manager.py +++ b/tests/test_scene_manager.py @@ -95,7 +95,7 @@ def test_save_images(test_video_file): image_name_glob = 'scenedetect.tempfile.*.jpg' image_name_template = 'scenedetect.tempfile.$SCENE_NUMBER\ - .$IMAGE_NUMBER.$TIMESTAMP_MS' + .$IMAGE_NUMBER.$FRAME_NUMBER.$TIMESTAMP_MS.$TIMECODE' try: video_fps = video.frame_rate From 7bfcb82dda44021ccacff8576794705241806d00 Mon Sep 17 00:00:00 2001 From: Sara Veldhoen Date: Fri, 26 Apr 2024 16:47:05 +0200 Subject: [PATCH 05/11] Added TIMESTAMP_MS to file_path substitutions --- scenedetect/scene_manager.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scenedetect/scene_manager.py b/scenedetect/scene_manager.py index df7251c4..9251e8f1 100644 --- a/scenedetect/scene_manager.py +++ b/scenedetect/scene_manager.py @@ -493,7 +493,10 @@ def save_images(scene_list: List[Tuple[FrameTimecode, FrameTimecode]], VIDEO_NAME=video.name, SCENE_NUMBER=scene_num_format % (i + 1), IMAGE_NUMBER=image_num_format % (j + 1), - FRAME_NUMBER=image_timecode.get_frames()), image_extension) + FRAME_NUMBER=image_timecode.get_frames(), + FRAME_TIMESTAMP_MS=int(image_timecode.get_seconds()*1000)), + image_extension, + ) image_filenames[i].append(file_path) # TODO: Combine this resize with the ones below. if aspect_ratio is not None: From fa22f320e3ed195bbc15da21ae905c7be6d5c302 Mon Sep 17 00:00:00 2001 From: Sara Veldhoen Date: Fri, 26 Apr 2024 17:05:15 +0200 Subject: [PATCH 06/11] Added $TIMESTAMP to image_name_template in test --- tests/test_scene_manager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_scene_manager.py b/tests/test_scene_manager.py index 20ef4677..05ab03c7 100644 --- a/tests/test_scene_manager.py +++ b/tests/test_scene_manager.py @@ -94,7 +94,8 @@ def test_save_images(test_video_file): sm.add_detector(ContentDetector()) image_name_glob = 'scenedetect.tempfile.*.jpg' - image_name_template = 'scenedetect.tempfile.$SCENE_NUMBER.$IMAGE_NUMBER' + image_name_template = 'scenedetect.tempfile.$SCENE_NUMBER\ + .$IMAGE_NUMBER.$TIMESTAMP_MS' try: video_fps = video.frame_rate From abbc8479da43693d482b566ca4535455a53724a5 Mon Sep 17 00:00:00 2001 From: Sara Veldhoen Date: Fri, 26 Apr 2024 17:07:18 +0200 Subject: [PATCH 07/11] Improved variable name --- scenedetect/scene_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scenedetect/scene_manager.py b/scenedetect/scene_manager.py index 9251e8f1..3b5f4870 100644 --- a/scenedetect/scene_manager.py +++ b/scenedetect/scene_manager.py @@ -494,7 +494,7 @@ def save_images(scene_list: List[Tuple[FrameTimecode, FrameTimecode]], SCENE_NUMBER=scene_num_format % (i + 1), IMAGE_NUMBER=image_num_format % (j + 1), FRAME_NUMBER=image_timecode.get_frames(), - FRAME_TIMESTAMP_MS=int(image_timecode.get_seconds()*1000)), + TIMESTAMP_MS=int(image_timecode.get_seconds()*1000)), image_extension, ) image_filenames[i].append(file_path) From ee96123b1e3e2d516e23ae8d40484a83bcc09035 Mon Sep 17 00:00:00 2001 From: Sara Veldhoen Date: Tue, 30 Apr 2024 10:01:40 +0200 Subject: [PATCH 08/11] Added $TIMECODE to image name template options (also added $FRAME_NUMBER to test) --- scenedetect/scene_manager.py | 16 +++++++++------- tests/test_scene_manager.py | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/scenedetect/scene_manager.py b/scenedetect/scene_manager.py index 3b5f4870..b6eed1e6 100644 --- a/scenedetect/scene_manager.py +++ b/scenedetect/scene_manager.py @@ -489,14 +489,16 @@ def save_images(scene_list: List[Tuple[FrameTimecode, FrameTimecode]], frame_im = video.read() if frame_im is not None: # TODO: Allow NUM to be a valid suffix in addition to NUMBER. - file_path = '%s.%s' % (filename_template.safe_substitute( - VIDEO_NAME=video.name, - SCENE_NUMBER=scene_num_format % (i + 1), - IMAGE_NUMBER=image_num_format % (j + 1), - FRAME_NUMBER=image_timecode.get_frames(), - TIMESTAMP_MS=int(image_timecode.get_seconds()*1000)), + file_path = '%s.%s' % ( + filename_template.safe_substitute( + VIDEO_NAME=video.name, + SCENE_NUMBER=scene_num_format % (i + 1), + IMAGE_NUMBER=image_num_format % (j + 1), + FRAME_NUMBER=image_timecode.get_frames(), + TIMESTAMP_MS=int(image_timecode.get_seconds() * 1000), + TIMECODE=image_timecode.get_timecode()), image_extension, - ) + ) image_filenames[i].append(file_path) # TODO: Combine this resize with the ones below. if aspect_ratio is not None: diff --git a/tests/test_scene_manager.py b/tests/test_scene_manager.py index 05ab03c7..0779ae2d 100644 --- a/tests/test_scene_manager.py +++ b/tests/test_scene_manager.py @@ -95,7 +95,7 @@ def test_save_images(test_video_file): image_name_glob = 'scenedetect.tempfile.*.jpg' image_name_template = 'scenedetect.tempfile.$SCENE_NUMBER\ - .$IMAGE_NUMBER.$TIMESTAMP_MS' + .$IMAGE_NUMBER.$FRAME_NUMBER.$TIMESTAMP_MS.$TIMECODE' try: video_fps = video.frame_rate From 37ba8aba05a038e6cf6cd891896e5f438b725c03 Mon Sep 17 00:00:00 2001 From: Sara Veldhoen Date: Thu, 2 May 2024 11:40:56 +0200 Subject: [PATCH 09/11] Use semicolon as timestamp separator in filename --- scenedetect/scene_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scenedetect/scene_manager.py b/scenedetect/scene_manager.py index b6eed1e6..d8813512 100644 --- a/scenedetect/scene_manager.py +++ b/scenedetect/scene_manager.py @@ -496,7 +496,7 @@ def save_images(scene_list: List[Tuple[FrameTimecode, FrameTimecode]], IMAGE_NUMBER=image_num_format % (j + 1), FRAME_NUMBER=image_timecode.get_frames(), TIMESTAMP_MS=int(image_timecode.get_seconds() * 1000), - TIMECODE=image_timecode.get_timecode()), + TIMECODE=image_timecode.get_timecode().replace(":", ";")), image_extension, ) image_filenames[i].append(file_path) From 351fe61b83e1e16661f2f8ddbce5bbe515b387bb Mon Sep 17 00:00:00 2001 From: Sara Veldhoen Date: Thu, 2 May 2024 11:41:27 +0200 Subject: [PATCH 10/11] Proper string concatenation --- tests/test_scene_manager.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_scene_manager.py b/tests/test_scene_manager.py index 0779ae2d..c974398d 100644 --- a/tests/test_scene_manager.py +++ b/tests/test_scene_manager.py @@ -94,8 +94,9 @@ def test_save_images(test_video_file): sm.add_detector(ContentDetector()) image_name_glob = 'scenedetect.tempfile.*.jpg' - image_name_template = 'scenedetect.tempfile.$SCENE_NUMBER\ - .$IMAGE_NUMBER.$FRAME_NUMBER.$TIMESTAMP_MS.$TIMECODE' + image_name_template = ('scenedetect.tempfile.' + '$SCENE_NUMBER.$IMAGE_NUMBER.$FRAME_NUMBER.' + '$TIMESTAMP_MS.$TIMECODE') try: video_fps = video.frame_rate From 5cef762b0429de36343bb2663905975f574c38dc Mon Sep 17 00:00:00 2001 From: Sara Veldhoen Date: Thu, 2 May 2024 11:54:03 +0200 Subject: [PATCH 11/11] Updated docstring --- scenedetect/scene_manager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scenedetect/scene_manager.py b/scenedetect/scene_manager.py index d8813512..64db99dd 100644 --- a/scenedetect/scene_manager.py +++ b/scenedetect/scene_manager.py @@ -383,9 +383,9 @@ def save_images(scene_list: List[Tuple[FrameTimecode, FrameTimecode]], encoder_param: Quality/compression efficiency, based on type of image: 'jpg' / 'webp': Quality 0-100, higher is better quality. 100 is lossless for webp. 'png': Compression from 1-9, where 9 achieves best filesize but is slower to encode. - image_name_template: Template to use when creating the images on disk. Can - use the macros $VIDEO_NAME, $SCENE_NUMBER, and $IMAGE_NUMBER. The image - extension is applied automatically as per the argument image_extension. + image_name_template: Template to use when creating the images on disk. Can use the macros + $VIDEO_NAME, $SCENE_NUMBER, $IMAGE_NUMBER, $FRAME_NUMBER, and $TIMESTAMP_MS. + The image extension is applied automatically as per the argument image_extension. output_dir: Directory to output the images into. If not set, the output is created in the working directory. show_progress: If True, shows a progress bar if tqdm is installed.