返回 Pixelle-Video
frame.py
根目录 / api / routers / frame.py
1 # Copyright (C) 2025 AIDC-AI
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 # http://www.apache.org/licenses/LICENSE-2.0
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS,
9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 # See the License for the specific language governing permissions and
11 # limitations under the License.
12
13 """
14 Frame/Template rendering endpoints
15 """
16
17 from fastapi import APIRouter, HTTPException
18 from loguru import logger
19
20 from api.dependencies import PixelleVideoDep
21 from api.schemas.frame import FrameRenderRequest, FrameRenderResponse, TemplateParamsResponse
22 from pixelle_video.services.frame_html import HTMLFrameGenerator
23 from pixelle_video.utils.template_util import parse_template_size, resolve_template_path
24
25 router = APIRouter(prefix="/frame", tags=["Frame Rendering"])
26
27
28 @router.post("/render", response_model=FrameRenderResponse)
29 async def render_frame(
30 request: FrameRenderRequest,
31 pixelle_video: PixelleVideoDep
32 ):
33 """
34 Render a single frame using HTML template
35
36 Generates a frame image by combining template, title, text, and image.
37 This is useful for previewing templates or generating custom frames.
38
39 - **template**: Template key (e.g., '1080x1920/default.html')
40 - **title**: Optional title text
41 - **text**: Frame text content
42 - **image**: Image path (can be local path or URL)
43
44 Returns path to generated frame image.
45
46 Example:
47 ```json
48 {
49 "template": "1080x1920/modern.html",
50 "title": "Welcome",
51 "text": "This is a beautiful frame with custom styling",
52 "image": "resources/example.png"
53 }
54 ```
55 """
56 try:
57 logger.info(f"Frame render request: template={request.template}")
58
59 # Resolve template path (returns absolute path with "templates/" or "data/templates/" prefix)
60 template_path = resolve_template_path(request.template)
61
62 # Parse template size
63 width, height = parse_template_size(template_path)
64
65 # Create HTML frame generator
66 generator = HTMLFrameGenerator(template_path)
67
68 # Generate frame
69 frame_path = await generator.generate_frame(
70 title=request.title,
71 text=request.text,
72 image=request.image
73 )
74
75 return FrameRenderResponse(
76 frame_path=frame_path,
77 width=width,
78 height=height
79 )
80
81 except Exception as e:
82 logger.error(f"Frame render error: {e}")
83 raise HTTPException(status_code=500, detail=str(e))
84
85
86 @router.get("/template/params", response_model=TemplateParamsResponse)
87 async def get_template_params(
88 template: str
89 ):
90 """
91 Get custom parameters for a template
92
93 Returns the custom parameters defined in the template HTML file.
94 These parameters can be passed via `template_params` in video generation requests.
95
96 Template parameters are defined using syntax: `{{param_name:type=default}}`
97
98 Supported types:
99 - `text`: String input
100 - `number`: Numeric input
101 - `color`: Color picker (hex format)
102 - `bool`: Boolean checkbox
103
104 Example template syntax:
105 ```html
106 <div style="color: {{accent_color:color=#ff0000}}">
107 {{custom_text:text=Hello World}}
108 </div>
109 ```
110
111 Args:
112 template: Template path (e.g., '1080x1920/image_default.html')
113
114 Returns:
115 Template parameters with their types, defaults, and labels
116
117 Example response:
118 ```json
119 {
120 "template": "1080x1920/image_default.html",
121 "media_width": 1080,
122 "media_height": 1440,
123 "params": {
124 "accent_color": {
125 "type": "color",
126 "default": "#ff0000",
127 "label": "accent_color"
128 },
129 "background": {
130 "type": "text",
131 "default": "https://example.com/bg.jpg",
132 "label": "background"
133 }
134 }
135 }
136 ```
137 """
138 try:
139 logger.info(f"Get template params: {template}")
140
141 # Resolve template path
142 template_path = resolve_template_path(template)
143
144 # Create generator and parse parameters
145 generator = HTMLFrameGenerator(template_path)
146 params = generator.parse_template_parameters()
147 media_width, media_height = generator.get_media_size()
148
149 return TemplateParamsResponse(
150 template=template,
151 media_width=media_width,
152 media_height=media_height,
153 params=params
154 )
155
156 except FileNotFoundError:
157 raise HTTPException(status_code=404, detail=f"Template not found: {template}")
158 except Exception as e:
159 logger.error(f"Get template params error: {e}")
160 raise HTTPException(status_code=500, detail=str(e))
161
162
162 lines PYTHON