Реализация AI-анализа эмоций собеседника во время видеозвонка

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

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

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Реализация AI-анализа эмоций собеседника во время видеозвонка
Сложный
~2-4 недели
Часто задаваемые вопросы

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

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

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

  • 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

Реализация AI-анализа эмоций собеседника во время видеозвонка

Анализ эмоций через камеру в реальном времени — технически реализуемо, но требует особого подхода к этике и UX. Покажем лицо технической стороны, не скрывая ограничений: модели анализа эмоций — один из самых критикуемых с точки зрения достоверности инструментов в AI.

Важное ограничение, которое нельзя игнорировать

Академический консенсус (Lisa Feldman Barrett, 2019) и практика показывают: мимика не однозначно отображается на эмоцию. Один и тот же паттерн движения лицевых мышц означает разное для разных людей и культур. Поэтому:

  • Называть вывод «эмоцией» некорректно — правильнее «аффективное состояние», «выражение лица»
  • Системы ни в коем случае не должны использоваться для принятия кадровых или юридических решений
  • Пользователь должен дать явное согласие на анализ своего лица

Это не просто этическое замечание — это архитектурное требование.

Технический стек

Детекция лица — MediaPipe Face Detection (iOS/Android), Vision VNDetectFaceRectanglesRequest (iOS).

Распознавание выражений — несколько вариантов:

  • Apple Vision VNDetectFaceExpressionsRequest (iOS 17+) — встроенный, без облака, 7 базовых Action Units
  • Microsoft Azure Face API — облачный, детальный, включает Action Units
  • AWS Rekognition (DetectFaces) — облачный, 7 базовых эмоций
  • FER+ модель (TFLite/CoreML) — open source, 8 классов, on-device

Для видеозвонков on-device — обязательно: нельзя стримить лицо собеседника в облако без его явного согласия.

Реализация на iOS с Vision (on-device)

// iOS 17+: анализ выражений лица через Vision
class FaceExpressionAnalyzer {

    func analyze(sampleBuffer: CMSampleBuffer) async throws -> ExpressionResult? {
        guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return nil }

        let faceRequest = VNDetectFaceLandmarksRequest()

        // iOS 17: анализ выражений — brow action units и т.д.
        let expressionRequest = VNDetectFaceExpressionsRequest()

        let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer)
        try handler.perform([faceRequest, expressionRequest])

        guard let faceObs = faceRequest.results?.first as? VNFaceObservation,
              let exprObs = expressionRequest.results?.first as? VNFaceExpressionObservation else {
            return nil
        }

        return ExpressionResult(
            faceBox: faceObs.boundingBox,
            browLower: exprObs.browLowerQuirk,
            browRaise: exprObs.browRaiseRight + exprObs.browRaiseLeft,
            eyesClosed: exprObs.eyeBlinkLeft + exprObs.eyeBlinkRight,
            mouthSmile: exprObs.mouthSmileLeft + exprObs.mouthSmileRight,
            mouthFrown: exprObs.mouthFrownLeft + exprObs.mouthFrownRight,
            mouthOpen: exprObs.mouthOpen,
            jawOpen: exprObs.jawOpen
        )
    }
}

VNDetectFaceExpressionsRequest работает с Action Units — базовыми движениями лицевых мышц из FACS (Facial Action Coding System). Это корректнее, чем «улыбка = счастье»: конкретное действие мышцы, без интерпретации.

Агрегация по времени

Один кадр — шум. Нужна агрегация по скользящему окну:

class ExpressionAggregator {
    private var history: [ExpressionResult] = []
    private let windowSize = 15  // ~0.5 сек при 30fps

    func update(_ result: ExpressionResult) -> AggregatedExpression {
        history.append(result)
        if history.count > windowSize { history.removeFirst() }

        return AggregatedExpression(
            averageSmile: history.map { $0.mouthSmile }.average(),
            averageBrowRaise: history.map { $0.browRaise }.average(),
            averageJawOpen: history.map { $0.jawOpen }.average(),
            // Тренд: растёт или падает улыбка за последние N кадров
            smileTrend: computeTrend(history.map { $0.mouthSmile })
        )
    }
}

Интеграция в видеозвонок

Анализ выполняется на локальном видеопотоке с камеры, не на стриме собеседника. Стрим собеседника — другое устройство, доступа к его сырым кадрам через стандартный WebRTC нет. Есть два пути:

SDK с поддержкой analysis — Agora Video SDK позволяет подключить local video processor:

// Agora: обработка локального видео перед отправкой
class EmotionVideoProcessor: AgoraVideoFrameDelegate {

    func onCapture(_ videoFrame: AgoraOutputVideoFrame,
                   sourceType: AgoraVideoSourceType) -> Bool {
        // Анализируем свой кадр до отправки
        if let pixelBuffer = videoFrame.pixelBuffer {
            Task {
                let result = try? await expressionAnalyzer.analyze(buffer: pixelBuffer)
                // result — это анализ своих эмоций, не собеседника
                await MainActor.run {
                    emotionDelegate?.didUpdateExpression(result)
                }
            }
        }
        return true  // пропускаем кадр дальше в стрим без изменений
    }
}

Peer-to-peer analysis — оба участника анализируют свои собственные выражения и передают результаты (не видео) через data channel. WebRTC data channel для JSON-пакетов — минимальный overhead.

// Передача данных об эмоциях через WebRTC DataChannel
struct EmotionDataPacket: Codable {
    let timestamp: Double
    let smile: Float
    let browRaise: Float
    let eyesClosed: Float
    // НЕ передаём изображение — только числа
}

func sendEmotionData(_ expression: AggregatedExpression) {
    let packet = EmotionDataPacket(
        timestamp: Date().timeIntervalSince1970,
        smile: expression.averageSmile,
        browRaise: expression.averageBrowRaise,
        eyesClosed: expression.averageJawOpen
    )
    let data = try! JSONEncoder().encode(packet)
    dataChannel.sendData(RTCDataBuffer(data: data, isBinary: false))
}

Так каждый участник анализирует только себя, но видит агрегированные данные от собеседника. Приватно и технически чисто.

UX: как показывать результат

Показывать «злой / грустный / счастливый» — некорректно и потенциально обидно. Правильные варианты:

  • Engagement indicator: «собеседник активно участвует в разговоре» (по browRaise + eyeBlink ритму)
  • Attention level: нейтральный индикатор вовлечённости без интерпретации эмоции
  • Настроение разговора: агрегация обоих участников в единый «тепловой» показатель
@Composable
fun EngagementIndicator(score: Float) {
    Box(
        modifier = Modifier
            .size(12.dp)
            .clip(CircleShape)
            .background(
                when {
                    score > 0.7f -> Color(0xFF4CAF50)   // активен
                    score > 0.4f -> Color(0xFFFFC107)   // нейтрален
                    else -> Color(0xFF9E9E9E)            // пассивен
                }
            )
    )
}

Никаких «лиц с эмоциями», никаких словесных ярлыков — только нейтральный цветовой индикатор.

Ориентиры по срокам

On-device анализ выражений через Vision + базовый engagement indicator в существующем видеозвонке — 1–2 недели. Полная система с peer-to-peer передачей данных через data channel, агрегацией, аналитикой разговора, экраном согласия и поддержкой iOS + Android — 2–4 недели.