LINUX.ORG.RU

Разработка android-приложения для аудио-звонков

 


0

2

Упрощённо:

  1. Есть самописный сервер на C++, в котором есть необходимый набор чего угодно из разряда: epoll-принималка коннектов, набор OPUS-кодера-декодера, цифровые фильтры, смешивалки сигналов, всякое нужное DSP и т.п. На этой стороне всё прозрачно понятно, дорабатываемо в любом направлении. Вопросов по этой части не будет.

  2. Android-приложение, которого пока нет. В нём только 2 кнопки «старт» и «стоп». Стоп делает его неактивным, интереснее что происходит в режиме «старт». В этом режиме приложение в фоне находится в состоянии постоянного «звонка». Под звонком понимается открытое соединение к серверу, в которое наше приложение постоянно шлёт поток OPUS-моно-20kbps, закодированный с микрофона телефона (или с гарнитуры) и параллельно получает аналогичный поток с сервера, декодирует и пихает в наушники. Строго говоря, приложение и сервер шлют свои потоки не постоянно, а возможно по сигналу от Voice Activity Detector, но это детали.

Как это делается у взрослых IP-телефонных чуваков или в браузерах, SIP, WebRTC - всё это не интересно, ибо это переусложнено для моего вышеописанного случая. Да, можно припахать, но зачем. Да и хочется сделать с нуля и очень примитивное.

Вопросы тут в другом:

  1. Андроид - штука сложная и у него существует много разных понятий «звонок». Звонком является не любое состояние, при котором включен микрофон и динамик. Например, если ты звонишь по GSM то отрубается mp3-плеер с музоном. Если ты звонишь в зуме, то это выглядит как-то иначе, но плеер тоже отрубается. А если ты звонишь в телеграме, то музон в плеере становится монофоническим, не отрубаясь. Короче «звонки» - это какое-то сложное глобалное состояние системы, которое влияет на другие приложения и на аудиосистему андроид-железки в целом. Нельзя просто так взять и написать приложение «диктофон», которое данные с микрофона будет отправлять в сеть, а данные из сети - в динамик и назвать это звонилкой. Короче тут вопрос в том, как правильно оформаляется «звонок» в приложении, чтобы он был по «статусу» хотя-бы как телеграмный звонок, когда ты заходишь в голосовой чат в телеге.

  2. Верно ли, что нельзя просто так взять сырые данные с микрофона андроида в указанном тобой формате, типа 48000/16bit/mono, а потом спокойно засунуть их в свой libopus-кодек, скомпилированный сишным компилятором и отправить в сеть? Андроидные микрофоны, видимые уровню приложения, способны отдать только какой-то готовый закодированный во что-то типа AAC или там mp4 поток? Если я хочу послать своему серверу OPUS-поток или вообще изобрести свой кодек, то мне надо сначала раскодировать кодированный поток в сырые байтики, а потом закодировать в нужный мне кодек? Зачем мне именно OPUS - ну потому что лучше ничего нет и потому что я хочу контролировать все нюансы звука, выбирать битрейт в зависимости от нагруженности сервера или ещё каких-то своих приколов, ну и потому что я уже умею с ним хорошо работать и не хочу переставать.

В общем, хотелось бы получить некоторых ключевых слов из мира java/android разработки, копая в которые я выйду на нужные имена классов/сущностей в SDK андроид девелопмента и почитаю, что правильно в таких случаях читать.

P.S. Советы «возьми такую-то либо и не мучайся» не нужны, цели не мучаться нет, цель больше самообразовательная, чем разработка продукта с выходом на IPO в сжатые сроки.



Последнее исправление: lesopilorama (всего исправлений: 3)

Раз всё на плюсах, то возможно стоит на NDK или JNI к Android прикрепиться. Про приоритеты фокуса это здесь, некоторые приложения (вроде самого лучшего аудиоплеера Neutron) могут перехватывать контроль.

ac130kz ★★
()
Последнее исправление: ac130kz (всего исправлений: 1)

Посмотри классы MediaRecorder, AudioRecord, возможно это именно то, что тебе нужно. Сырые данные взять можно, битрейт, каналы и разрядность указываешь сам. С плюсовой либой общаться через JNI, со стороны явы будет совсем просто:

public class MyLibWrapper {

     static {
        System.loadLibrary("myLib");
       }

    public static native String myLibFunc1();

    public static native int myLibFunc2(int errType, String group, String msg);

}

На плюсах только довольно муторно функции под JNI перелопачивать

man-from-36
()
Последнее исправление: man-from-36 (всего исправлений: 3)