Почему on-device анализ — единственное верное решение для видеозвонков?
Во время видеозвонка вы хотите оценить реакцию собеседника, но отправка видео в облако нарушает приватность и увеличивает задержку. On-device анализ решает обе проблемы: вся обработка на устройстве, задержка менее 10 мс. При этом вы сохраняете контроль над данными, не нарушая App Store Review Guidelines и GDPR. Академические исследования FACS (Facial Action Coding System) показывают: мимика не однозначно отображает эмоции. Поэтому мы избегаем ярлыков «злой» или «счастливый», используем нейтральные метрики — уровень вовлеченности, активность мимики. Система не должна влиять на кадровые или юридические решения. Современные решения mobile emotion recognition работают локально, что особенно важно для приложений с высокими требованиями к конфиденциальности.
Почему мы не используем категоризацию эмоций?
Категоризация эмоций (счастье, грусть) — упрощение, ведущее к ошибкам. Action Units по FACS фиксируют конкретные движения мышц, что дает объективные данные. Например, улыбка может быть вежливой или искренней — мы не делаем предположений, а передаем числовые метрики. Пользователь видит только агрегированные показатели вовлеченности, а не эмоциональные ярлыки. В реальных проектах мы используем комбинацию Action Units и машинного обучения для повышения точности распознавания.
Как мы реализуем анализ на iOS и Android
Стек технологий
- Детекция лица: MediaPipe Face Detection (iOS/Android), Apple Vision (iOS)
- Распознавание выражений: Apple Vision
VNDetectFaceExpressionsRequest, FER+ (CoreML/TFLite) - Интеграция в звонок: WebRTC data channel или Agora Video SDK
Сравнение подходов
| Критерий | Apple Vision | FER+ (on-device) | Azure Face API (облако) |
|---|---|---|---|
| Задержка | <10ms | <30ms | 200-500ms |
| Приватность | Полная | Полная | Нет (кадры уходят) |
| Точность (Action Units) | 85% | 80% | 90% |
| Стоимость | Включено в ОС | Бесплатно | Платная подписка (от $0.50 за 1000 вызовов) |
Для видеозвонков on-device решение предпочтительнее по задержке и приватности. Отсутствие облачных затрат — дополнительный плюс. On-device решение в 10 раз быстрее облачного по задержке передачи, что критично для real-time коммуникации.
Как мы это делаем на iOS
// iOS: анализ выражений лица через Vision class FaceExpressionAnalyzer { func analyze(sampleBuffer: CMSampleBuffer) async throws -> ExpressionResult? { guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return nil } let faceRequest = VNDetectFaceLandmarksRequest() 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. Это корректнее, чем интерпретировать улыбку как счастье.
Агрегация по времени
Один кадр — шум. Используем скользящее окно из 15 кадров (~0.5 сек):
class ExpressionAggregator { private var history: [ExpressionResult] = [] private let windowSize = 15 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(), smileTrend: computeTrend(history.map { $0.mouthSmile }) ) } } Как интегрировать анализ в существующий видеозвонок?
SDK с кастомным процессором — Agora Video SDK позволяет перехватывать кадры до отправки:
class EmotionVideoProcessor: AgoraVideoFrameDelegate { func onCapture(_ videoFrame: AgoraOutputVideoFrame, sourceType: AgoraVideoSourceType) -> Bool { if let pixelBuffer = videoFrame.pixelBuffer { Task { let result = try? await expressionAnalyzer.analyze(buffer: pixelBuffer) await MainActor.run { emotionDelegate?.didUpdateExpression(result) } } } return true } } Peer-to-peer через data channel — оба участника анализируют себя и передают результаты (не видео):
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)) } Приватно и чисто: каждый видит только свои данные и агрегат собеседника. Для сравнения, облачные сервисы emotion AI требуют передачи видео за пределы устройства, что увеличивает задержку и риски.
UX и частые ошибки
Показываем вовлеченность, а не эмоции
Правильные индикаторы — не эмоции, а вовлеченность:
@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) } ) ) } Никаких словесных ярлыков — только нейтральный цветовой индикатор.
Чего стоит избегать
- Использование облачных API без согласия пользователя — блокировка в App Store.
- Наивная интерпретация одной эмоции — ведет к недоверию пользователей.
- Отсутствие агрегации по времени — шумные данные.
Процесс внедрения и сроки
Этапы работы
| Этап | Описание | Длительность |
|---|---|---|
| Аудит | Анализ текущего стека видеозвонка и требований к приватности | 1-2 дня |
| Прототип | Реализация on-device анализа с MediaPipe / Vision | 3-5 дней |
| Интеграция | Data channel для P2P обмена или интеграция SDK | 2-4 дня |
| UX | Индикатор вовлеченности + экран согласия | 2-3 дня |
| Тестирование | На реальных устройствах, отладка | 2-3 дня |
| Документация | Код-ревью, инструкции, передача по проекту | 1-2 дня |
Ориентировочные сроки
Базовая версия: от 1 до 2 недель. Полная система (iOS + Android + data channel): от 2 до 4 недель. Стоимость рассчитывается индивидуально. Свяжитесь с нами для консультации — мы подготовим индивидуальное решение. Оцените экономию на облачных расходах: при 10 000 ежемесячных звонков вызовы Azure Face API обойдутся в $500–1500, тогда как on-device решение исключает эти затраты.
Что входит в работу
- Готовый модуль анализа эмоций (iOS/Android) с исходным кодом.
- Документация по интеграции и настройке.
- Пример использования с индикатором вовлеченности.
- Консультация по прохождению модерации App Store / Google Play.
- Поддержка в течение 30 дней после передачи.
Заключение
On-device анализ мимики — этичное и технически эффективное решение для видеозвонков. Единоразовая экономия на облачных расходах может составить существенную сумму. Закажите консультацию по интеграции в ваш существующий видеозвонок. Используйте on-device emotion detection для соблюдения приватности и снижения задержек.







