Нативная работа с видео и аудио: Потоковая передача данных

45 минут Урок 6

Введение: За пределами статических кадров

Приветствую, коллеги. В предыдущих модулях мы научились работать с текстом и статичными изображениями. Это база, с которой начинают все. Но реальный мир не статичен. Он движется, звучит и меняется во времени. Истинная сила Gemini 3 раскрывается именно здесь — в способности воспринимать аудио и видео нативно.

Что значит «нативно»? Раньше, чтобы скормить нейросети видео, разработчикам приходилось писать «костыли»: нарезать видео на кадры (фреймы), извлекать аудиодорожку, транскрибировать её через Whisper или Google Speech-to-Text, и только потом отправлять эту кучу разрозненных данных в модель. Это было долго, дорого и, главное, терялся контекст. Модель не видела связи между жестом руки и интонацией голоса.

Gemini 3 меняет правила игры. Она «смотрит» видео и «слышит» аудио как единый поток токенов. Она понимает, что сарказм в голосе противоречит улыбке на лице. В этом уроке мы разберем, как технически реализовать работу с такими тяжелыми данными, используя File API и потоковую передачу (Streaming), чтобы ваши приложения работали быстро, даже если пользователь загружает часовую лекцию.

Аудио как первый класс данных

Начнем с аудио. Многие ошибочно полагают, что работа с аудио в LLM — это просто транскрипция. Это в корне неверно. Gemini не просто переводит звук в текст; она анализирует звучание.

  • Паралингвистика: Модель слышит вздохи, паузы, изменение темпа речи и интонации.
  • Мультиспикерность: Она способна различать спикеров без сложной диаризации (хотя подсказки ей помогают).
  • Звуковые события: Стук в дверь, звук сирены, фоновая музыка — всё это контекст, который учитывается при генерации ответа.

Для работы с аудиофайлами (особенно длинными) мы не можем просто передать их в теле запроса как Base64. Лимиты HTTP нас остановят. Мы используем File API — промежуточное хранилище Google, куда мы загружаем медиа, получаем дескриптор (URI) и уже его скармливаем модели.

python
import google.generativeai as genai
import time
import os

# Настройка API ключа
# Предполагается, что ключ сохранен в переменных окружения
genai.configure(api_key=os.environ["GEMINI_API_KEY"])

def upload_and_process_audio(file_path):
    """
    Загружает аудиофайл и анализирует его содержимое.
    Используем File API для эффективной работы с большими данными.
    """
    print(f"Загрузка файла: {file_path}...")
    
    # 1. Загрузка файла в облако Google
    audio_file = genai.upload_file(path=file_path)
    
    print(f"Файл загружен. URI: {audio_file.uri}")
    
    # 2. Инициализация модели Gemini 3 (предположим использование Pro версии)
    model = genai.GenerativeModel('gemini-3.0-pro-latest')
    
    # 3. Формирование промпта
    # Обратите внимание: мы просим не просто текст, а анализ тональности
    prompt = "Прослушай эту запись совещания. 1. Сделай краткое резюме. 2. Опиши эмоциональный фон: был ли конфликт или все прошло спокойно?"
    
    # 4. Генерация ответа
    response = model.generate_content([prompt, audio_file])
    
    return response.text

# Пример вызова (закомментирован для безопасности)
# print(upload_and_process_audio("meeting_recording.mp3"))

Видео: Пространство и Время

Переходим к видео. Видео для Gemini — это последовательность изображений плюс аудиодорожка. Но есть нюанс: частота дискретизации. Модель не смотрит 60 кадров в секунду (это сожгло бы контекстное окно мгновенно). Обычно API сэмплирует видео с частотой 1 кадр в секунду (1 fps), что достаточно для понимания большинства сюжетов.

Жизненный цикл обработки видео

  1. Upload: Вы загружаете файл (MP4, MOV и т.д.) через `upload_file`.
  2. State Processing: Критически важный этап! Видео не готово мгновенно. После загрузки оно переходит в статус `PROCESSING`. Вы не можете отправить запрос к модели, пока статус не станет `ACTIVE`. Если вы попытаетесь сделать это раньше, получите ошибку 400.
  3. Inference: После активации видео становится токенами в контекстном окне.

Для видео крайне важно использовать потоковую генерацию ответов (Streaming Response). Видео — сложный инпут, «обдумывание» может занять пару секунд. Чтобы пользователь не смотрел на зависший экран, мы должны отдавать текст по мере его появления (token by token).

python
import time

def process_video_with_streaming(file_path):
    """
    Демонстрация полного цикла: Загрузка -> Ожидание обработки -> Потоковая генерация.
    """
    # 1. Загрузка
    video_file = genai.upload_file(path=file_path)
    print(f"Загрузка завершена: {video_file.name}")

    # 2. Активное ожидание завершения процессинга (Polling)
    while video_file.state.name == "PROCESSING":
        print("Ожидание обработки видео на сервере...")
        time.sleep(2) # Пауза чтобы не спамить API
        video_file = genai.get_file(video_file.name) # Обновляем статус

    if video_file.state.name == "FAILED":
        raise ValueError("Не удалось обработать видеофайл.")

    print(f"Видео готово. Состояние: {video_file.state.name}")

    # 3. Инициализация модели
    model = genai.GenerativeModel('gemini-3.0-flash') 
    # Flash версия отлично подходит для быстрого анализа видео

    # 4. Запрос с использованием stream=True
    prompt = """
    Посмотри это видео. 
    Составь таймкоды ключевых событий.
    Для каждого события дай описание того, что происходит на экране.
    """
    
    print("Начинаю генерацию ответа...\n")
    
    # stream=True возвращает итератор, а не готовый ответ
    response_stream = model.generate_content([video_file, prompt], stream=True)

    # 5. Обработка потока
    full_text = ""
    for chunk in response_stream:
        # chunk.text содержит кусочек сгенерированного ответа
        print(chunk.text, end="", flush=True)
        full_text += chunk.text
    
    # Не забываем удалять файлы после использования, чтобы не забивать квоту хранилища
    # genai.delete_file(video_file.name)
    
    return full_text

Стратегии оптимизации токенов и задержек

Работа с видео «дорогая» с точки зрения токенов. Час видео может занимать десятки тысяч токенов. Вот несколько профессиональных советов:

1. Правильный выбор модели:
Для задач, где нужно просто найти объект («есть ли в видео кошка?»), используйте Gemini Flash. Она быстрее, дешевле и имеет огромное контекстное окно. Для глубокого анализа эмоций или сложных причинно-следственных связей («почему герой решил украсть машину?») используйте версию Pro.

2. Prompt Engineering для видео:
Никогда не просите «просто перескажи». Модель может зацепиться за неважные детали. Используйте структуру: «Роль: Видео-редактор. Задача: Выдели 3 главных момента для трейлера. Формат: JSON с таймкодами».

3. Смешивание модальностей:
Вы можете передать видео И текст документа одновременно. Например: «Вот видеозапись установки детали (видео). А вот инструкция производителя (PDF/текст). Найди, где мастер нарушил инструкцию». Это высший пилотаж мультимодальной разработки.

Упражнение

Создайте скрипт 'Smart Lecture Notes'. Скрипт должен принимать путь к видеофайлу лекции (можно использовать короткий сэмпл 1-2 минуты), загружать его в Gemini и генерировать структурированный конспект в формате Markdown. Конспект должен содержать: Введение, Список основных тезисов и Практические выводы. Обязательно реализуйте проверку статуса обработки файла (цикл while).

Вопрос

Почему при работе с видеофайлами через Gemini API необходимо реализовывать цикл ожидания (polling) после загрузки файла?