File size: 1,775 Bytes
74acf19 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | <?php
namespace App\Services;
class HuggingFaceVideoService
{
public function __construct(
private HuggingFaceImageService $huggingFaceImage,
private MotionVideoService $motionVideo,
) {
}
public function generate(?string $sourceImageUrl, string $prompt, array $options = []): array
{
$cleanPrompt = trim($prompt);
$usesGeneratedFrame = false;
$imageUrl = trim((string) $sourceImageUrl);
if ($imageUrl === '') {
$images = $this->huggingFaceImage->generate($cleanPrompt, $this->resolveAspect($options), 1);
$imageUrl = trim((string) ($images[0] ?? ''));
$usesGeneratedFrame = true;
}
$video = $this->motionVideo->createFromImageUrl($imageUrl, $cleanPrompt, $options);
return [
'url' => $video['url'] ?? null,
'provider' => 'huggingface-motion',
'aspect' => $video['aspect'] ?? ($options['aspect_ratio'] ?? '16:9'),
'prompt' => $cleanPrompt,
'duration_seconds' => $video['duration_seconds'] ?? 8,
'source_image_url' => $imageUrl,
'applied_settings' => array_merge((array) ($video['applied_settings'] ?? []), [
'video_provider' => 'huggingface',
]),
'notice' => $usesGeneratedFrame
? 'Start frame dibuat lewat Hugging Face, lalu dianimasikan dengan motion renderer lokal.'
: 'Source frame dipakai langsung, lalu dirender ke video dengan pipeline Hugging Face/local motion.',
'async' => false,
];
}
private function resolveAspect(array $options): string
{
return (($options['aspect_ratio'] ?? '16:9') === '9:16') ? 'portrait' : 'landscape';
}
} |