fix
This commit is contained in:
@@ -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<String, Object> requestBody = new HashMap<>();
|
||||
List<Map<String, Object>> 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<String, Object> 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<String, Object> statusResponse = webClient.get()
|
||||
.uri(URI.create(operationUrl))
|
||||
.header("Authorization", "Bearer " + getAccessTokenFromResources()) // Обязательно обновляем токен
|
||||
.header("Authorization", "Bearer " + getAccessTokenFromResources())
|
||||
.retrieve()
|
||||
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {})
|
||||
.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<String, Object> responseObj = (Map<String, Object>) statusResponse.get("response");
|
||||
return extractVideoFromResponse(responseObj);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user