base.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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. Base Pipeline for Video Generation
  14. All custom pipelines should inherit from BasePipeline.
  15. """
  16. from abc import ABC, abstractmethod
  17. from typing import Optional, Callable
  18. from loguru import logger
  19. from pixelle_video.models.progress import ProgressEvent
  20. from pixelle_video.models.storyboard import VideoGenerationResult
  21. class BasePipeline(ABC):
  22. """
  23. Base pipeline for video generation
  24. All custom pipelines should inherit from this class and implement __call__.
  25. Design principles:
  26. - Each pipeline represents a complete video generation workflow
  27. - Pipelines are independent and can have completely different logic
  28. - Pipelines have access to all core services via self.core
  29. - Pipelines should report progress via progress_callback
  30. Example:
  31. >>> class MyPipeline(BasePipeline):
  32. ... async def __call__(self, text: str, **kwargs):
  33. ... # Step 1: Generate content
  34. ... narrations = await some_logic(text)
  35. ...
  36. ... # Step 2: Process frames
  37. ... for narration in narrations:
  38. ... audio = await self.core.tts(narration)
  39. ... # ...
  40. ...
  41. ... return VideoGenerationResult(...)
  42. """
  43. def __init__(self, pixelle_video_core):
  44. """
  45. Initialize pipeline with core services
  46. Args:
  47. pixelle_video_core: PixelleVideoCore instance (provides access to all services)
  48. """
  49. self.core = pixelle_video_core
  50. # Quick access to services (convenience)
  51. self.llm = pixelle_video_core.llm
  52. self.tts = pixelle_video_core.tts
  53. self.media = pixelle_video_core.media
  54. self.video = pixelle_video_core.video
  55. # Backward compatibility alias
  56. self.image = pixelle_video_core.media
  57. @abstractmethod
  58. async def __call__(
  59. self,
  60. text: str,
  61. progress_callback: Optional[Callable[[ProgressEvent], None]] = None,
  62. **kwargs
  63. ) -> VideoGenerationResult:
  64. """
  65. Execute the pipeline
  66. Args:
  67. text: Input text (meaning varies by pipeline)
  68. progress_callback: Optional callback for progress updates (receives ProgressEvent)
  69. **kwargs: Pipeline-specific parameters
  70. Returns:
  71. VideoGenerationResult with video path and metadata
  72. Raises:
  73. Exception: Pipeline-specific exceptions
  74. """
  75. pass
  76. def _report_progress(
  77. self,
  78. callback: Optional[Callable[[ProgressEvent], None]],
  79. event_type: str,
  80. progress: float,
  81. **kwargs
  82. ):
  83. """
  84. Report progress via callback
  85. Args:
  86. callback: Progress callback function
  87. event_type: Type of progress event
  88. progress: Progress value (0.0-1.0)
  89. **kwargs: Additional event-specific parameters (frame_current, frame_total, etc.)
  90. """
  91. if callback:
  92. event = ProgressEvent(event_type=event_type, progress=progress, **kwargs)
  93. callback(event)
  94. logger.debug(f"Progress: {progress*100:.0f}% - {event_type}")
  95. else:
  96. logger.debug(f"Progress: {progress*100:.0f}% - {event_type}")