shouldAutoApplyBgm($post)) { return false; } $bgm = data_get($post->meta, 'bgm', []); $prompt = trim((string) data_get($bgm, 'prompt', '')); if ($prompt === '') { throw new \RuntimeException('BGM auto aktif, tapi prompt musik masih kosong. Isi dulu sebelum publish otomatis dijalankan.'); } $duration = (int) data_get($bgm, 'duration', 15); $volume = (float) data_get($bgm, 'volume', 0.24); $sourceVideoUrl = (string) $post->video_url; $track = $this->music->generate($prompt, $duration); $mixed = $this->composer->compose($sourceVideoUrl, (string) ($track['url'] ?? ''), $volume); $meta = is_array($post->meta) ? $post->meta : []; $meta['bgm'] = array_merge($bgm, [ 'provider' => 'freepik', 'applied' => true, 'applied_at' => now()->toIso8601String(), 'mixed_video_url' => (string) ($mixed['url'] ?? ''), 'track_url' => (string) ($track['url'] ?? ''), ]); $post->update([ 'video_url' => (string) ($mixed['url'] ?? $post->video_url), 'meta' => $meta, ]); SocialMediaAsset::query()->create([ 'user_id' => $post->user_id, 'type' => 'video', 'provider' => 'freepik-music-mix', 'prompt' => $prompt, 'url' => (string) ($mixed['url'] ?? ''), 'thumbnail_url' => null, 'width' => 1080, 'height' => 1920, 'duration_seconds' => (int) ($track['duration_seconds'] ?? $duration), 'meta' => [ 'source_post_id' => $post->id, 'source_video_url' => $sourceVideoUrl, 'music_url' => $track['url'] ?? null, 'music_provider' => 'freepik', 'music_duration' => $duration, 'music_volume' => $volume, 'source' => 'pre_publish_automation', ], ]); return true; } public function shouldAutoApplyBgm(SocialPost $post): bool { if (blank($post->video_url)) { return false; } $bgm = data_get($post->meta, 'bgm', []); return (bool) data_get($bgm, 'enabled', false) && ! (bool) data_get($bgm, 'applied', false) && data_get($bgm, 'provider', 'freepik') === 'freepik'; } }