Я пытаюсь реализовать трехсторонний видеочат внутри приложения для Android, используя пакетный код для веб-сайтов для Android (т.е. не используя WebView). Я написал сервер сигнализации с помощью node.js и использовал библиотеку Gottox socket.io java client в клиентском приложении для подключения к сервер, обмениваться 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 для совместного использования камеры, чтобы я мог отправлять одно и то же видео нескольким одноранговым узлам?
Одна из моих идей заключалась в том, чтобы реализовать какой-то класс камеры Singleton для замены VideoCapturerAndroid, который можно было бы использовать для нескольких соединений, но я даже не уверен, что это сработает, и я хотел бы знать, есть ли способ делать 3-сторонние вызовы с использованием API, прежде чем я начну взламывать внутри библиотеки.
Возможно ли, и если да, то как?
Update:
Я попробовал совместно использовать объект 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.