Я пытаюсь реализовать трехсторонний видеочат в приложении Android с помощью пакета собственного кода WebRTC для Android (т.е. без использования WebView). Я написал сервер сигнализации с использованием node.js и использовал java-клиент Gottox socket.io внутри клиентского приложения для подключения к серверу, обмена SDP-пакетами и установления двустороннего видеочата.
Однако теперь у меня проблемы с переходом на трехсторонний звонок. Приложение AppRTCDemo, которое поставляется с пакетом собственного кода WebRTC, демонстрирует только двусторонние вызовы (если третья сторона пытается присоединиться к комнате, возвращается сообщение «комната заполнена»).
Согласно этот ответ (который не относится к Android в частности), я должен сделать это, создав несколько PeerConnections, чтобы каждый участник чата подключился к двум другим участникам.
Однако, когда я создаю более одного PeerConnectionClient (класс Java, который обертывает PeerConection, который реализован на собственной стороне в libjingle_peerconnection_so.so), изнутри библиотеки возникает исключение, возникающее в результате конфликта с обоими из них, пытающимися доступ к камере:
E/VideoCapturerAndroid(21170): startCapture failed
E/VideoCapturerAndroid(21170): java.lang.RuntimeException: Fail to connect to camera service
E/VideoCapturerAndroid(21170): at android.hardware.Camera.native_setup(Native Method)
E/VideoCapturerAndroid(21170): at android.hardware.Camera.<init>(Camera.java:548)
E/VideoCapturerAndroid(21170): at android.hardware.Camera.open(Camera.java:389)
E/VideoCapturerAndroid(21170): at org.webrtc.VideoCapturerAndroid.startCaptureOnCameraThread(VideoCapturerAndroid.java:528)
E/VideoCapturerAndroid(21170): at org.webrtc.VideoCapturerAndroid.access$11(VideoCapturerAndroid.java:520)
E/VideoCapturerAndroid(21170): at org.webrtc.VideoCapturerAndroid$6.run(VideoCapturerAndroid.java:514)
E/VideoCapturerAndroid(21170): at android.os.Handler.handleCallback(Handler.java:733)
E/VideoCapturerAndroid(21170): at android.os.Handler.dispatchMessage(Handler.java:95)
E/VideoCapturerAndroid(21170): at android.os.Looper.loop(Looper.java:136)
E/VideoCapturerAndroid(21170): at org.webrtc.VideoCapturerAndroid$CameraThread.run(VideoCapturerAndroid.java:484)
Это происходит при инициализации локального клиента еще до попытки установить соединение, поэтому это не связано с node.js, socket.io или каким-либо другим сигнальным сервером.
Как мне получить несколько PeerConnections для совместного использования камеры, чтобы я мог отправлять одно и то же видео более чем одному партнеру?
Одна из моих идей заключалась в том, чтобы реализовать какой-то одноэлементный класс камеры для замены VideoCapturerAndroid, который можно было бы использовать для нескольких подключений, но я даже не уверен, что это сработает, и я хотел бы знать, есть ли способ сделать 3- way вызывает с помощью API, прежде чем я начну взламывать библиотеку.
Возможно ли это, и если да, то как?
Обновление:
Я попытался поделиться объектом VideoCapturerAndroid между несколькими PeerConnectionClients, создав его только для первого соединения и передав его в функцию инициализации для последующих, но в результате получилось, что «Capturer можно использовать только один раз!» исключение при создании второго VideoTrack из объекта VideoCapturer для второго однорангового соединения:
E/AndroidRuntime(18956): FATAL EXCEPTION: Thread-1397
E/AndroidRuntime(18956): java.lang.RuntimeException: Capturer can only be taken once!
E/AndroidRuntime(18956): at org.webrtc.VideoCapturer.takeNativeVideoCapturer(VideoCapturer.java:52)
E/AndroidRuntime(18956): at org.webrtc.PeerConnectionFactory.createVideoSource(PeerConnectionFactory.java:113)
E/AndroidRuntime(18956): at com.example.rtcapp.PeerConnectionClient.createVideoTrack(PeerConnectionClient.java:720)
E/AndroidRuntime(18956): at com.example.rtcapp.PeerConnectionClient.createPeerConnectionInternal(PeerConnectionClient.java:482)
E/AndroidRuntime(18956): at com.example.rtcapp.PeerConnectionClient.access$20(PeerConnectionClient.java:433)
E/AndroidRuntime(18956): at com.example.rtcapp.PeerConnectionClient$2.run(PeerConnectionClient.java:280)
E/AndroidRuntime(18956): at android.os.Handler.handleCallback(Handler.java:733)
E/AndroidRuntime(18956): at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime(18956): at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime(18956): at com.example.rtcapp.LooperExecutor.run(LooperExecutor.java:56)
Попытка поделиться объектом VideoTrack между PeerConnectionClients привела к этой ошибке из собственного кода:
E/libjingle(19884): Local fingerprint does not match identity.
E/libjingle(19884): P2PTransportChannel::Connect: The ice_ufrag_ and the ice_pwd_ are not set.
E/libjingle(19884): Local fingerprint does not match identity.
E/libjingle(19884): Failed to set local offer sdp: Failed to push down transport description: Local fingerprint does not match identity.
Совместное использование MediaStream между PeerConnectionClients приводит к внезапному закрытию приложения без появления каких-либо сообщений об ошибках в Logcat.