Реализация наложения оверлеев (текст, логотип) на стрим с мобильного устройства

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Реализация наложения оверлеев (текст, логотип) на стрим с мобильного устройства
Средний
~3-5 дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    495

Реализация наложения оверлеев (текст, логотип) на стрим с мобильного устройства

Наложить логотип на стрим выглядит просто — пока не сталкиваешься с тем, что overlay нужно рендерить не на экран, а напрямую в видеопоток до энкодера. UIKit/SwiftUI-вьюшки здесь не помогут: они рисуют в display pipeline, который не имеет отношения к CVPixelBuffer, уходящему в VideoToolbox.

Где правильно встроить оверлей

Пайплайн выглядит так:

AVCaptureVideoDataOutput → CMSampleBuffer → CVPixelBuffer → [оверлей] → H.264-энкодер → RTMP/SRT

Оверлей должен применяться к CVPixelBuffer до передачи в энкодер. Два способа:

Metal (рекомендуемый). Создаём MTLTexture из CVPixelBuffer через CVMetalTextureCacheCreateTextureFromImage, рендерим оверлей поверх через Metal render pass, записываем результат обратно в CVPixelBuffer. Работает на GPU — нагрузка на CPU минимальна.

CoreImage. Используем CISourceOverCompositing фильтр: накладываем CIImage логотипа на CIImage из CMSampleBuffer. Проще в коде, но на iPhone 12 и старше при 1080p30 добавляет 4–6ms к обработке каждого кадра на главном CPU — на грани дропа.

На продакшн-проектах с требованием 1080p30 без дропов — только Metal.

Реализация через Metal

class OverlayRenderer {
    private let device: MTLDevice
    private let commandQueue: MTLCommandQueue
    private var textureCache: CVMetalTextureCache?
    private var overlayTexture: MTLTexture? // предзагруженный логотип

    func apply(to pixelBuffer: CVPixelBuffer) -> CVPixelBuffer {
        var cvTexture: CVMetalTexture?
        CVMetalTextureCacheCreateTextureFromImage(
            nil, textureCache!, pixelBuffer, nil,
            .bgra8Unorm,
            CVPixelBufferGetWidth(pixelBuffer),
            CVPixelBufferGetHeight(pixelBuffer),
            0, &cvTexture
        )
        guard let texture = CVMetalTextureGetTexture(cvTexture!) else { return pixelBuffer }

        let commandBuffer = commandQueue.makeCommandBuffer()!
        // render pass: основная текстура + overlayTexture поверх
        // ...
        commandBuffer.commit()
        commandBuffer.waitUntilCompleted()
        return pixelBuffer // модифицированный in-place
    }
}

Логотип (overlayTexture) загружаем один раз при старте сессии из PNG с альфа-каналом. Не загружайте UIImage на каждый кадр — это 2–3ms аллокации на каждый вызов.

Текстовые оверлеи: отдельная проблема

Статический текст (название канала) — просто Metal-текстура, подготовленная один раз через CoreText. Проблема в динамическом тексте: счётчик зрителей, таймер, donation-сообщения. Их нельзя рендерить через Metal напрямую — Metal не работает с текстом, только с геометрией и текстурами.

Решение: создаём offscreen CALayer с CATextLayer, рисуем его в UIGraphicsImageRenderer, получаем UIImage, конвертируем в MTLTexture. Это делаем в фоновом потоке не чаще, чем раз в 500ms для счётчиков и по событию для donation-сообщений. На экране текст обновляется плавно, в стрим уходит без задержки.

Android: аналогичный подход через OpenGL ES / Vulkan

На Android аналог — SurfaceTexture + OpenGL ES 2.0. Камера рендерит в SurfaceTexture, мы накладываем оверлей через GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA), результат уходит в MediaCodec через Surface. Vulkan мощнее, но поддерживается с Android 7+ и требует значительно больше boilerplate — оправдан только при сложных эффектах.

Позиционирование и адаптация оверлея

Позиция логотипа хранится как относительные координаты (0.0–1.0 от размера кадра), а не абсолютные пиксели. Это позволяет корректно работать при смене разрешения или ориентации без перерасчёта логики. При landscape-ротации — пересчитываем overlayRect в Metal render pass автоматически.

Fade-in/fade-out для donation-текста реализуем через изменение альфа-канала MTLTexture между кадрами — плавное появление за 15–20 кадров (0.5–0.7 секунды).

Сроки

Статический логотип + Metal-пайплайн на iOS: 1–1.5 недели. Динамический текст, анимации оверлеев, поддержка iOS + Android: 3–4 недели. Стоимость рассчитывается индивидуально.