爆款开头复刻/拆镜复刻追加日志|拆镜复刻追加视频AI分析API

This commit is contained in:
2026-07-07 19:52:12 +08:00
parent 35ffa317e7
commit 2d419b171e
16 changed files with 1153 additions and 91 deletions
@@ -15,6 +15,7 @@ from app.enums.shot_replicate import (
ShotAnalysisStatusEnum,
ShotSegmentAnalysisStatusEnum,
ShotSegmentReplicateStatusEnum,
ShotReplicateLogEventEnum,
ShotSegmentSourceModeEnum,
ShotSplitStatusEnum,
ShotTaskSetStatusEnum,
@@ -28,6 +29,7 @@ from app.schemas.shot_replicate import (
ShotSegmentDeleteOut,
ShotSegmentDetailOut,
ShotSegmentListOut,
ShotReanalyzeOut,
ShotSegmentOut,
ShotSplitByAIOut,
ShotSplitByAIRequest,
@@ -716,3 +718,124 @@ async def delete_segment(
released_size_bytes=int(released_size_bytes or 0),
)
async def prepare_reanalyze_task_set(
db: AsyncSession,
*,
current_user: User,
task_set_id: str,
force: bool = False,
reason: str | None = None,
) -> ShotReanalyzeOut:
"""重置原视频分析状态,供 API 重新投递 Celery。"""
task_set = await get_task_set_for_user(db, task_set_id=task_set_id, user=current_user, for_update=True)
if task_set.analysis_status == ShotAnalysisStatusEnum.PROCESSING.value:
log_module_event_file(
module=MODULE,
event_type=ShotReplicateLogEventEnum.TASK_SET_REANALYZE_REJECTED.value,
project_id=task_set.id,
user_id=task_set.user_id,
message="原视频分析正在处理中,拒绝再次分析",
detail={"task_set_id": task_set.id, "analysis_status": task_set.analysis_status, "reason": reason},
event_status="rejected",
)
raise HTTPException(status_code=409, detail="原视频分析正在处理中,不能重复投递")
if task_set.analysis_status == ShotAnalysisStatusEnum.COMPLETED.value and not force:
raise HTTPException(status_code=409, detail="原视频分析已完成,如确需重跑请传 force=true")
if force:
active_segments_result = await db.execute(
select(func.count())
.select_from(ShotReplicateSegment)
.where(
ShotReplicateSegment.task_set_id == task_set.id,
ShotReplicateSegment.deleted_at.is_(None),
)
)
if int(active_segments_result.scalar() or 0) > 0:
raise HTTPException(status_code=409, detail="当前总任务集已存在拆镜片段,不能强制重跑原视频分析")
task_set.status = ShotTaskSetStatusEnum.PENDING_ANALYSIS.value
task_set.analysis_status = ShotAnalysisStatusEnum.PENDING.value
task_set.analysis_error_message = None
task_set.original_video_content = None
task_set.original_video_category = None
task_set.original_video_audience = None
task_set.ai_suggestion_json = None
task_set.analysis_raw_json = None
task_set.analysis_result_json = None
await db.flush()
log_module_event_file(
module=MODULE,
event_type=ShotReplicateLogEventEnum.TASK_SET_REANALYZE_RECEIVED.value,
project_id=task_set.id,
user_id=task_set.user_id,
message="原视频再次分析已重置状态",
detail={"task_set_id": task_set.id, "force": force, "reason": reason, "video_url": task_set.video_url},
)
return ShotReanalyzeOut(
message="原视频再次分析任务已准备投递",
task_set_id=task_set.id,
segment_id=None,
analysis_status=task_set.analysis_status,
celery_task_name="shot_replicate.analyze_original_video",
)
async def prepare_reanalyze_segment(
db: AsyncSession,
*,
current_user: User,
segment_id: str,
force: bool = False,
reason: str | None = None,
) -> ShotReanalyzeOut:
"""重置自定义切片视频分析状态,供 API 重新投递 Celery。"""
segment = await get_segment_for_user(db, segment_id=segment_id, user=current_user, for_update=True)
if segment.split_status != ShotSplitStatusEnum.COMPLETED.value:
raise HTTPException(status_code=409, detail="当前片段还未切割完成,不能再次分析")
if not segment.segment_video_url:
raise HTTPException(status_code=409, detail="当前片段缺少 segment_video_url,不能再次分析")
if segment.analysis_status == ShotSegmentAnalysisStatusEnum.PROCESSING.value:
log_module_event_file(
module=MODULE,
event_type=ShotReplicateLogEventEnum.SEGMENT_REANALYZE_REJECTED.value,
project_id=segment.task_set_id,
step_id=segment.id,
user_id=segment.user_id,
message="切片视频分析正在处理中,拒绝再次分析",
detail={"segment_id": segment.id, "analysis_status": segment.analysis_status, "reason": reason},
event_status="rejected",
)
raise HTTPException(status_code=409, detail="切片视频分析正在处理中,不能重复投递")
if segment.analysis_status == ShotSegmentAnalysisStatusEnum.COMPLETED.value and not force:
raise HTTPException(status_code=409, detail="切片视频分析已完成,如确需重跑请传 force=true")
if segment.source_mode != ShotSegmentSourceModeEnum.CUSTOM.value and not force:
raise HTTPException(status_code=409, detail="AI 建议片段默认无需单独分析,如确需重跑请传 force=true")
segment.analysis_status = ShotSegmentAnalysisStatusEnum.PENDING.value
segment.analysis_error_message = None
segment.analysis_json = None
segment.original_video_content = None
segment.original_video_category = None
segment.original_video_audience = None
segment.segment_content = None
segment.segment_category = None
segment.segment_audience = None
await db.flush()
log_module_event_file(
module=MODULE,
event_type=ShotReplicateLogEventEnum.SEGMENT_REANALYZE_RECEIVED.value,
project_id=segment.task_set_id,
step_id=segment.id,
user_id=segment.user_id,
message="切片视频再次分析已重置状态",
detail={"segment_id": segment.id, "task_set_id": segment.task_set_id, "force": force, "reason": reason, "video_url": segment.segment_video_url},
)
return ShotReanalyzeOut(
message="切片视频再次分析任务已准备投递",
task_set_id=segment.task_set_id,
segment_id=segment.id,
analysis_status=segment.analysis_status,
celery_task_name="shot_replicate.analyze_custom_segment_video",
)