安装:
要开始,库中有一个高级函数可以对视频执行内容感知场景检测(尝试在 Python 提示符下运行):
pip install scenedetect[opencv] --upgrade
需要 ffmpeg
和 mkvmerge
以支持视频分割功能
开始
命令行快速开始
- 在每个快速切换处分割输入视频:
scenedetect -i video.mp4 split-video
- 保存每个切换的一些帧:
scenedetect -i video.mp4 save-images
- 跳过输入视频的前10秒:
scenedetect -i video.mp4 time-s 10s
使用方法二:代码
在Python中使用PySceneDetect主要用到下面几个类:
- scenedetect.scene_manager 🎞️: SceneManager作为一种方式来协调视频帧(VideoStream** 通过视频流实例)上的检测场景(通过SceneDetector实例)。 该模块还包含将场景信息以各种格式导出的功能:使用
save_images
保存每个场景的图像,使用write_scene_list
将场景/剪辑信息保存为CSV格式,使用write_scene_list_html
将场景以可视化的HTML格式导出。**- SceneManager:用于协调SceneDetector,VideoManager和可选的StatsManager对象的高级管理器。
- VideoManager:用于加载视频并提供搜索。
- StatsManager:用于存储/缓存帧指标,以加快在同一视频上后续场景检测的运行速度,并可以保存到CSV文件或从CSV中加载缓存。
- scenedetect.detectors 🕵️: 用于实现检测算法的基类,如ContentDetector,ThresholdDetector等。检测算法:
- ContentDetector**: **它能够快速检测视频内容中的变化/剪辑
- ThresholdDetector**: **它能够检测视频亮度/强度的变化。
- AdaptiveDetector: 类似于 ContentDetector,但在摄像机快速移动期间可能会减少误报。
- scenedetect.video_stream 🎥: 视频输入通过界面处理。中提供了常见视频库的实现
- OpenCV:
VideoStreamCv2
- PyAV:** **VideoStreamAv
- MoviePy:
VideoStreamMoviePy
- OpenCV:
- scenedetect.video_splitter ✂️: 包含并根据检测到的场景拆分视频。
- scenedetect.frame_timecode ⏱️:FrameTimecode** 包含用于存储、转换和执行时间码算术的类 具有精确到帧的精度**
- FrameTimecode:用于存储时间码以及对时间码值进行算术运算(加/减/比较),并具有帧级的精确度。
- scenedetect.scene_detector 🌐: 包含检测算法必须实现的SceneDetector接口。
- scenedetect.stats_manager 🧮: 包含StatsManager类,用于缓存帧指标并以CSV格式加载/保存到磁盘以供分析。也用作持久缓存,使同一视频的多次传递速度大大加快。
- scenedetect.platform 🐱💻: 日志记录和实用程序函数
代码示例:
def test_detect_video(self,path):
if path is None:
path = 'video/test-1.mp4'
# 分析转场视频自动分割
#AdaptiveDetector(能更好地处理快速摄像机移动)
scene_list = detect(path, ContentDetector())
for i,scene in enumerate(scene_list):
print(' 场景%2d: 开始时间%s/ 帧数%d, 结束时间%s/ 帧数%d' % (
i + 1,
scene[0].get_timecode(), scene[0].get_frames(),
scene[1].get_timecode(), scene[1].get_frames()))
return scene_list
def test_split_video(self,path):
# 使用ffmpeg自动分割
scene_list = self.test_detect_video(path)
split_video_ffmpeg(path, scene_list)
'''
加载视频、检测场景并返回包含每个检测到的场景(开始、结束)时间码的元祖列表
'''
def test_find_scenes(video_path, threshold=27.0):
if video_path is None:
video_path = 'video/test-1.mp4'
video = open_video(video_path)
scene_manager = SceneManager()
scene_manager.add_detector(
ContentDetector(threshold=threshold))
# 检测视频中从当前位置到结束的所有场景。
scene_manager.detect_scenes(video)
# `get_scene_list `返回开始结束时间码对的列表
# 对于找到的每个场景。
return scene_manager.get_scene_list()
# 回调,在每个新场景检测的第一帧上调用。
def on_new_scene(frame_img: numpy.ndarray, frame_num: int):
print("New scene found at frame %d." % frame_num)
video = open_video('video/test-1.mp4')
scene_manager = SceneManager()
scene_manager.add_detector(ContentDetector())
scene_manager.detect_scenes(video=video, callback=on_new_scene)
常用功能模块
常用的detect()
该模块附带了帮助函数来简化常见的用例。 detect()可用于按路径对视频执行场景检测。open_video()可以用来为SceneManager.scenedetect打开一个视频
scenedetect.detect(video_path, detector, stats_file_path=None, show_progress=False, start_time=None, end_time=None, start_in_scene=False)
使用指定的检测器对给定的视频路径执行场景检测。
Parameters:
- video_path (str) – 输入视频的路径(绝对或相对路径)。
- detector (SceneDetector) – 一个 SceneDetector 实例 (有关完整列表,请参阅scenedetect.detectors ).
- stats_file_path (str | None) – 保存每帧指标以进行统计分析的路径或确定更好的阈值threshold
- show_progress (bool) – 显示进度条,显示估计剩余时间。默认为False。
- start_time (str | float | int | None) – 视频中的起点, 以时间码(str)、秒数(float)或帧数(int)的形式表示.HH:MM:SS[.nnn]123.45200
- end_time (str | float | int | None) – 视频中的终点, 以时间码(str)、秒数(float)或帧数(int)的形式表示.HH:MM:SS[.nnn]``123.45200
- start_in_scene (bool) – 假设视频开始于一个场景。这意味着当使用ContentDetector检测快速剪切时,如果没有发现任何剪切,则生成的场景列表将包含跨越整个视频的单个场景(而不是没有场景)。 当使用ThresholdDetector检测淡出时,视频的开始部分将始终包括在内,直到检测到第一个淡出事件。
返回:
List of scenes (pairs of objects).FrameTimecode
异常
- VideoOpenFailure: 无法打开
video_path
。 - StatsFileCorrupt:
stats_file_path
是无效的统计文件。 - ValueError:
start_time
或end_time
的格式不正确。 - TypeError:
start_time
或end_time
是无效类型。
返回类型
- List[Tuple[FrameTimecode, FrameTimecode]]
常用的open_video()
另一个常用的函数是 scenedetect.open_video()
,它用于在给定路径处打开视频。如果指定了 backend
,但在当前系统中不可用,OpenCV(VideoStreamCv2)将作为后备使用。
scenedetect.open_video(
path,
framerate=None,
backend='opencv',
**kwargs
)
参数
- path (str): 要打开的视频文件的路径。
- framerate (float | None): 如果设置,则覆盖检测到的帧速率。
- backend (str): 要使用的特定后端的名称(如果可能)。请参阅当前系统。如果后端无法打开视频,则使用 OpenCV 作为后备。
- kwargs: 要传递给指定后端构造函数的可选命名参数,用于覆盖特定于后端的选项。
返回
- 使用指定视频路径创建的 Backend 对象。
异常
- VideoOpenFailure: 构建 VideoStream 失败。如果尝试了多个后端,将返回来自第一个后端的错误。
返回类型
- VideoStream
Scenedetect模块
Scenedetect.detectors模块
本模块包含以下场景检测算法:
ContentDetector
- 描述: 使用 HSV 颜色空间中像素变化的加权平均值来检测镜头变化。
- 命令行: 可用作
detect-content
。 - 参数:
threshold (float)
: 像素强度平均变化必须超过的阈值,以触发一个镜头切换。默认27.0min_scene_len (int)
: 一次镜头切换后,必须经过的帧数才能将新的镜头添加到场景列表中。默认15weights (Components)
: 计算帧分数时每个组件(色调、饱和度、亮度、边缘)的权重。luma_only (bool)
: 如果为True
,仅考虑亮度通道的变化。默认:Falsekernel_size (int | None)
: 扩展检测到的边缘时使用的内核大小。必须是奇数且 ≥ 3。如果为None
,则根据视频分辨率自动设置。filter_mode (Mode)
: 过滤以满足min_scene_len
时使用的模式。
ThresholdDetector
- 描述: 使用 RGB 中的平均像素强度来检测缓慢过渡(淡入/淡出)。
- 命令行: 可用作
detect-threshold
。 - 参数:
threshold (float)
: 每个像素值(R、G、B)必须 ≤ 该值以触发淡入/淡出。min_scene_len (int)
: 任何场景的最短长度(帧数或FrameTimecode
)。fade_bias (float)
: 介于 -1.0 和 +1.0 之间的浮点数,表示场景开始的时间码偏移量(-1.0 导致在淡入黑色时切换,0.0 在中间,+1.0 在通过阈值的位置切换)。add_final_scene (bool)
: 布尔值,表示如果视频以淡出结束,是否在该时间码生成额外的场景。method (Method)
: 检测淡入淡出事件时如何处理阈值。block_size (已废弃)
: 仅用于向后兼容。
AdaptiveDetector
- 描述: 在 HSV 颜色空间上执行滚动平均,这可以改善快速运动的处理。
- 命令行: 可用作
detect-adaptive
。 - 参数:
adaptive_threshold (float)
: 分数比率必须超过以触发新场景的阈值。min_scene_len (int)
: 任何场景的最短长度。window_width (int)
: 每个帧前后要平均的窗口大小(帧数)。必须至少为 1。min_content_val (float)
: 内容值必须超过以注册为新场景的最小阈值。weights (Components)
: 计算帧分数时每个组件的权重。luma_only (bool)
: 如果为True
,仅考虑亮度通道的变化。kernel_size (int | None)
: 后边缘检测过滤时使用的内核大小。如果为None
,则根据视频分辨率自动设置。video_manager (已废弃)
: 仅用于向后兼容。min_delta_hsv (已废弃)
: 改用min_content_val
。
HistogramDetector
- 描述: 使用 YUV 空间中 Y 通道的直方图差异来查找快速切片。
- 命令行: 可用作
detect-histogram
。 - 参数:
threshold (float)
: 直方图差异的最大相对值,介于 0.0 和 1.0 之间。bins (int)
: 直方图的区间数。min_scene_len (int)
: 任何场景的最短长度。
HashDetector
- 描述: 使用感知哈希计算相邻帧之间的相似性。如果差异超过设定的阈值,则触发场景切换。
- 命令行: 可用作
detect-hash
。 - 参数:
threshold (float)
: 表示相邻帧感知哈希之间相对汉明距离的值,范围从 0.0 到 1.0。较小的阈值需要更多的相关性,使检测器更敏感。汉明距离在与阈值比较前会除以size x size
进行归一化。size (int)
: DCT 中使用的低频数据的方形大小。lowpass (int)
: 要从 DCT 中过滤掉的高频信息量。值为 2 表示保留低频数据的 1/2,值为 4 表示仅保留 1/4,依此类推。min_scene_len (int)
: 任何给定场景的最短长度(帧数或FrameTimecode
)。
总结
这些检测器通过不同的方法来识别视频中的场景变化,可以根据具体需求选择合适的检测器。例如,ContentDetector
适用于快速镜头切换,而 ThresholdDetector
适用于慢速过渡(如淡入/淡出),AdaptiveDetector
适用于处理快速运动的场景,HistogramDetector
适用于基于直方图差异的快速切片检测,HashDetector
适用于基于感知哈希的相似性检测。
scenedetect.backends 模块
此模块包含了由各种 Python 多媒体库支持的 VideoStream
实现。除了直接创建后端对象外,还可以使用 scenedetect.open_video()
函数打开带有指定后端的视频,如果指定的后端不可用,则默认回退到OpenCV。
所有当前系统上可用的后端可以通过 AVAILABLE_BACKENDS
查找。
如果你已经有一个 cv2.VideoCapture
对象并希望用于场景检测,可以使用 VideoCaptureAdapter
代替后端。这在处理设备或流时特别有用。
视频文件
假设我们有一个名为 video.mp4
的文件位于工作目录中,可以使用 open_video()
加载它并进行场景检测:
from scenedetect import open_video
video = open_video('video.mp4')
可以传递一个来自 AVAILABLE_BACKENDS
的后端给 open_video()
(例如 backend='opencv'
)。传递给 open_video()
的其他关键字参数将转发给后端构造函数。如果指定的后端不可用或加载视频失败,将尝试使用 OpenCV 作为回退。
直接使用特定后端的例子如下:
# 手动导入并构建后端:
from scenedetect.backends.opencv import VideoStreamCv2
video = VideoStreamCv2('video.mp4')
在上述两个例子中,生成的视频都可以与 SceneManager.detect_scenes()
一起使用。
设备 / 摄像头 / 流
你可以使用现有的 cv2.VideoCapture
对象与 PySceneDetect API 一起使用 VideoCaptureAdapter
。例如,使用摄像头设备:
from scenedetect import SceneManager, ContentDetector
from scenedetect.backends import VideoCaptureAdapter
# 打开设备 ID 2
cap = cv2.VideoCapture(2)
video = VideoCaptureAdapter(cap)
total_frames = 1000
scene_manager = SceneManager()
scene_manager.add_detector(ContentDetector())
scene_manager.detect_scenes(video=video, duration=total_frames)
在处理实时输入时,可以在 detect_scenes()
中传递一个回调函数,在每次检测到场景事件时调用。详情请参阅 SceneManager
示例。
支持的后端
scenedetect.backends.AVAILABLE_BACKENDS: Dict[str, Type] = {
'opencv': <class 'scenedetect.backends.opencv.VideoStreamCv2'>,
'pyav': <class 'scenedetect.backends.pyav.VideoStreamAv'>
}
所有 scenedetect.open_video()
可以考虑用于 backend
参数的后端。这些后端必须支持以下签名的构造:
BackendType(path: str, framerate: Optional[float])
VideoStreamCv2
由 OpenCV VideoCapture
对象支持。这是默认后端。支持视频文件、图像序列和网络流/URL。
VideoCaptureAdapter
用于包装输入设备或管道。可以从现有的 cv2.VideoCapture
构建。这允许对不支持寻址的输入进行场景检测。
类信息
VideoCaptureAdapter
class scenedetect.backends.opencv.VideoCaptureAdapter(cap, framerate=None, max_read_attempts=5)
现有 VideoCapture
对象的适配器。与 VideoStreamCv2
不同,此类支持可能不支持寻址的 VideoCapture
。
参数
cap (VideoCapture)
: 要包装的cv2.VideoCapture
对象。必须已经打开并且准备好调用cap.read()
。framerate (float | None)
: 如果设置,覆盖检测到的帧率。max_read_attempts (int)
: 在帧解码失败后继续解码视频的尝试次数。这允许处理有少数损坏帧或元数据的视频(在这种情况下,检测算法的准确性可能会降低)。一旦达到此限制,解码将停止并发出错误。
方法
read(decode=True, advance=True)
: 读取并解码下一帧为np.ndarray
。当视频结束或达到最大解码尝试次数时返回False
。decode (bool)
: 解码并返回帧。advance (bool)
: 寻址到下一帧。如果为False
,将返回当前(最后一)帧。- 返回类型:
ndarray | bool
reset()
: 不支持。seek(target)
: 假设底层VideoCapture
不支持寻址。target (FrameTimecode | float | int)
: 目标位置。如果是浮点数,解释为秒;如果是整数,解释为帧号。
属性
aspect_ratio (float)
: 显示/像素纵横比,1.0 表示正方形像素。capture (VideoCapture)
: 返回底层VideoCapture
对象。谨慎使用。duration (FrameTimecode | None)
: 流的持续时间,如果非终止则为None
。frame_number (int)
: 当前在流中的帧位置。- 1 表示上次调用
read(advance=True)
时解码了第一帧,0 表示尚未读取任何帧。 - 如果未读取任何帧,此方法始终返回 0。
- 1 表示上次调用
frame_rate (float)
: 帧率(每秒帧数)。frame_size (Tuple[int, int])
: 每个视频帧的大小(像素)。is_seekable (bool)
: 始终为False
,因为假设底层VideoCapture
不支持寻址。name (str)
: 始终为'CAP_ADAPTER'
。path (str)
: 始终为'CAP_ADAPTER'
。position (FrameTimecode)
: 当前在流中的位置。- 如果未读取任何帧,此方法始终返回 0(即等于
base_timecode
)。
- 如果未读取任何帧,此方法始终返回 0(即等于
position_ms (float)
: 当前在流中的位置(毫秒)。第一帧的时间为 0.0 ms。- 如果未读取任何帧,此方法始终返回 0.0。
VideoStreamCv2
class scenedetect.backends.opencv.VideoStreamCv2(path=None, framerate=None, max_decode_attempts=5, path_or_device=None)
OpenCV cv2.VideoCapture
后端。
参数
path (AnyStr)
: 视频路径。可以是文件、图像序列(如'folder/DSC_%04d.jpg'
)或网络流。framerate (float | None)
: 如果设置,覆盖检测到的帧率。max_decode_attempts (int)
: 在帧解码失败后继续解码视频的尝试次数。这允许处理有少数损坏帧或元数据的视频(在这种情况下,检测算法的准确性可能会降低)。一旦达到此限制,解码将停止并发出错误。path_or_device (bytes | str | int)
: [已废弃] 指定文件、图像序列或网络流/URL 的路径。对于设备/管道,请使用VideoCaptureAdapter
。
方法
read(decode=True, advance=True)
: 读取并解码下一帧为np.ndarray
。当视频结束或达到最大解码尝试次数时返回False
。decode (bool)
: 解码并返回帧。advance (bool)
: 寻址到下一帧。如果为False
,将返回当前(最后一)帧。- 返回类型:
ndarray | bool
reset()
: 关闭并重新打开VideoStream
(等效于调用seek(0)
)。seek(target)
: 寻址到给定的时间码。如果给定的是帧号,则表示当前的寻址指针(例如,如果寻址到 0,下一个解码的帧将是视频的第一帧)。target (FrameTimecode | float | int)
: 目标位置。如果是浮点数,解释为秒;如果是整数,解释为帧号。- 抛出异常:
SeekError
: 寻址过程中发生错误,或不支持寻址。ValueError
:target
无效(例如,它是负数)。
属性
aspect_ratio (float)
: 显示/像素纵横比,1.0 表示正方形像素。capture (VideoCapture)
: 返回底层VideoCapture
对象。谨慎使用。duration (FrameTimecode | None)
: 流的持续时间,如果非终止则为None
。frame_number (int)
: 当前在流中的帧位置。- 1 表示上次调用
read(advance=True)
时解码了第一帧,0 表示尚未读取任何帧。 - 如果未读取任何帧,此方法始终返回 0。
- 1 表示上次调用
frame_rate (float)
: 帧率(每秒帧数)。frame_size (Tuple[int, int])
: 每个视频帧的大小(像素)。is_seekable (bool)
: 是否支持寻址。如果打开的是设备/摄像头,则始终为False
。name (str)
: 视频名称,不带扩展名,或设备名称。path (bytes | str)
: 视频或设备路径。position (FrameTimecode)
: 当前在流中的位置。- 可以解释为通过调用
read(advance=True)
解码的最后一帧的显示时间戳。 - 如果未读取任何帧,此方法始终返回 0(即等于
base_timecode
)。
- 可以解释为通过调用
position_ms (float)
: 当前在流中的位置(毫秒)。第一帧的时间为 0.0 ms。- 如果未读取任何帧,此方法始终返回 0.0。
VideoStreamAv
class scenedetect.backends.pyav.VideoStreamAv(path_or_io, framerate=None, name=None, threading_mode=None, suppress_output=False)
PyAV av.InputContainer
后端。
参数
path_or_io (AnyStr | BinaryIO)
: 视频路径,或文件对象。framerate (float | None)
: 如果设置,覆盖检测到的帧率。name (str | None)
: 覆盖从视频路径派生的name
属性。如果path_or_io
是文件对象,应设置此参数。threading_mode (str | None)
: PyAV 视频流线程类型。有效线程模式包括'AUTO'
,'FRAME'
,'NONE'
, 和'SLICE'
。如果此模式为'AUTO'
或'FRAME'
且suppress_output=True
,可能会导致应用程序锁定。详情请参阅 PyAV 文档。suppress_output (bool)
: 是否抑制输出。如果设置为True
,可能会导致应用程序锁定。
属性
aspect_ratio (float)
: 像素纵横比,1.0 表示正方形像素。duration (FrameTimecode)
: 视频的持续时间。frame_number (int)
: 当前在流中的帧位置。- 将始终返回 0,直到读取第一个帧。
frame_rate (float)
: 帧率(每秒帧数)。frame_size (Tuple[int, int])
: 每个视频帧的大小(像素)。is_seekable (bool)
: 是否支持寻址。name (str)
: 视频名称,不带扩展名,或设备名称。path (bytes | str)
: 视频路径。position (FrameTimecode)
: 当前在流中的位置。- 可以解释为通过调用
read(advance=True)
解码的最后一帧的显示时间戳。 - 如果未读取任何帧,此方法始终返回 0(即等于
base_timecode
)。
- 可以解释为通过调用
position_ms (float)
: 当前在流中的位置(毫秒)。第一帧的时间为 0.0 ms。- 如果未读取任何帧,此方法始终返回 0.0。
SceneManager 模块
该模块实现了 SceneManager
,协调运行场景检测器(SceneDetector
)对视频流(VideoStream
)中的帧进行检测。视频解码在一个单独的线程中进行,以提高性能。
该模块还包含其他辅助函数(如 save_images()
),可用于处理结果场景列表。
使用示例
以下示例展示了 SceneManager
的基本用法:
from scenedetect import open_video, SceneManager, ContentDetector
video = open_video(video_path)
scene_manager = SceneManager()
scene_manager.add_detector(ContentDetector())
# 检测视频当前位置到结尾的所有场景。
scene_manager.detect_scenes(video)
# `get_scene_list` 返回一个包含每个场景的开始/结束时间码对的列表。
scenes = scene_manager.get_scene_list()
可选回调也可以在每个检测到的新场景上被调用,例如:
from scenedetect import open_video, SceneManager, ContentDetector
# 回调函数,在每次新场景检测的第一个帧上被调用。
def on_new_scene(frame_img: numpy.ndarray, frame_num: int):
print(f"New scene found at frame {frame_num}")
video = open_video(test_video_file)
scene_manager = SceneManager()
scene_manager.add_detector(ContentDetector())
scene_manager.detect_scenes(video=video, callback=on_new_scene)
使用摄像头/设备或现有的 cv2.VideoCapture
设备时,使用 VideoCaptureAdapter
而不是 open_video
。
存储每帧统计信息
SceneManager
可以使用可选的 StatsManager
将帧统计信息保存到磁盘:
from scenedetect import open_video, ContentDetector, SceneManager, StatsManager
video = open_video(test_video_file)
scene_manager = SceneManager(stats_manager=StatsManager())
scene_manager.add_detector(ContentDetector())
scene_manager.detect_scenes(video=video)
scene_list = scene_manager.get_scene_list()
print_scenes(scene_list=scene_list)
# 将每帧统计信息保存到磁盘。
scene_manager.stats_manager.save_to_csv(csv_file=STATS_FILE_PATH)
统计文件可用于找到更好的检测参数。
类
scenedetect.scene_manager.SceneManager(stats_manager=None)
- 协调运行场景检测器(
SceneDetector
)对视频流(VideoStream
)中的帧进行检测。视频解码在一个单独的线程中进行,以提高性能。 - 参数:
stats_manager(StatsManager| None)
– 绑定到此SceneManager
的StatsManager
。可以通过生成的对象的stats_manager
属性访问并保存到磁盘。
- 协调运行场景检测器(
方法
add_detector(detector)
- 添加/注册一个场景检测器(如
ContentDetector
,ThresholdDetector
),以便在调用detect_scenes
时运行。SceneManager
拥有检测器对象,因此可以传递临时对象。 - 参数:
detector(SceneDetector)
– 要添加到SceneManager
的场景检测器。
- 返回类型:
None
- 添加/注册一个场景检测器(如
clear()
- 清除所有切割点/场景并重置
SceneManager
的位置。 - 任何生成的统计信息仍然保存在传递给
SceneManager
构造函数的StatsManager
对象中,因此,使用相同的帧源回溯到原始时间(或视频开头)并后续调用detect_scenes
时,将使用之前调用detect_scenes
计算并保存的缓存帧度量标准。 - 返回类型:
None
- 清除所有切割点/场景并重置
clear_detectors()
- 移除通过
add_detector
添加到SceneManager
的所有场景检测器。 - 返回类型:
None
- 移除通过
compute_downscale_factor(frame_width, effective_width=256)
- 静态方法。根据帧宽度计算下采样因子,使得帧宽度接近
effective_width
。 - 参数:
frame_width(int)
– 帧宽度。effective_width(int)
– 目标宽度,默认为256。
- 返回:
- 下采样因子。
- 返回类型:
int
- 静态方法。根据帧宽度计算下采样因子,使得帧宽度接近
detect_scenes(video=None, duration=None, end_time=None, frame_skip=0, show_progress=False, callback=None, frame_source=None)
- 对给定视频执行场景检测,返回处理的帧数。结果可以通过调用
get_scene_list()
或get_cut_list()
获取。 - 视频解码在一个后台线程中进行,以允许场景检测和帧解码并行进行。检测将继续直到没有更多帧,指定的持续时间或结束时间已到达,或调用了
stop()
。 - 参数:
video(VideoStream)
– 通过scenedetect.open_video
或直接创建(例如scenedetect.backends.opencv.VideoStreamCv2
)获得的VideoStream
。duration(FrameTimecode| None)
– 从当前位置开始检测的时间量。end_time(FrameTimecode| None)
– 结束检测的时间点。frame_skip(int)
– 跳过的帧数(提高检测速度但牺牲准确性)。使用StatsManager
时必须为0(默认值)。show_progress(bool)
– 如果为True,并且安装了tqdm
模块,显示带有进度、帧率和预计完成时间的进度条。callback(Callable[[ndarray, int], None]| None)
– 如果设置,每次检测到场景/事件后被调用。frame_source(VideoStream| None)
– [已弃用] 不要使用。仅用于与旧版本兼容。
- 返回:
- 从帧源读取和处理的帧数。
- 返回类型:
int
- 抛出:
ValueError
– 如果SceneManager
是使用StatsManager
对象构造的,则frame_skip
必须为0(默认值)。
- 对给定视频执行场景检测,返回处理的帧数。结果可以通过调用
get_cut_list(base_timecode=None, show_warning=True)
- [已弃用] 返回检测到的场景变化/切割点的
FrameTimecode
列表。 - 与
get_scene_list
不同,切割列表返回一个FrameTimecode
列表,表示输入视频中新场景被检测到的位置,即输入应该被切割/分割的帧。 - 如果仅使用稀疏检测器(如
MotionDetector
),这将始终为空。 - 参数:
base_timecode(FrameTimecode| None)
– [已弃用] 不要使用。仅用于向后兼容。show_warning(bool)
– 如果设置为False,抑制警告错误。在 v0.7 中,这将无效,错误将变成Python警告。
- 返回:
- 表示输入视频中检测到场景变化的时间点的
FrameTimecode
对象列表,这些时间点也可以传递给外部工具用于自动分割输入成单独的场景。
- 表示输入视频中检测到场景变化的时间点的
- 返回类型:
List[FrameTimecode]
- [已弃用] 返回检测到的场景变化/切割点的
get_event_list(base_timecode=None)
- [已弃用] 不要使用。
- 获取稀疏检测事件的开始/结束时间码列表。
- 与
get_scene_list
不同,事件列表返回一个FrameTimecode
列表,表示输入视频中新场景仅由稀疏检测器检测到的位置,否则是相同的。 - 参数:
base_timecode(FrameTimecode| None)
– [已弃用] 不要使用。仅用于向后兼容。
- 返回:
- 表示检测到场景的
FrameTimecode
对象对列表。
- 表示检测到场景的
- 返回类型:
List[Tuple[FrameTimecode, FrameTimecode]]
get_num_detectors()
- 获取通过
add_detector
添加的已注册场景检测器的数量。 - 返回类型:
int
- 获取通过
get_scene_list(base_timecode=None, start_in_scene=False)
- 返回每个检测到场景的开始/结束
FrameTimecode
元组列表。 - 参数:
base_timecode(FrameTimecode| None)
– [已弃用] 不要使用。仅用于向后兼容。start_in_scene(bool)
– 假设视频从场景开始。这意味着当使用ContentDetector
检测快速切换时,如果没有找到切换点,结果的场景列表将包含一个覆盖整个视频的单个场景(而不是没有场景)。当使用ThresholdDetector
检测淡入淡出时,视频的开头部分将一直包含到第一个淡出事件被检测到为止。
- 返回:
- 形式为
(start_time, end_time)
的元组列表,其中start_time
和end_time
是表示每个检测到场景在视频中开始和结束的确切时间和帧的FrameTimecode
对象。
- 形式为
- 返回类型:
List[Tuple[FrameTimecode, FrameTimecode]]
- 返回每个检测到场景的开始/结束
get_scene_list_from_cuts(cut_list, num_frames, start_frame, start_pos, end_pos, base_timecode=None)
- 根据检测到的场景切割点列表生成场景列表。
- 此函数在使用
SceneManager.get_scene_list()
方法时被调用。场景列表是从切割列表(SceneManager.get_cut_list()
)生成的,注意每个场景是连续的,从输入的第一帧到最后一帧。如果切割列表为空,结果场景将从start_pos
跨越到end_pos
。 - 参数:
cut_list(Iterable[FrameTimecode])
– 发生场景切割/变化的FrameTimecode
对象列表。base_timecode(FrameTimecode| None)
– 所有FrameTimecodes
在切割列表中的基准时间码。num_frames
– 处理的视频帧数或帧时间码,表示视频的持续时间(用于生成最后一个场景的结束时间)。start_frame
– 切割列表的开始帧或帧时间码。用于生成第一个场景的开始时间。start_pos(int| FrameTimecode)
–end_pos(int| FrameTimecode)
–
- 返回:
- 形式为
(start_time, end_time)
的元组列表,其中start_time
和end_time
是表示每个场景占据的视频确切时间和帧的FrameTimecode
对象。
- 形式为
- 返回类型:
List[Tuple[FrameTimecode, FrameTimecode]]
save_images(scene_list, video, num_images=3, frame_margin=1, image_extension='jpg', encoder_param=95, image_name_template='$VIDEO_NAME-Scene-$SCENE_NUMBER-$IMAGE_NUMBER', output_dir=None, show_progress=False, scale=None, height=None, width=None, interpolation=Interpolation.CUBIC, video_manager=None)
- 从每个场景中保存一组图像,给定场景列表和关联的视频/帧源。
- 参数:
scene_list(List[Tuple[FrameTimecode, FrameTimecode]])
– 通过调用SceneManager
的detect_scenes()
方法返回的场景列表(帧时间码对)。video(VideoStream)
– 对应于场景列表的VideoStream
对象。请注意,视频将被关闭/重新打开并逐帧搜索。num_images(int)
– 每个场景生成的图像数量。最小值为1。frame_margin(int)
– 在每个场景的开始和结束周围填充的帧数(例如,将第一个/最后一个图像移动到场景内N帧)。可以设置为0,但这可能导致某些视频文件无法提取最后一帧。image_extension(str)
– 要保存的图像类型(必须是 ‘jpg’、‘png’ 或 ‘webp’ 之一)。encoder_param(int)
– 图像的质量/压缩效率,基于图像类型:- ‘jpg’/‘webp’: 质量范围0-100,越高越好。webp的100是无损的。
- ‘png’: 压缩级别1-9,其中9达到最佳文件大小但编码速度较慢。
image_name_template(str)
– 用于命名图像文件的模板。可以使用模板变量$VIDEO_NAME
、$SCENE_NUMBER
、$IMAGE_NUMBER
、$TIMECODE
、$FRAME_NUMBER
、$TIMESTAMP_MS
。不应包含扩展名。output_dir(str| None)
– 输出图像的目录。如果不设置,输出将在工作目录中创建。show_progress(bool| None)
– 如果为True且安装了tqdm
,则显示进度条。scale(float| None)
– 可选因子,用于调整保存的图像大小。缩放因子为1表示不缩放。值小于1表示保存的图像更小,值大于1表示保存的图像更大。如果指定了高度或宽度,则忽略此值。height(int| None)
– 可选值,表示保存图像的高度。同时指定高度和宽度将按固定大小调整图像,而不考虑纵横比。仅指定高度将按该像素数调整图像高度,同时保持纵横比。width(int| None)
– 可选值,表示保存图像的宽度。同时指定宽度和高度将按固定大小调整图像,而不考虑纵横比。仅指定宽度将按该像素数调整图像宽度,同时保持纵横比。interpolation(Interpolation)
– 调整图像大小时使用的插值方法。video_manager
– [已弃用] 不要使用。仅用于向后兼容。
- 返回:
{scene_num: [image_paths]}
,其中scene_num
是场景列表中场景的编号(从1开始),image_paths
是新保存/创建的图像路径列表。
stop()
- 如果正在进行
detect_scenes()
调用,则停止该调用。线程安全。 - 返回类型:
None
- 如果正在进行
属性
auto_downscale: bool
- 如果设置为True,将根据视频帧大小自动缩放。如果设置,将覆盖
downscale
。
- 如果设置为True,将根据视频帧大小自动缩放。如果设置,将覆盖
downscale: int
- 缩放每个帧的因子。总是大于等于1,其中1表示不缩放。如果
auto_downscale=True
,则忽略此值。
- 缩放每个帧的因子。总是大于等于1,其中1表示不缩放。如果
interpolation: Interpolation
- 缩放帧时使用的插值方法。必须是
cv2.INTER_*
之一。
- 缩放帧时使用的插值方法。必须是
stats_manager: StatsManager| None
- 获取与此
SceneManager
关联的StatsManager
,如果有。
- 获取与此
插值方法
Interpolation.BICUBIC = 2
- 双三次插值。
Interpolation.LANCZOS4 = 4
- Lanczos 插值,覆盖8x8邻域。
Interpolation.LINEAR = 1
- 双线性插值。
Interpolation.NEAREST = 0
- 最近邻插值。
StatsManager 模块
该模块包含 StatsManager
类,它为每个 SceneDetector
提供了一个键值存储,用于写入每帧计算出的度量标准。StatsManager
必须在创建时注册到 SceneManager
。
整个 StatsManager
可以保存到一个可读的CSV文件中,这允许对给定输入的理想阈值(或其他检测参数)进行精确确定。
异常
scenedetect.stats_manager.FrameMetricNotRegistered
- [已弃用 - 不要使用] 不再使用。
scenedetect.stats_manager.FrameMetricRegistered
- [已弃用 - 不要使用] 不再使用。
scenedetect.stats_manager.StatsFileCorrupt(message='无法从提供的CSV文件加载帧度量数据')
- 当帧度量标准/统计数据不能从提供的CSV文件中加载时引发。
- 参数:
message(str)
– 错误信息。
类
scenedetect.stats_manager.StatsManager(base_timecode=None)
- 提供一个用于帧度量标准/计算的键值存储,可用于两遍检测算法以及将统计信息保存到CSV文件。
- 分析统计信息CSV文件对于找到某些检测方法的最佳算法参数也非常有用。此外,可以通过迭代调用
get_metrics()
方法,获取一系列帧中感兴趣的度量标准,并通过绘图模块(如matplotlib)绘制这些数据。 - 目前只应使用由浮点数或整数组成的度量标准。
- 初始化一个新的
StatsManager
。 - 参数:
base_timecode(FrameTimecode)
– 与该对象关联的时间码。必须不是None(默认值将在未来的版本中移除)。
方法
get_metrics(frame_number, metric_keys)
- 返回给定帧请求的统计信息/度量标准。
- 参数:
frame_number(int)
– 要检索度量标准的帧号。metric_keys(List[str])
– 要查找的度量标准键列表。
- 返回:
- 包含给定帧号的请求帧度量标准的列表,顺序与输入的度量标准键列表相同。如果找不到特定度量标准,则返回None。
- 返回类型:
List[Any]
is_save_required()
- 是否需要保存:检查自加载以来统计信息是否已更新。
- 返回:
- 如果有尚未写入磁盘的帧度量标准/统计信息,则返回True,否则返回False。
- 返回类型:
bool
load_from_csv(csv_file)
- [已弃用] 不要使用。
- 将存储在CSV文件中的所有度量标准加载到
StatsManager
实例中。将在未来的版本中移除,成为无操作。 - 参数:
csv_file(str| bytes| TextIO)
– 以读模式打开的文件句柄(例如open('...', 'r')
)或作为字符串的路径。
- 返回:
- 从CSV文件读取的帧数/行数,如果输入文件为空或未找到,则返回None。
- 返回类型:
int or None
- 抛出:
StatsFileCorrupt
– 统计文件损坏且无法加载,或者指定了错误的文件。
metrics_exist(frame_number, metric_keys)
- 度量标准是否存在:检查给定帧是否存在给定的度量标准/统计信息。
- 返回:
- 如果给定的度量标准键存在于帧中,则返回True,否则返回False。
- 返回类型:
bool
- 参数:
frame_number(int)
– 帧号。metric_keys(Iterable[str])
– 度量标准键列表。
register_metrics(metric_keys)
- 注册度量标准键列表,这些度量标准键将被探测器使用。
- 参数:
metric_keys(Iterable[str])
– 度量标准键列表。
- 返回类型:
None
save_to_csv(csv_file, base_timecode=None, force_save=True)
- 保存到CSV:将
StatsManager
中存储的所有帧度量标准保存到CSV文件中。 - 参数:
csv_file(str| bytes| TextIO)
– 以写模式打开的文件句柄(例如open('...', 'w')
)或作为字符串的路径。base_timecode(FrameTimecode| None)
– [已弃用] 不要使用。为了向后兼容。force_save
– 如果为True,即使不需要更新也会写入度量标准。
- 抛出:
OSError
– 如果路径无法打开或发生写入失败。
- 返回类型:
None
- 保存到CSV:将
set_metrics(frame_number, metric_kv_dict)
- 设置度量标准:设置给定帧的提供的统计信息/度量标准。
- 参数:
frame_number(int)
– 帧号。metric_kv_dict(Dict[str, Any])
– 映射度量标准键到相应的整数/浮点数度量标准值的字典。
- 返回类型:
None
valid_header(row)
- 静态方法。检查给定的CSV行是否是统计文件的有效头部。
- 参数:
row(List[str])
– 从CSV读取器解码的行。
- 返回:
- 如果行是有效的统计文件头部,则返回True,否则返回False。
- 返回类型:
bool
常量
scenedetect.stats_manager.COLUMN_NAME_FRAME_NUMBER='Frame Number'
- 统计文件CSV中包含帧号的列名。
scenedetect.stats_manager.COLUMN_NAME_TIMECODE='Timecode'
- 统计文件CSV中包含时间码的列名。
FrameTimecode 模块
FrameTimecode
模块实现了 FrameTimecode
类,用于存储每个剪辑的精确时间戳。这是通过指定时间码和视频帧率来实现的,允许将帧号转换为浮点数秒或字符串形式的 "HH:MM:SS[.nnn]"
。
使用示例
可以通过指定时间码(整数表示帧数,浮点数表示秒数,或字符串形式的 "HH:MM:SS"
或 "HH:MM:SS.nnn"
)和帧率来创建 FrameTimecode
对象:
frames = FrameTimecode(timecode=29, fps=29.97)
seconds_float = FrameTimecode(timecode=10.0, fps=10.0)
timecode_str = FrameTimecode(timecode="00:00:10.000", fps=10.0)
也可以对 FrameTimecode
对象进行算术和比较操作,另一个操作数也可以是上述类型之一:
x = FrameTimecode(timecode="00:01:00.000", fps=10.0)
# 可以加整数(帧数)、浮点数(秒数)或字符串(时间码)
print(x + 10)
print(x + 10.0)
print(x + "00:10:00")
# 所有比较运算符也是如此
print((x + 10.0) == "00:01:10.000")
FrameTimecode
对象可以相加和相减,但当前实现不允许负值,并且会将负结果限制为 0。
警告:
当减去 FrameTimecode
对象或添加负数帧/秒时要小心。在下面的例子中,c
将位于第 0 帧,因为 b > a
,但 d
将位于第 5 帧:
a = FrameTimecode(5, 10.0)
b = FrameTimecode(10, 10.0)
c = a - b # b > a, 所以 c == 0
d = b - a
assert(c == 0)
assert(d == 5)
FrameTimecode 类
FrameTimecode
类用于基于帧的时间码,使用视频帧率在帧号和秒/时间码之间进行转换。
时间码只有符合以下三种类型/格式之一时才有效:
- 字符串形式的时间码
"HH:MM:SS[.nnn]"
(例如"01:23:45"
或"01:23:45.678"
) - 浮点数表示的秒数,或字符串形式的
"SSSS.nnnn"
(例如"45.678"
) - 整数表示的确切帧数,或字符串形式的
NNNNN
(例如456
或"456"
)
参数
timecode (int | float | str | FrameTimecode)
: 帧号(整数)、秒数(浮点数)或时间码(字符串形式的'HH:MM:SS'
或'HH:MM:SS.nnn'
)。fps (int | float | str | FrameTimecode)
: 用作所有算术运算的时间基准的帧率。
异常
TypeError
: 如果timecode
或fps
是不支持的类型,则抛出此异常。ValueError
: 如果指定了负时间码或帧率,则抛出此异常。
方法
equal_framerate(fps)
: 判断传递的帧率是否与当前对象的帧率相等。- 参数:
fps
- 要比较的帧率。 - 返回: 如果传递的帧率匹配当前
FrameTimecode
对象的帧率,则返回True
,否则返回False
。 - 返回类型:
bool
- 参数:
get_framerate()
: 获取FrameTimecode
对象使用的帧率。- 返回: 当前
FrameTimecode
对象的帧率,单位为每秒帧数。 - 返回类型:
float
- 返回: 当前
get_frames()
: 获取当前时间/位置的帧数。这相当于访问self.frame_num
属性(与指定的帧率一起,形成其他时间测量计算的基础,例如get_seconds()
方法)。- 返回: 当前时间的帧数(当前帧号)。
- 返回类型:
int
get_seconds()
: 获取当前帧的位置(以秒为单位)。- 返回: 当前时间/位置的秒数。
- 返回类型:
float
get_timecode(precision=3, use_rounding=True)
: 获取格式化的时间码字符串,形式为"HH:MM:SS[.nnn]"
。- 参数:
precision (int)
: 输出中小数点后的位数[.nnn]
。use_rounding (bool)
: 是否将输出四舍五入到所需精度。如果为False
,则值将被截断到指定的精度。
- 返回: 当前时间的形式为
"HH:MM:SS[.nnn]"
。 - 返回类型:
str
- 参数:
previous_frame()
: 返回上一帧的新FrameTimecode
对象(如果在第 0 帧,则返回 0)。- 返回类型:
FrameTimecode
- 返回类型:
常量
MAX_FPS_DELTA: float = 1e-05
: 用于帧率相等性测试时,两个帧率之间允许的最大差异。
SceneDetector 模块
SceneDetector
模块包含了 SceneDetector
接口,所有在 scenedetect.detectors
模块中实现的场景检测器都继承自该接口。
SceneDetector
类代表了检测算法为了与 PySceneDetect 兼容而需要提供的接口。
警告:
此 API 仍不稳定,计划在 v1.0 发布时进行更改和设计改进。检测算法不仅提供时间码,还将提供特定类型的事件(如 in
、out
、cut
等)。
类:scenedetect.scene_detector.SceneDetector
当实现场景检测算法时需要继承的基本类。
此 API 不稳定且可能发生变化。
这表示一个“密集”场景检测器,它返回视频中下一个场景/镜头开始的帧列表。
有关如何创建特定检测器的示例,请参见 scenedetect.detectors
模块中实现的场景检测器。
方法
get_metrics()
: 获取检测器使用的所有度量名称/键的列表。- 返回: 检测器在
process_frame
方法中使用StatsManager
时将使用的帧度量键名列表。 - 返回类型:
List[str]
- 返回: 检测器在
is_processing_required(frame_num)
: [已弃用] 不要使用- 测试: 给定帧的所有计算是否已完成。
- 返回: 如果
SceneDetector
有assigned_metric_keys
,并且stats_manager
属性设置为包含给定帧所需帧度量/计算的有效StatsManager
对象,则返回False
,表示不需要该帧进行场景检测;否则返回True
,表示需要将frame_img
传递给process_frame
方法。 - 参数:
frame_num (int)
- 帧号。 - 返回类型:
bool
post_process(frame_num)
: 在读取最后一帧后执行任何处理。- 原型方法,没有实际检测。
- 返回: 需要添加到切割列表中的帧号列表。
- 参数:
frame_num (int)
- 帧号。 - 返回类型:
List[int]
process_frame(frame_num, frame_img)
: 处理下一帧。假设frame_num
是连续的。- 参数:
frame_num (int)
- 正在传递的帧的帧号。可以从任意值开始,但必须保持连续。frame_img (numpy.ndarray or None)
- 对应于frame_img
的视频帧。
- 返回: 检测到场景切割的帧号列表。列表中可能有 0 个或多个帧,不一定与
frame_num
相同。 - 返回类型:
List[int]
- 参数:
stats_manager_required()
: 检测器是否需要StatsManager
。- 返回: 如果检测器需要
StatsManager
,则返回True
,否则返回False
。 - 返回类型:
bool
- 返回: 如果检测器需要
属性
event_buffer_length: int
: 给定事件可以缓冲的时间内的帧数。表示process_frame
结果中任何事件最多可以落后于frame_number
的帧数。stats_manager: StatsManager | None = None
: 可选的StatsManager
,用于缓存帧度量数据。
类:scenedetect.scene_detector.SparseSceneDetector
当实现稀疏场景检测算法时需要继承的基本类。
此类将在 v1.0 版本中移除,不应使用。
与密集检测器不同,稀疏检测器检测“事件”并返回一对帧,而不是单个切割点。
示例
MotionDetector
是一个 SparseSceneDetector
的示例。
方法
post_process(frame_num)
: 在读取最后一帧后执行任何处理。- 原型方法,没有实际检测。
- 返回: 需要直接添加到输出场景列表中的帧对列表。
- 参数:
frame_num (int)
- 帧号。 - 返回类型:
List[Tuple[int, int]]
process_frame(frame_num, frame_img)
: 计算/存储度量并检测任何场景变化。- 原型方法,没有实际检测。
- 返回: 需要直接添加到输出场景列表中的帧对列表。
- 参数:
frame_num (int)
- 帧号。frame_img (ndarray)
- 视频帧。
- 返回类型:
List[Tuple[int, int]]
VideoStream 模块
VideoStream
模块包含了 VideoStream
类,该类提供了与视频输入无关的库抽象接口。
要通过路径打开视频,可以使用 scenedetect.open_video()
函数:
from scenedetect import open_video
video = open_video('video.mp4')
while True:
frame = video.read()
if frame is False:
break
print("已读取 %d 帧" % video.frame_number)
您还可以选择指定帧率和特定的后端库。除非指定,否则将使用 OpenCV 作为视频后端。有关详细示例,请参见 scenedetect.backends
。
新的 VideoStream
实现可以通过将其添加到 tests/test_video_stream.py
测试套件中进行测试。
异常
FrameRateUnavailable
: 当视频帧率不可用或无法计算时,提供一致的错误消息。这是VideoOpenFailure
的子类。- 参数:
message
- 后端可以提供的关于打开失败的附加上下文。
- 参数:
SeekError
: 尝试定位时发生不可恢复的错误,或者底层流不可定位(如果有更多相关信息,将提供)。- 描述: 流保证处于有效状态,但位置可能会重置。
VideoOpenFailure
: 如果打开视频失败,由后端引发。- 参数:
message (str)
- 后端可以提供的关于打开失败的附加上下文。
- 参数:
scenedetect.video_stream.VideoStream
所有视频后端必须实现的接口。
抽象静态方法
BACKEND_NAME()
: 用于标识此后端的唯一名称。应在派生类中定义为静态属性(例如BACKEND_NAME = 'backend_identifier'
)。- 返回类型:
str
- 返回类型:
方法
read(decode=True, advance=True)
: 读取并解码下一帧为np.ndarray
。视频结束时返回False
。- 参数:
decode (bool)
- 解码并返回帧。advance (bool)
- 定位到下一帧。如果为False
,将返回当前(最后一个)帧。
- 返回: 如果
decode = True
,返回解码后的帧(np.ndarray
),或视频结束时返回False
(bool
)。如果decode = False
,返回一个布尔值,指示是否成功定位到下一帧。 - 返回类型:
ndarray | bool
- 参数:
reset()
: 关闭并重新打开VideoStream
(相当于回到开头)。- 返回类型:
None
- 返回类型:
seek(target)
: 定位到给定的时间码。如果以帧号给出,表示当前定位指针(例如,定位到 0,下一帧解码将是视频的第一帧)。- 对于 1 基索引(第一帧是帧 #1),目标帧号需要转换为 0 基索引,方法是减去一。例如,如果我们要定位到第一帧,我们调用
seek(0)
然后read()
。如果我们要定位到第五帧,我们调用seek(4)
然后read()
,此时frame_number
将为 5。 - 可能不支持所有后端类型或输入(例如摄像头)。
- 参数:
target (FrameTimecode | float | int)
- 要定位的目标位置。如果是浮点数,解释为秒数。如果是整数,解释为帧号。 - 抛出异常:
SeekError
- 定位时发生错误,或不支持定位。ValueError
-target
不是有效值(即它是负数)。
- 返回类型:
None
- 对于 1 基索引(第一帧是帧 #1),目标帧号需要转换为 0 基索引,方法是减去一。例如,如果我们要定位到第一帧,我们调用
属性
aspect_ratio: float
: 像素纵横比,浮点数(1.0 表示方形像素)。base_timecode: FrameTimecode
: 用作时间基准的FrameTimecode
对象。duration: FrameTimecode | None
: 流的持续时间,以FrameTimecode
表示,或如果非终止则为None
。frame_number: int
: 当前流中的位置,以帧号表示。- 描述: 在读取第一帧之前返回 0。
frame_rate: float
: 帧率,单位为每秒帧数。frame_size: Tuple[int, int]
: 每个视频帧的大小,以像素为单位,表示为(width, height)
。is_seekable: bool
: 如果允许调用seek()
,则为True
,否则为False
。name: bytes | str
: 视频名称,不带扩展名,或设备名称。path: bytes | str
: 视频或设备路径。position: FrameTimecode
: 当前流中的位置,以FrameTimecode
表示。- 描述: 可以解释为显示时间戳,因此帧 1 对应于显示时间 0。即使
frame_number
为 1,也返回 0。
- 描述: 可以解释为显示时间戳,因此帧 1 对应于显示时间 0。即使
position_ms: float
: 当前流中的位置,以毫秒为单位的显示时间。第一帧的显示时间为 0。
平台与日志记录
scenedetect.platform
模块包含了所有平台/库特定的兼容性修复以及一些用于处理日志记录和调用外部命令的实用函数。
异常
CommandTooLong
: 如果命令行参数的长度超过 Windows 允许的限制,则引发此异常。
类
FakeTqdmLoggingRedirect(**kwargs)
: 提供一个用于重定向日志消息的无操作tqdm
上下文管理器。- 描述: 无操作。
FakeTqdmObject(**kwargs)
: 提供一个类似tqdm
的无操作对象。- 方法:
close()
: 无操作。set_description(desc=None, refresh=True)
: 无操作。update(n=1)
: 无操作。
- 方法:
Template(template)
: 用于替换文件名中$TEMPLATES
实例的模板匹配器。
别名
logging_redirect_tqdm
:FakeTqdmLoggingRedirect
的别名。tqdm
:FakeTqdmObject
的别名。
函数
get_and_create_path(file_path, output_directory=None)
: 获取并返回指定输出目录中file_path
的完整/绝对路径,同时创建所需的目录。- 参数:
file_path (AnyStr)
: 要获取路径的文件名。如果file_path
是绝对路径(例如,从驱动器/根目录开始),不会修改路径,仅确保所有输出目录已创建。output_directory (AnyStr | None)
: 可选的输出目录,用于覆盖file_path
如果它是相对于工作目录的目录。
- 返回: 适合写入的输出文件的完整路径。
- 返回类型:
AnyStr
- 参数:
get_cv2_imwrite_params()
: 获取 OpenCVimwrite
支持的图像格式及其关联的质量/压缩参数索引,如果不支持该格式,则返回None
。- 返回: 支持的图像格式/扩展名(如
'jpg'
,'png'
等)映射到相应的 OpenCV 质量或压缩参数的字典,例如{ 'jpg': cv2.IMWRITE_JPEG_QUALITY, 'png': cv2.IMWRITE_PNG_COMPRESSION, ... }
。如果当前系统库中未找到参数,则为None
(例如{ 'jpg': None }
)。 - 返回类型:
Dict[str, int | None]
- 返回: 支持的图像格式/扩展名(如
get_ffmpeg_path()
: 获取当前系统上可用的ffmpeg
路径。首先查找PATH
,然后检查imageio_ffmpeg
包中是否有可用的ffmpeg
。如果找不到ffmpeg
,则返回None
。- 返回类型:
str | None
- 返回类型:
get_ffmpeg_version()
: 获取ffmpeg
版本标识符,如果找不到ffmpeg
,则返回None
。使用get_ffmpeg_path()
。- 返回类型:
str | None
- 返回类型:
get_file_name(file_path, include_extension=True)
: 返回file_path
引用的文件名,可选地移除扩展名。- 如果
include_extension
为False
,结果始终为字符串。 - 示例:
/tmp/foo.bar -> foo
- 参数:
file_path (AnyStr)
- 返回类型:
AnyStr
- 如果
get_mkvmerge_version()
: 获取mkvmerge
版本标识符,如果mkvmerge
未在PATH
中找到,则返回None
。- 返回类型:
str | None
- 返回类型:
get_system_version_info()
: 获取系统的操作系统、Python、包和外部工具版本。适用于调试或提交错误报告。- 用途: 用于
scenedetect version-a
命令。 - 返回类型:
str
- 用途: 用于
init_logger(log_level=20, show_stdout=False, log_file=None)
: 初始化 PySceneDetect 的日志记录。使用的日志记录器实例名为pyscenedetect
。默认情况下,日志记录器没有任何处理器以抑制输出。每次调用此函数时,所有现有的日志处理器都会被替换。- 参数:
log_level (int)
: 日志消息的详细程度。应该是[logging.INFO, logging.DEBUG, logging.WARNING, logging.ERROR, logging.CRITICAL]
中的一个。show_stdout (bool)
: 如果为True
,添加处理器以在标准输出上显示日志消息(默认为False
)。log_file (str | None)
: 如果设置,添加处理器以将调试日志消息转储到给定的文件路径。
- 参数:
invoke_command(args)
: 与调用 Python 的subprocess.call()
方法相同,但在命令长度过长时显式引发不同的异常。- 详情: 参见 https://github.com/Breakthrough/PySceneDetect/issues/164。
- 参数:
args (List[str])
- 要传递给subprocess.call()
的字符串列表。 - 返回: 命令的返回码。
- 抛出异常:
CommandTooLong
-args
超过 Windows 内置的命令行长度限制。 - 返回类型:
int