mirror of
https://github.com/Hommy-master/capcut-mate.git
synced 2026-09-01 15:32:57 +08:00
新增加添加遮罩的接口。
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
# 添加遮罩接口文档
|
||||
|
||||
## 接口概述
|
||||
向现有草稿中的指定片段添加遮罩效果。遮罩是视频编辑中的重要功能,通过遮罩可以控制图像的可见区域,创造出各种视觉效果。支持多种遮罩类型(线性、镜面、圆形、矩形、爱心、星形),每种遮罩都可以精确配置位置、大小、羽化、旋转等属性。
|
||||
|
||||
## 接口信息
|
||||
- **请求方式**: POST
|
||||
- **接口路径**: `/v1/add_masks`
|
||||
- **Content-Type**: `application/json`
|
||||
|
||||
## 请求参数
|
||||
|
||||
### 请求体 (Body)
|
||||
|
||||
| 参数名 | 类型 | 必填 | 默认值 | 描述 |
|
||||
|--------|------|------|--------|------|
|
||||
| draft_url | string | 是 | "" | 目标草稿的完整URL |
|
||||
| segment_ids | array | 是 | [] | 要应用遮罩的片段ID数组 |
|
||||
| name | string | 否 | "线性" | 遮罩类型名称 |
|
||||
| X | integer | 否 | 0 | 遮罩中心X坐标(像素) |
|
||||
| Y | integer | 否 | 0 | 遮罩中心Y坐标(像素) |
|
||||
| width | integer | 否 | 512 | 遮罩宽度(像素) |
|
||||
| height | integer | 否 | 512 | 遮罩高度(像素) |
|
||||
| feather | integer | 否 | 0 | 羽化程度(0-100) |
|
||||
| rotation | integer | 否 | 0 | 旋转角度(度) |
|
||||
| invert | boolean | 否 | false | 是否反转遮罩 |
|
||||
| roundCorner | integer | 否 | 0 | 圆角半径(0-100) |
|
||||
|
||||
### 支持的遮罩类型
|
||||
|
||||
| 遮罩名称 | 描述 | 适用场景 |
|
||||
|----------|------|----------|
|
||||
| 线性 | 线性渐变遮罩 | 线性过渡效果、渐变显示隐藏 |
|
||||
| 镜面 | 镜像对称遮罩 | 对称效果、镜像反射 |
|
||||
| 圆形 | 圆形遮罩 | 聚光灯效果、圆形裁剪 |
|
||||
| 矩形 | 矩形遮罩 | 窗口效果、矩形裁剪 |
|
||||
| 爱心 | 爱心形状遮罩 | 浪漫场景、特殊形状裁剪 |
|
||||
| 星形 | 星形遮罩 | 闪光效果、装饰性裁剪 |
|
||||
|
||||
### 遮罩配置详解
|
||||
|
||||
- **位置控制**: X、Y参数控制遮罩在画面中的位置
|
||||
- **尺寸控制**: width、height控制遮罩的大小
|
||||
- **羽化效果**: feather参数控制边缘的柔化程度,值越大边缘越柔和
|
||||
- **旋转变换**: rotation参数控制遮罩的旋转角度
|
||||
- **反转效果**: invert参数可以反转遮罩的显示/隐藏区域
|
||||
- **圆角处理**: roundCorner参数为矩形遮罩添加圆角效果
|
||||
|
||||
## 请求示例
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/v1/add_masks" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=7427078525303048221",
|
||||
"segment_ids": ["d62994b4-25fe-422a-a123-87ef05038558", "e73995c5-36ef-533b-b234-98fg16149669"],
|
||||
"name": "圆形",
|
||||
"X": 100,
|
||||
"Y": 200,
|
||||
"width": 300,
|
||||
"height": 300,
|
||||
"feather": 20,
|
||||
"rotation": 0,
|
||||
"invert": false,
|
||||
"roundCorner": 0
|
||||
}'
|
||||
```
|
||||
|
||||
## 响应格式
|
||||
|
||||
### 成功响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "Success",
|
||||
"data": {
|
||||
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=7427078525303048221",
|
||||
"masks_added": 2,
|
||||
"affected_segments": ["d62994b4-25fe-422a-a123-87ef05038558", "e73995c5-36ef-533b-b234-98fg16149669"],
|
||||
"mask_ids": ["mask_001", "mask_002"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**响应字段说明**:
|
||||
- `draft_url`: 草稿URL
|
||||
- `masks_added`: 成功添加的遮罩数量
|
||||
- `affected_segments`: 受影响的片段ID列表
|
||||
- `mask_ids`: 遮罩ID列表
|
||||
|
||||
### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 2023,
|
||||
"message": "无效的遮罩信息,请检查遮罩参数是否正确"
|
||||
}
|
||||
```
|
||||
|
||||
## 错误码说明
|
||||
|
||||
| 错误码 | 错误信息 | 描述 |
|
||||
|--------|----------|------|
|
||||
| 2001 | 无效的草稿URL | 草稿URL格式错误或草稿不存在 |
|
||||
| 2015 | 片段未找到 | 指定的segment_id不存在 |
|
||||
| 2016 | 无效的片段类型 | 片段类型不支持添加遮罩 |
|
||||
| 2023 | 无效的遮罩信息 | 遮罩参数格式错误或值无效 |
|
||||
| 2024 | 遮罩添加失败 | 添加遮罩过程中发生错误 |
|
||||
| 2025 | 遮罩类型未找到 | 指定的遮罩名称不存在 |
|
||||
|
||||
## 使用说明
|
||||
|
||||
1. **片段要求**: 只有视频片段(VideoSegment)支持添加遮罩
|
||||
2. **遮罩限制**: 每个片段只能添加一个遮罩,重复添加会失败
|
||||
3. **坐标系统**: X、Y坐标以像素为单位,原点位于素材中心
|
||||
4. **参数范围**:
|
||||
- feather: 0-100,羽化程度
|
||||
- rotation: 0-360度,旋转角度
|
||||
- roundCorner: 0-100,圆角半径(仅矩形遮罩有效)
|
||||
5. **批量处理**: 支持同时为多个片段添加相同配置的遮罩
|
||||
|
||||
## 应用场景
|
||||
|
||||
### 创意视觉效果
|
||||
- **聚光灯效果**: 使用圆形遮罩突出画面重点
|
||||
- **窗口效果**: 使用矩形遮罩创建窗口视觉
|
||||
- **浪漫场景**: 使用爱心遮罩营造浪漫氛围
|
||||
- **装饰效果**: 使用星形遮罩增加装饰元素
|
||||
|
||||
### 画面过渡
|
||||
- **渐变显示**: 使用线性遮罩实现渐进显示效果
|
||||
- **对称效果**: 使用镜面遮罩创建对称视觉
|
||||
- **柔和边缘**: 通过羽化参数实现柔和的边缘过渡
|
||||
|
||||
### 内容遮挡
|
||||
- **隐私保护**: 遮挡敏感信息区域
|
||||
- **焦点引导**: 突出重要内容,弱化无关区域
|
||||
- **艺术创作**: 创造独特的视觉艺术效果
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 遮罩效果只对视频片段有效,不支持音频、文本或贴纸片段
|
||||
- 添加遮罩后会影响片段的视觉呈现,请确保遮罩配置符合预期
|
||||
- 遮罩参数的单位和坐标系以素材自身为基准
|
||||
- 建议在添加遮罩前预览效果,确保达到预期的视觉效果
|
||||
- 遮罩的渲染性能可能影响导出速度,请根据需要合理使用
|
||||
|
||||
## 相关接口
|
||||
|
||||
- [创建草稿](./create_draft.md) - 创建新的剪映草稿
|
||||
- [添加视频](./add_videos.md) - 向草稿添加视频内容
|
||||
- [添加特效](./add_effects.md) - 向草稿添加视频特效
|
||||
- [保存草稿](./save_draft.md) - 保存草稿更改
|
||||
@@ -34,6 +34,9 @@ class CustomError(Enum):
|
||||
INVALID_EFFECT_INFO = (2020, "无效的特效信息,请检查effect_infos字段值是否正确", "Invalid effect information, please check if the value of the effect_infos field is correct.")
|
||||
EFFECT_ADD_FAILED = (2021, "特效添加失败", "Effect addition failed")
|
||||
EFFECT_NOT_FOUND = (2022, "特效未找到,请检查特效名称是否正确", "Effect not found, please check if the effect name is correct.")
|
||||
INVALID_MASK_INFO = (2023, "无效的遮罩信息,请检查遮罩参数是否正确", "Invalid mask information, please check if mask parameters are correct.")
|
||||
MASK_ADD_FAILED = (2024, "遮罩添加失败", "Mask addition failed")
|
||||
MASK_NOT_FOUND = (2025, "遮罩类型未找到,请检查遮罩名称是否正确", "Mask type not found, please check if the mask name is correct.")
|
||||
|
||||
# ===== 系统错误码 (9000-9999) =====
|
||||
INTERNAL_SERVER_ERROR = (9998, "系统内部错误", "Internal server error")
|
||||
|
||||
@@ -7,6 +7,7 @@ from src.schemas.add_sticker import AddStickerResponse
|
||||
from src.schemas.add_keyframes import AddKeyframesResponse
|
||||
from src.schemas.add_captions import AddCaptionsResponse
|
||||
from src.schemas.add_effects import AddEffectsResponse
|
||||
from src.schemas.add_masks import AddMasksResponse
|
||||
from src.schemas.save_draft import SaveDraftResponse
|
||||
from src.schemas.create_draft import CreateDraftResponse
|
||||
from fastapi import APIRouter, Request, Depends
|
||||
@@ -18,6 +19,7 @@ from src.schemas.add_sticker import AddStickerRequest, AddStickerResponse
|
||||
from src.schemas.add_keyframes import AddKeyframesRequest, AddKeyframesResponse
|
||||
from src.schemas.add_captions import AddCaptionsRequest, AddCaptionsResponse
|
||||
from src.schemas.add_effects import AddEffectsRequest, AddEffectsResponse
|
||||
from src.schemas.add_masks import AddMasksRequest, AddMasksResponse
|
||||
from src.schemas.save_draft import SaveDraftRequest, SaveDraftResponse
|
||||
from src.schemas.gen_video import GenVideoRequest, GenVideoResponse
|
||||
from src.schemas.get_draft import GetDraftRequest, GetDraftResponse
|
||||
@@ -206,6 +208,34 @@ def add_effects(aer: AddEffectsRequest) -> AddEffectsResponse:
|
||||
segment_ids=segment_ids
|
||||
)
|
||||
|
||||
@router.post(path="/add_masks", response_model=AddMasksResponse)
|
||||
def add_masks(amr: AddMasksRequest) -> AddMasksResponse:
|
||||
"""
|
||||
向剪映草稿添加遮罩 (v1版本)
|
||||
"""
|
||||
|
||||
# 调用service层处理业务逻辑
|
||||
draft_url, masks_added, affected_segments, mask_ids = service.add_masks(
|
||||
draft_url=amr.draft_url,
|
||||
segment_ids=amr.segment_ids,
|
||||
name=amr.name,
|
||||
X=amr.X,
|
||||
Y=amr.Y,
|
||||
width=amr.width,
|
||||
height=amr.height,
|
||||
feather=amr.feather,
|
||||
rotation=amr.rotation,
|
||||
invert=amr.invert,
|
||||
roundCorner=amr.roundCorner
|
||||
)
|
||||
|
||||
return AddMasksResponse(
|
||||
draft_url=draft_url,
|
||||
masks_added=masks_added,
|
||||
affected_segments=affected_segments,
|
||||
mask_ids=mask_ids
|
||||
)
|
||||
|
||||
@router.get(path="/get_draft", response_model=GetDraftResponse)
|
||||
def get_draft(params: Annotated[GetDraftRequest, Depends()]) -> GetDraftResponse:
|
||||
"""
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import List
|
||||
|
||||
|
||||
class AddMasksRequest(BaseModel):
|
||||
"""添加遮罩请求参数"""
|
||||
draft_url: str = Field(default="", description="草稿URL")
|
||||
segment_ids: List[str] = Field(default=[], description="要应用遮罩的片段ID数组")
|
||||
name: str = Field(default="线性", description="遮罩类型名称")
|
||||
X: int = Field(default=0, description="遮罩中心X坐标(像素)")
|
||||
Y: int = Field(default=0, description="遮罩中心Y坐标(像素)")
|
||||
width: int = Field(default=512, description="遮罩宽度(像素)")
|
||||
height: int = Field(default=512, description="遮罩高度(像素)")
|
||||
feather: int = Field(default=0, description="羽化程度(0-100)")
|
||||
rotation: int = Field(default=0, description="旋转角度(度)")
|
||||
invert: bool = Field(default=False, description="是否反转遮罩")
|
||||
roundCorner: int = Field(default=0, description="圆角半径(0-100)")
|
||||
|
||||
|
||||
class AddMasksResponse(BaseModel):
|
||||
"""添加遮罩响应参数"""
|
||||
draft_url: str = Field(default="", description="草稿URL")
|
||||
masks_added: int = Field(default=0, description="成功添加的遮罩数量")
|
||||
affected_segments: List[str] = Field(default=[], description="受影响的片段ID列表")
|
||||
mask_ids: List[str] = Field(default=[], description="遮罩ID列表")
|
||||
@@ -6,8 +6,9 @@ from .add_sticker import add_sticker
|
||||
from .add_keyframes import add_keyframes
|
||||
from .add_captions import add_captions
|
||||
from .add_effects import add_effects
|
||||
from .add_masks import add_masks
|
||||
from .save_draft import save_draft
|
||||
from .gen_video import gen_video
|
||||
from .get_draft import get_draft
|
||||
|
||||
__all__ = ["create_draft", "add_videos", "add_audios", "add_images", "add_sticker", "add_keyframes", "add_captions", "add_effects", "save_draft", "gen_video", "get_draft"]
|
||||
__all__ = ["create_draft", "add_videos", "add_audios", "add_images", "add_sticker", "add_keyframes", "add_captions", "add_effects", "add_masks", "save_draft", "gen_video", "get_draft"]
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
from typing import List, Dict, Any, Tuple, Optional
|
||||
from src.utils.logger import logger
|
||||
from src.pyJianYingDraft import ScriptFile, MaskType
|
||||
from src.pyJianYingDraft.video_segment import VideoSegment
|
||||
from src.pyJianYingDraft.segment import VisualSegment
|
||||
from src.utils.draft_cache import DRAFT_CACHE
|
||||
from exceptions import CustomException, CustomError
|
||||
from src.utils import helper
|
||||
|
||||
|
||||
def add_masks(
|
||||
draft_url: str,
|
||||
segment_ids: List[str],
|
||||
name: str = "线性",
|
||||
X: int = 0,
|
||||
Y: int = 0,
|
||||
width: int = 512,
|
||||
height: int = 512,
|
||||
feather: int = 0,
|
||||
rotation: int = 0,
|
||||
invert: bool = False,
|
||||
roundCorner: int = 0
|
||||
) -> Tuple[str, int, List[str], List[str]]:
|
||||
"""
|
||||
向现有草稿中的指定片段添加遮罩效果的业务逻辑
|
||||
|
||||
Args:
|
||||
draft_url: 草稿URL,必选参数
|
||||
segment_ids: 要应用遮罩的片段ID数组,必选参数
|
||||
name: 遮罩类型名称,默认值:"线性"。支持:"线性", "镜面", "圆形", "矩形", "爱心", "星形"
|
||||
X: 遮罩中心X坐标(像素),默认值:0
|
||||
Y: 遮罩中心Y坐标(像素),默认值:0
|
||||
width: 遮罩宽度(像素),默认值:512
|
||||
height: 遮罩高度(像素),默认值:512
|
||||
feather: 羽化程度(0-100),默认值:0
|
||||
rotation: 旋转角度(度),默认值:0
|
||||
invert: 是否反转遮罩,默认值:false
|
||||
roundCorner: 圆角半径(0-100),默认值:0
|
||||
|
||||
Returns:
|
||||
Tuple[str, int, List[str], List[str]]: 返回元组包含以下信息
|
||||
- draft_url: 草稿URL
|
||||
- masks_added: 成功添加的遮罩数量
|
||||
- affected_segments: 受影响的片段ID列表
|
||||
- mask_ids: 遮罩ID列表
|
||||
|
||||
Raises:
|
||||
CustomException: 遮罩添加失败
|
||||
"""
|
||||
logger.info(f"add_masks started, draft_url: {draft_url}, segment_ids: {segment_ids}, mask_name: {name}")
|
||||
|
||||
# 1. 提取草稿ID
|
||||
draft_id = helper.get_url_param(draft_url, "draft_id")
|
||||
if (not draft_id) or (draft_id not in DRAFT_CACHE):
|
||||
logger.error(f"Invalid draft_url or draft not found in cache: {draft_url}")
|
||||
raise CustomException(CustomError.INVALID_DRAFT_URL)
|
||||
|
||||
# 2. 验证片段ID列表
|
||||
if not segment_ids or len(segment_ids) == 0:
|
||||
logger.error("No segment_ids provided")
|
||||
raise CustomException(CustomError.INVALID_MASK_INFO)
|
||||
|
||||
logger.info(f"Processing {len(segment_ids)} segments for mask addition")
|
||||
|
||||
# 3. 从缓存中获取草稿
|
||||
script: ScriptFile = DRAFT_CACHE[draft_id]
|
||||
|
||||
# 4. 查找遮罩类型
|
||||
mask_type = find_mask_type_by_name(name)
|
||||
if mask_type is None:
|
||||
logger.error(f"Mask type not found for name: {name}")
|
||||
raise CustomException(CustomError.MASK_NOT_FOUND)
|
||||
|
||||
# 5. 遍历片段ID,为每个片段添加遮罩
|
||||
masks_added = 0
|
||||
affected_segments: List[str] = []
|
||||
mask_ids: List[str] = []
|
||||
|
||||
for i, segment_id in enumerate(segment_ids):
|
||||
try:
|
||||
logger.info(f"Processing segment {i+1}/{len(segment_ids)}, segment_id: {segment_id}")
|
||||
|
||||
mask_id = add_mask_to_segment(
|
||||
script=script,
|
||||
segment_id=segment_id,
|
||||
mask_type=mask_type,
|
||||
center_x=X,
|
||||
center_y=Y,
|
||||
width=width,
|
||||
height=height,
|
||||
feather=feather,
|
||||
rotation=rotation,
|
||||
invert=invert,
|
||||
round_corner=roundCorner
|
||||
)
|
||||
|
||||
masks_added += 1
|
||||
affected_segments.append(segment_id)
|
||||
mask_ids.append(mask_id)
|
||||
logger.info(f"Added mask to segment {i+1}/{len(segment_ids)}, mask_id: {mask_id}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to add mask to segment {i+1}/{len(segment_ids)}, segment_id: {segment_id}, error: {str(e)}")
|
||||
raise
|
||||
|
||||
# 6. 保存草稿
|
||||
script.save()
|
||||
logger.info(f"Draft saved successfully")
|
||||
|
||||
logger.info(f"add_masks completed successfully - draft_id: {draft_id}, masks_added: {masks_added}")
|
||||
|
||||
return draft_url, masks_added, affected_segments, mask_ids
|
||||
|
||||
|
||||
def add_mask_to_segment(
|
||||
script: ScriptFile,
|
||||
segment_id: str,
|
||||
mask_type: MaskType,
|
||||
center_x: int = 0,
|
||||
center_y: int = 0,
|
||||
width: int = 512,
|
||||
height: int = 512,
|
||||
feather: int = 0,
|
||||
rotation: int = 0,
|
||||
invert: bool = False,
|
||||
round_corner: int = 0
|
||||
) -> str:
|
||||
"""
|
||||
向指定片段添加遮罩
|
||||
|
||||
Args:
|
||||
script: 草稿文件对象
|
||||
segment_id: 目标片段ID
|
||||
mask_type: 遮罩类型
|
||||
center_x: 遮罩中心X坐标(像素)
|
||||
center_y: 遮罩中心Y坐标(像素)
|
||||
width: 遮罩宽度(像素)
|
||||
height: 遮罩高度(像素)
|
||||
feather: 羽化程度(0-100)
|
||||
rotation: 旋转角度(度)
|
||||
invert: 是否反转遮罩
|
||||
round_corner: 圆角半径(0-100)
|
||||
|
||||
Returns:
|
||||
mask_id: 遮罩ID
|
||||
|
||||
Raises:
|
||||
CustomException: 添加遮罩失败
|
||||
"""
|
||||
try:
|
||||
# 1. 查找片段
|
||||
segment = find_segment_by_id(script, segment_id)
|
||||
if segment is None:
|
||||
logger.error(f"Segment not found: {segment_id}")
|
||||
raise CustomException(CustomError.SEGMENT_NOT_FOUND)
|
||||
|
||||
# 2. 验证片段类型(只有VideoSegment支持遮罩)
|
||||
if not isinstance(segment, VideoSegment):
|
||||
logger.error(f"Segment {segment_id} is not a video segment, cannot add mask")
|
||||
raise CustomException(CustomError.INVALID_SEGMENT_TYPE)
|
||||
|
||||
# 3. 检查片段是否已有遮罩
|
||||
if segment.mask is not None:
|
||||
logger.error(f"Segment {segment_id} already has a mask")
|
||||
raise CustomException(CustomError.MASK_ADD_FAILED)
|
||||
|
||||
# 4. 计算遮罩尺寸参数
|
||||
# 根据 add_mask 方法的要求,size 是主要尺寸(以占素材高度的比例表示)
|
||||
material_width, material_height = segment.material_size
|
||||
size = height / material_height # 高度比例
|
||||
rect_width = width / material_width if mask_type == MaskType.矩形 else None
|
||||
|
||||
logger.info(f"Adding mask to segment {segment_id}: type={mask_type.value.name}, center=({center_x}, {center_y}), size={size}")
|
||||
logger.info(f"Mask details - width: {width}, height: {height}, feather: {feather}, rotation: {rotation}, invert: {invert}, round_corner: {round_corner}")
|
||||
|
||||
# 5. 添加遮罩到片段
|
||||
segment.add_mask(
|
||||
mask_type=mask_type,
|
||||
center_x=float(center_x),
|
||||
center_y=float(center_y),
|
||||
size=size,
|
||||
rotation=float(rotation),
|
||||
feather=float(feather),
|
||||
invert=invert,
|
||||
rect_width=rect_width,
|
||||
round_corner=float(round_corner)
|
||||
)
|
||||
|
||||
mask_id = segment.mask.global_id if segment.mask is not None else ""
|
||||
if not mask_id:
|
||||
logger.error(f"Failed to create mask for segment {segment_id}")
|
||||
raise CustomException(CustomError.MASK_ADD_FAILED)
|
||||
|
||||
logger.info(f"Successfully added mask to segment {segment_id}, mask_id: {mask_id}")
|
||||
|
||||
return mask_id
|
||||
|
||||
except CustomException:
|
||||
logger.error(f"Add mask to segment failed, segment_id: {segment_id}")
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Add mask to segment failed, error: {str(e)}")
|
||||
raise CustomException(CustomError.MASK_ADD_FAILED)
|
||||
|
||||
|
||||
def find_segment_by_id(script: ScriptFile, segment_id: str) -> Optional[VisualSegment]:
|
||||
"""
|
||||
通过segment_id在草稿中查找对应的片段
|
||||
|
||||
Args:
|
||||
script: 草稿文件对象
|
||||
segment_id: 片段ID
|
||||
|
||||
Returns:
|
||||
找到的片段对象,如果未找到则返回None
|
||||
"""
|
||||
logger.info(f"Searching for segment with id: {segment_id}")
|
||||
|
||||
# 遍历所有轨道
|
||||
for track_name, track in script.tracks.items():
|
||||
logger.info(f"Searching in track: {track_name}, segments count: {len(track.segments)}")
|
||||
|
||||
# 遍历轨道中的所有片段
|
||||
for segment in track.segments:
|
||||
if segment.segment_id == segment_id:
|
||||
logger.info(f"Found segment {segment_id} in track {track_name}")
|
||||
return segment
|
||||
|
||||
logger.warning(f"Segment {segment_id} not found in any track")
|
||||
return None
|
||||
|
||||
|
||||
def find_mask_type_by_name(mask_name: str) -> Optional[MaskType]:
|
||||
"""
|
||||
根据遮罩名称查找对应的遮罩类型
|
||||
|
||||
Args:
|
||||
mask_name: 遮罩名称
|
||||
|
||||
Returns:
|
||||
对应的遮罩类型枚举,如果未找到则返回None
|
||||
"""
|
||||
logger.info(f"Searching for mask type with name: {mask_name}")
|
||||
|
||||
# 搜索MaskType中的遮罩
|
||||
for mask_type in MaskType:
|
||||
if mask_type.value.name == mask_name:
|
||||
logger.info(f"Found mask type: {mask_name}")
|
||||
return mask_type
|
||||
|
||||
logger.warning(f"Mask type not found for name: {mask_name}")
|
||||
return None
|
||||
Reference in New Issue
Block a user