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';
    }
}