From 39ef9e8c142f1e022e5a1d043745ba29b20f2eb4 Mon Sep 17 00:00:00 2001 From: arys Date: Tue, 3 Mar 2026 19:23:58 +0500 Subject: [PATCH] fix --- .../service/GeminiVideoGenerationService.java | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/main/java/kz/konturai/parser/service/GeminiVideoGenerationService.java b/src/main/java/kz/konturai/parser/service/GeminiVideoGenerationService.java index 746f7c9..83fec1c 100644 --- a/src/main/java/kz/konturai/parser/service/GeminiVideoGenerationService.java +++ b/src/main/java/kz/konturai/parser/service/GeminiVideoGenerationService.java @@ -26,7 +26,8 @@ public class GeminiVideoGenerationService { private static final Logger logger = LoggerFactory.getLogger(GeminiVideoGenerationService.class); - private static final String VERTEX_API_TEMPLATE = "https://%s-aiplatform.googleapis.com/v1/projects/%s/locations/%s/publishers/google/models/%s:predictLongRunning"; + // ИСПОЛЬЗУЕМ СТРОГО v1beta1 (иначе Google не понимает операции для новых моделей) + private static final String VERTEX_API_BASE = "https://%s-aiplatform.googleapis.com/v1beta1"; private static final String CREDENTIALS_FILE_PATH = "keys/google-key.json"; private final WebClient webClient; @@ -43,7 +44,7 @@ public class GeminiVideoGenerationService { public GeminiVideoGenerationService() { HttpClient httpClient = HttpClient.create() .resolver(DefaultAddressResolverGroup.INSTANCE) - .responseTimeout(Duration.ofMillis(600000)); // 10 минут + .responseTimeout(Duration.ofMillis(600000)); ExchangeStrategies strategies = ExchangeStrategies.builder() .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(150 * 1024 * 1024)) @@ -57,7 +58,9 @@ public class GeminiVideoGenerationService { public byte[] generateVideo(String prompt) { try { - String endpointUrl = String.format(VERTEX_API_TEMPLATE, location, projectId, location, model); + // ШАГ 1: Запускаем задачу + String endpointUrl = String.format("%s/projects/%s/locations/%s/publishers/google/models/%s:predictLongRunning", + String.format(VERTEX_API_BASE, location), projectId, location, model); Map requestBody = new HashMap<>(); List> instances = new ArrayList<>(); @@ -70,9 +73,8 @@ public class GeminiVideoGenerationService { parameters.put("aspectRatio", "9:16"); requestBody.put("parameters", parameters); - logger.info("VEO: Запускаем генерацию (Long Running Operation). Промпт: {}", prompt); + logger.info("VEO: Запускаем генерацию. Промпт: {}", prompt); - // ШАГ 1: Запускаем задачу Map initResponse = webClient.post() .uri(URI.create(endpointUrl)) .header("Authorization", "Bearer " + getAccessTokenFromResources()) @@ -87,31 +89,25 @@ public class GeminiVideoGenerationService { return null; } + // ШАГ 2: Берем сырой путь операции и собираем ссылку через v1beta1 String rawOperationName = (String) initResponse.get("name"); - logger.info("VEO: Задача успешно принята Google. Сырой ID: {}", rawOperationName); + logger.info("VEO: Задача успешно принята Google. ID: {}", rawOperationName); - // ================================================================= - // ШАГ 2: ФИКС БАГА GOOGLE CLOUD - // Вырезаем чистый ID операции и собираем каноничный Vertex URL - // ================================================================= - String operationId = rawOperationName.substring(rawOperationName.lastIndexOf("/") + 1); - String cleanOperationPath = String.format("projects/%s/locations/%s/operations/%s", projectId, location, operationId); - String operationUrl = String.format("https://%s-aiplatform.googleapis.com/v1/%s", location, cleanOperationPath); - - logger.info("VEO: Сформирован ПРАВИЛЬНЫЙ URL для проверки: {}", operationUrl); + String operationUrl = String.format("%s/%s", String.format(VERTEX_API_BASE, location), rawOperationName); + logger.info("VEO: URL для проверки (v1beta1): {}", operationUrl); // ШАГ 3: Цикл опроса (Polling) int attempts = 0; - int maxAttempts = 60; // Максимум 15 минут (60 попыток по 15 сек) + int maxAttempts = 60; // Ждем до 15 минут while (attempts < maxAttempts) { - Thread.sleep(15000); // Ждем 15 секунд перед проверкой + Thread.sleep(15000); attempts++; logger.info("VEO: Проверка статуса видео... (попытка {}/{})", attempts, maxAttempts); Map statusResponse = webClient.get() .uri(URI.create(operationUrl)) - .header("Authorization", "Bearer " + getAccessTokenFromResources()) // Обязательно обновляем токен + .header("Authorization", "Bearer " + getAccessTokenFromResources()) .retrieve() .bodyToMono(new ParameterizedTypeReference>() {}) .block(Duration.ofSeconds(30)); @@ -125,6 +121,7 @@ public class GeminiVideoGenerationService { Boolean isDone = (Boolean) statusResponse.get("done"); if (Boolean.TRUE.equals(isDone)) { logger.info("VEO: 🔥 ВИДЕО ГОТОВО! Скачиваем результат..."); + @SuppressWarnings("unchecked") Map responseObj = (Map) statusResponse.get("response"); return extractVideoFromResponse(responseObj); }