Почему 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 для соблюдения приватности и снижения задержек.







