frame.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. Frame/Template rendering endpoints
  14. """
  15. from fastapi import APIRouter, HTTPException
  16. from loguru import logger
  17. from api.dependencies import PixelleVideoDep
  18. from api.schemas.frame import FrameRenderRequest, FrameRenderResponse, TemplateParamsResponse
  19. from pixelle_video.services.frame_html import HTMLFrameGenerator
  20. from pixelle_video.utils.template_util import parse_template_size, resolve_template_path
  21. router = APIRouter(prefix="/frame", tags=["Frame Rendering"])
  22. @router.post("/render", response_model=FrameRenderResponse)
  23. async def render_frame(
  24. request: FrameRenderRequest,
  25. pixelle_video: PixelleVideoDep
  26. ):
  27. """
  28. Render a single frame using HTML template
  29. Generates a frame image by combining template, title, text, and image.
  30. This is useful for previewing templates or generating custom frames.
  31. - **template**: Template key (e.g., '1080x1920/default.html')
  32. - **title**: Optional title text
  33. - **text**: Frame text content
  34. - **image**: Image path (can be local path or URL)
  35. Returns path to generated frame image.
  36. Example:
  37. ```json
  38. {
  39. "template": "1080x1920/modern.html",
  40. "title": "Welcome",
  41. "text": "This is a beautiful frame with custom styling",
  42. "image": "resources/example.png"
  43. }
  44. ```
  45. """
  46. try:
  47. logger.info(f"Frame render request: template={request.template}")
  48. # Resolve template path (returns absolute path with "templates/" or "data/templates/" prefix)
  49. template_path = resolve_template_path(request.template)
  50. # Parse template size
  51. width, height = parse_template_size(template_path)
  52. # Create HTML frame generator
  53. generator = HTMLFrameGenerator(template_path)
  54. # Generate frame
  55. frame_path = await generator.generate_frame(
  56. title=request.title,
  57. text=request.text,
  58. image=request.image
  59. )
  60. return FrameRenderResponse(
  61. frame_path=frame_path,
  62. width=width,
  63. height=height
  64. )
  65. except Exception as e:
  66. logger.error(f"Frame render error: {e}")
  67. raise HTTPException(status_code=500, detail=str(e))
  68. @router.get("/template/params", response_model=TemplateParamsResponse)
  69. async def get_template_params(
  70. template: str
  71. ):
  72. """
  73. Get custom parameters for a template
  74. Returns the custom parameters defined in the template HTML file.
  75. These parameters can be passed via `template_params` in video generation requests.
  76. Template parameters are defined using syntax: `{{param_name:type=default}}`
  77. Supported types:
  78. - `text`: String input
  79. - `number`: Numeric input
  80. - `color`: Color picker (hex format)
  81. - `bool`: Boolean checkbox
  82. Example template syntax:
  83. ```html
  84. <div style="color: {{accent_color:color=#ff0000}}">
  85. {{custom_text:text=Hello World}}
  86. </div>
  87. ```
  88. Args:
  89. template: Template path (e.g., '1080x1920/image_default.html')
  90. Returns:
  91. Template parameters with their types, defaults, and labels
  92. Example response:
  93. ```json
  94. {
  95. "template": "1080x1920/image_default.html",
  96. "media_width": 1080,
  97. "media_height": 1440,
  98. "params": {
  99. "accent_color": {
  100. "type": "color",
  101. "default": "#ff0000",
  102. "label": "accent_color"
  103. },
  104. "background": {
  105. "type": "text",
  106. "default": "https://example.com/bg.jpg",
  107. "label": "background"
  108. }
  109. }
  110. }
  111. ```
  112. """
  113. try:
  114. logger.info(f"Get template params: {template}")
  115. # Resolve template path
  116. template_path = resolve_template_path(template)
  117. # Create generator and parse parameters
  118. generator = HTMLFrameGenerator(template_path)
  119. params = generator.parse_template_parameters()
  120. media_width, media_height = generator.get_media_size()
  121. return TemplateParamsResponse(
  122. template=template,
  123. media_width=media_width,
  124. media_height=media_height,
  125. params=params
  126. )
  127. except FileNotFoundError:
  128. raise HTTPException(status_code=404, detail=f"Template not found: {template}")
  129. except Exception as e:
  130. logger.error(f"Get template params error: {e}")
  131. raise HTTPException(status_code=500, detail=str(e))