Android WebRTC — Mix AudioTracks для конференции

Я пытаюсь решить проблему с WebRTC Native Android. Я успешно адаптировал AppRTCDemo от вызова 1-1 к вызовам 1-N. В настоящее время у меня есть следующий сценарий:

  • А (я) могу говорить/слушать Б
  • A (я) могу говорить/слушать C
  • B и C не могут разговаривать или слушать друг друга.

Для этого у меня (A) есть 2 PeerConnection соответственно с B и C. Я понимаю, что мне нужно немного смешать потоки мультимедиа или звуковые дорожки, или, другими словами:

  • Смешать (A, B) -> отправить в C

  • Смешать (A, C) -> отправить в B

Любые указатели на то, как это сделать? Спасибо


person EdGs    schedule 19.09.2016    source источник
comment
Зачем вам нужно смешивать A и B и отправлять в C? Есть ли какая-то причина для B и C не устанавливать соединение напрямую?   -  person samgak    schedule 25.09.2016
comment
@samgak Значение B и C напрямую связаны друг с другом? Если клиент (A) является приложением для Android и создал 2 одноранговых соединения с B и еще одно с C... Я не понимаю, как можно было бы подключить B к C напрямую, как вы предложили, от клиента?   -  person EdGs    schedule 27.09.2016
comment
B и C используют одно и то же приложение? Если нет, то какие?   -  person samgak    schedule 27.09.2016
comment
Я использую его с мостом WebRTC-2-Sip. B и C — это звонки на телефонные номера, которые могут быть стационарными voip-телефонами или настольными программными телефонами.   -  person EdGs    schedule 27.09.2016


Ответы (1)


Я полагаю, что вы отправляете один и тот же локальный поток обеим сторонам (сторона-B и сторона-C) в мультисоединении, потому что, если вы попытаетесь создать разные локальные потоки для разных соединений, это выдаст ошибку, поскольку он снова попытается получить доступ к микрофону и камере. что невозможно (я считаю).

Вы должны создавать локальный поток примерно так:

stream = sessionFactory.createLocalMediaStream(LOCAL_MEDIA_ID);

Для отправки потока Party-B на Party-C вы можете сделать это:

  • step1-- создайте соединение p2p между стороной-A и стороной-B
  • step2-- создайте соединение p2p между стороной-A и стороной-C
  • шаг 3 - когда вы добавляете локальный поток, вы вызываете что-то вроде этого

    peerconnection2.addStream(myStream)
    

Вместо myStream (для однорангового соединения с C) вы можете добавить remoteStreamB (удаленный поток, который вы получаете от B). Это добавит поток, который вы получаете от B, как локальный поток во втором одноранговом соединении, которое находится с C.

Для отправки удаленного потока от Party-C к Party-B:

  • Предположим, у вас есть одноранговое соединение1 с Party-B. Чтобы добавить удаленный поток из C в качестве локального потока, сначала вам придется удалить текущие дорожки, а затем добавить новые дорожки.
  • для этого вы можете сделать что-то вроде этого

    AudioTrack t1 = mystream.audioTracks.get(0);
    VideoTrack v1 = myStream.videoTracks.get(0);
    if(myStream.removeTrack(t1)){
     if(myStream.removeTrack(v1)){
      t1 = remoteStreamC.audioTracks.get(0);
      v1 = remoteStreamC.videoTracks.get(0);
    
      myStream.addTrack(t1);
      myStream.addTrack(v1);
     }
    }
    

    Таким образом вы измените содержимое локального потока, который вы отправляете на B. Теперь этот поток будет иметь аудио- и видеодорожки, поступающие с удаленного потока C.

Но чтобы сделать этот процесс безошибочным, вам придется использовать обработку ошибок, потому что, когда кто-то разрывает соединение (либо B, либо C), вы будете получать нулевые треки.... В этом случае вам придется немедленно отправить запрос на отбой на другая сторона тоже.

person Alex Morrison    schedule 24.09.2016
comment
В ближайшее время постараюсь реализовать ваше предложение. Я сообщу вам результаты. Спасибо!! - person EdGs; 27.09.2016
comment
Ты прав. Я создаю localStream только один раз. И, ваш первый пример, B-Party to C-Party работает, при создании C-party peerConnection я передаю поток B-party как localMedia в C-party. Я пробовал 2-й пример с C-Party на B-Party, но безуспешно. К B-party уже подключен localStream. Как только я заменяю треки, как вы предложили, я теряю звук на B-Party. Нужно ли вызывать B-PeerConnection.removeStream(localStream), а затем B-PeerConnection.addStream(modifiedStream)? Другими словами, как заменить поток B-party? Это тоже должно вызвать новое предложение, верно? - person EdGs; 27.09.2016
comment
Хорошо, ваш ответ привел меня туда, где мне было нужно. Как оказалось, onRenegotiationNeeded срабатывал, но никаких предложений не отправлялось, когда я добавлял или удалял MediaStream из PeerConnection. Поэтому я заставляю его создать предложение. Странно, так как вы думаете, что это сработает после комментария. Ничего не нужно делать; AppRTC следует предварительно согласованному протоколу сигнализации/согласования в теле метода. Теперь, после создания трехстороннего вызова, реализующего то, что вы предложили, качество звука на стороне однорангового узла значительно ухудшается. Есть идеи, почему? Спасибо - person EdGs; 28.09.2016
comment
Приведенное выше решение приводит к плохому качеству звука при добавлении/удалении потоков. Насколько я понимаю, идеальным было бы объединить 2 медиапотока в один медиапоток и добавить его к одноранговому соединению. Любые указатели на то, как решить эту проблему? - person EdGs; 28.09.2016
comment
мы меняем медиапотоки, поэтому будут задержки ... вам нужно будет справиться с ситуацией для этого. что-то вроде того, что пользователь на другом конце не сможет узнать, что есть задержка. Насчет качества звука... Могу только сказать, что оно зависит от используемого кодека. здесь нам нужно убедиться, что оба одноранговых соединения используют одни и те же кодеки. - person Alex Morrison; 29.09.2016
comment
Нет, мы не добавляем два медиапотока в один… мы просто заменяем дорожки одного медиапотока дорожками другого медиапотока. Вы также можете напрямую добавить удаленный поток, исходящий от стороны c (например, RStreamC), в одноранговое соединение между A и B (например, pc1) как pc1.addStream(RStreamC). вам также необходимо сначала удалить предыдущий локальный поток с помощью этого pc1.removeStream(mystream). - person Alex Morrison; 29.09.2016
comment
Извините, что поднимаю старую тему, но удалось ли вам решить проблему с искаженным звуком? - person clawoo; 23.06.2017