- FFMpegSliceSegment的起始结束时间不小于0的校验
- ffmpeg_slice_media少传递了options对象
This commit is contained in:
shuohigh@gmail.com 2025-06-12 14:38:50 +08:00
parent f1e4fa3d6c
commit 9022e52827
5 changed files with 33 additions and 5 deletions

View File

@ -19,12 +19,21 @@ class FFMpegSliceSegment(BaseModel):
@classmethod @classmethod
def parse_start(cls, v: Union[float, str, TimeDelta]): def parse_start(cls, v: Union[float, str, TimeDelta]):
if isinstance(v, float): if isinstance(v, float):
if v < 0.0:
raise ValueError("开始时间点不能小于0")
return TimeDelta(seconds=v) return TimeDelta(seconds=v)
elif isinstance(v, int): elif isinstance(v, int):
if v < 0:
raise ValueError("开始时间点不能小于0")
return TimeDelta(seconds=v) return TimeDelta(seconds=v)
elif isinstance(v, str): elif isinstance(v, str):
return TimeDelta.from_format_string(v) timedelta = TimeDelta.from_format_string(v)
if timedelta.total_seconds() < 0.0:
raise ValueError("开始时间点不能小于0")
return timedelta
elif isinstance(v, TimeDelta): elif isinstance(v, TimeDelta):
if v.total_seconds() < 0.0:
raise ValueError("开始时间点不能小于0")
return v return v
else: else:
raise TypeError(v) raise TypeError(v)
@ -33,12 +42,21 @@ class FFMpegSliceSegment(BaseModel):
@classmethod @classmethod
def parse_end(cls, v: Union[float, TimeDelta]): def parse_end(cls, v: Union[float, TimeDelta]):
if isinstance(v, float): if isinstance(v, float):
if v < 0.0:
raise ValueError("结束时间点不能小于0")
return TimeDelta(seconds=v) return TimeDelta(seconds=v)
elif isinstance(v, int): elif isinstance(v, int):
if v < 0:
raise ValueError("结束时间点不能小于0")
return TimeDelta(seconds=v) return TimeDelta(seconds=v)
elif isinstance(v, str): elif isinstance(v, str):
return TimeDelta.from_format_string(v) timedelta = TimeDelta.from_format_string(v)
if timedelta.total_seconds() < 0.0:
raise ValueError("结束时间点不能小于0")
return timedelta
elif isinstance(v, TimeDelta): elif isinstance(v, TimeDelta):
if v.total_seconds() < 0.0:
raise ValueError("结束时间点不能小于0")
return v return v
else: else:
raise TypeError(v) raise TypeError(v)

View File

@ -176,6 +176,11 @@ class MediaSource(BaseModel):
return f"{self.protocol.value}/{self.path}" return f"{self.protocol.value}/{self.path}"
return f"{self.protocol.value}/{self.endpoint}/{self.bucket}/{self.path}" return f"{self.protocol.value}/{self.endpoint}/{self.bucket}/{self.path}"
@computed_field(description="CDN挂载地址")
@property
def url(self) -> str:
return f"{config.S3_cdn_endpoint}/{self.get_cdn_url()}"
def __str__(self): def __str__(self):
match self.protocol: match self.protocol:
case MediaProtocol.http: case MediaProtocol.http:

View File

@ -79,9 +79,10 @@ class FFMPEGResult(BaseModel):
@computed_field(description="可通过CDN访问的资源链接") @computed_field(description="可通过CDN访问的资源链接")
@property @property
def url(self) -> str: def url(self) -> str:
if not self.urn.startswith("s3://"): prefix = f"s3://{config.S3_region}/{config.S3_bucket_name}"
raise ValueError("无法转换非s3前缀协议") if not self.urn.startswith(prefix):
return self.urn.replace('s3://', f"{config.S3_cdn_endpoint}/") raise ValueError("无法转换非s3前缀协议和非当前挂载点的s3协议")
return self.urn.replace(prefix, f"{config.S3_cdn_endpoint}/")
class BaseFFMPEGTaskRequest(BaseModel): class BaseFFMPEGTaskRequest(BaseModel):

View File

@ -461,6 +461,8 @@ class VideoUtils:
if marker.end.total_seconds() > 0 and math.isclose(marker.end.total_seconds(), metadata.format.duration, if marker.end.total_seconds() > 0 and math.isclose(marker.end.total_seconds(), metadata.format.duration,
rel_tol=diff_tolerance): rel_tol=diff_tolerance):
marker.end = TimeDelta(seconds=metadata.format.duration) marker.end = TimeDelta(seconds=metadata.format.duration)
logger.warning(
f"{i}个切割点结束点{marker.end.total_seconds()}s接近视频时长[0-{metadata.format.duration}s]范围")
else: else:
raise ValueError( raise ValueError(
f"{i}个切割点结束点{marker.end.total_seconds()}s超出视频时长[0-{metadata.format.duration}s]范围") f"{i}个切割点结束点{marker.end.total_seconds()}s超出视频时长[0-{metadata.format.duration}s]范围")

View File

@ -161,10 +161,12 @@ with ffmpeg_worker_image.imports():
case MediaProtocol.hls: case MediaProtocol.hls:
outputs = await ffmpeg_hls_slice_process(media_source=media, outputs = await ffmpeg_hls_slice_process(media_source=media,
media_markers=markers, media_markers=markers,
options=options,
fn_id=fn_id) fn_id=fn_id)
case MediaProtocol.s3: case MediaProtocol.s3:
outputs = await ffmpeg_slice_process(media_source=media, outputs = await ffmpeg_slice_process(media_source=media,
media_markers=markers, media_markers=markers,
options=options,
fn_id=fn_id) fn_id=fn_id)
case _: # webhook不会报错需要确认 case _: # webhook不会报错需要确认
raise NotImplementedError("暂不支持的协议") raise NotImplementedError("暂不支持的协议")