Android Webrtc为语音聊天应用创建网格架构
我正在尝试创建一个android语音聊天应用程序,4人一组,4人可以互相交谈。这可以使用android web RTC中的mesh架构来完成。我已经创建了所有先决条件,即设置转弯服务器、信号服务器和android应用程序代码。这里的问题是,我不能让它为超过两个人工作。这里Android Webrtc为语音聊天应用创建网格架构,android,webrtc-android,Android,Webrtc Android,我正在尝试创建一个android语音聊天应用程序,4人一组,4人可以互相交谈。这可以使用android web RTC中的mesh架构来完成。我已经创建了所有先决条件,即设置转弯服务器、信号服务器和android应用程序代码。这里的问题是,我不能让它为超过两个人工作。这里s发生的事情,最初是一个用户(a)加入一个房间。然后另一个用户(B)加入房间。SDP报价、应答和ICE候选人成功交换并建立连接。A和B都可以相互交谈。当第三个用户(C)加入房间时,问题开始出现。当C进入房间后,SDP报价、答案和
s发生的事情,最初是一个用户(a)加入一个房间。然后另一个用户(B)加入房间。SDP报价、应答和ICE候选人成功交换并建立连接。A和B都可以相互交谈。当第三个用户(C)加入房间时,问题开始出现。当C进入房间后,SDP报价、答案和ICE候选人将与A、B和C交换,然后B和C成功连接,他们都可以互相交谈,而B则与A断开连接,表示A听不见B和B听不见A,虽然它们在启动时已成功连接,但用户A以单向连接到C,表示C可以收听A,而A不能收听C
我想不出来。任何帮助都是非常感激的
我的RTCClient类中有此代码
class RTCClient(context: Application, mSocketId: String) {
val socketId: String = mSocketId
private val listOfServers = ArrayList<IceServer>()
init {
initPeerConnectionFactory(context)
createServeList()
}
private fun createServeList() {
listOfServers.add(IceServer.builder("stun:stun.services.mozilla.com").createIceServer())
listOfServers.add(IceServer.builder("stun:stun.l.google.com:19302").createIceServer())
listOfServers.add(
IceServer.builder("turn:ip:port").setUsername("usernmae")
.setPassword("password").createIceServer()
)
}
private val peerConnectionFactory by lazy { buildPeerConnectionFactory() }
private val localAudioSource by lazy { peerConnectionFactory.createAudioSource(MediaConstraints()) }
private val peerConnection by lazy { buildPeerConnection(peerConnectionObserver) }
private fun initPeerConnectionFactory(context: Application) {
val options = PeerConnectionFactory.InitializationOptions.builder(context)
.setEnableInternalTracer(true)
.setFieldTrials("WebRTC-H264HighProfile/Enabled/")
.createInitializationOptions()
PeerConnectionFactory.initialize(options)
}
private fun buildPeerConnectionFactory(): PeerConnectionFactory {
return PeerConnectionFactory
.builder()
.setOptions(PeerConnectionFactory.Options().apply {
disableEncryption = true
disableNetworkMonitor = true
})
.createPeerConnectionFactory()
}
private fun buildPeerConnection(observer: PeerConnection.Observer) =
peerConnectionFactory.createPeerConnection(
listOfServers,
observer
)
fun startLocalAudioSource(): ConnectionFactory {
val audioTrack = peerConnectionFactory.createAudioTrack("ARDAMSa0", localAudioSource)
val localMediaStream = peerConnectionFactory.createLocalMediaStream("ARDAMS")
localMediaStream.addTrack(audioTrack)
peerConnection?.addStream(localMediaStream)
return ConnectionFactory(peerConnectionFactory, peerConnection)
}
private fun PeerConnection.call(sdpObserver: SdpObserver) {
val constraints = MediaConstraints().apply {
mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveVideo", "false"))
}
createOffer(object : SdpObserver by sdpObserver {
override fun onCreateSuccess(desc: SessionDescription?) {
setLocalDescription(object : SdpObserver {
override fun onSetFailure(p0: String?) {
}
override fun onSetSuccess() {
}
override fun onCreateSuccess(p0: SessionDescription?) {
}
override fun onCreateFailure(p0: String?) {
}
}, desc)
sdpObserver.onCreateSuccess(desc)
}
}, constraints)
}
private fun PeerConnection.answer(sdpObserver: SdpObserver) {
val constraints = MediaConstraints().apply {
mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveVideo", "false"))
}
createAnswer(object : SdpObserver by sdpObserver {
override fun onCreateSuccess(p0: SessionDescription?) {
setLocalDescription(object : SdpObserver {
override fun onSetFailure(p0: String?) {
}
override fun onSetSuccess() {
}
override fun onCreateSuccess(p0: SessionDescription?) {
}
override fun onCreateFailure(p0: String?) {
}
}, p0)
sdpObserver.onCreateSuccess(p0)
}
}, constraints)
}
fun call(sdpObserver: SdpObserver) = peerConnection?.call(sdpObserver)
fun answer(sdpObserver: SdpObserver) = peerConnection?.answer(sdpObserver)
fun onRemoteSessionReceived(sessionDescription: SessionDescription) {
peerConnection?.setRemoteDescription(object : SdpObserver {
override fun onSetFailure(p0: String?) {
}
override fun onSetSuccess() {
}
override fun onCreateSuccess(p0: SessionDescription?) {
}
override fun onCreateFailure(p0: String?) {
}
}, sessionDescription)
}
fun addIceCandidate(iceCandidate: IceCandidate?) {
peerConnection?.addIceCandidate(iceCandidate)
}
val sdpObserver = object : AppSdpObserver() {
override fun onCreateSuccess(p0: SessionDescription?) {
super.onCreateSuccess(p0)
SocketConnection.socket.emit("offer", BaseClass.gSon.toJson(p0), socketId)
}
}
private val peerConnectionObserver = object : PeerConnectionObserver() {
override fun onIceCandidate(p0: IceCandidate?) {
super.onIceCandidate(p0)
SocketConnection.socket.emit("ice", BaseClass.gSon.toJson(p0), socketId)
}
}
}
这是对等连接观察者类
open class PeerConnectionObserver : PeerConnection.Observer {
override fun onIceCandidate(p0: IceCandidate?) {
Timber.tag("VoiceChatFragment").d("On ice candidates")
}
override fun onDataChannel(p0: DataChannel?) {
Timber.tag("VoiceChatFragment").d("On Data Channel")
}
override fun onIceConnectionReceivingChange(p0: Boolean) {
Timber.tag("VoiceChatFragment").d("On Ice connection receiving change")
}
override fun onIceConnectionChange(p0: PeerConnection.IceConnectionState?) {
Timber.tag("VoiceChatFragment").d("On ice connection change")
}
override fun onIceGatheringChange(p0: PeerConnection.IceGatheringState?) {
Timber.tag("VoiceChatFragment").d("On ice gathering change")
}
override fun onAddStream(p0: MediaStream?) {
Timber.tag("VoiceChatFragment").d("On Add stream")
}
override fun onSignalingChange(p0: PeerConnection.SignalingState?) {
Timber.tag("VoiceChatFragment").d("On Signaling change")
}
override fun onIceCandidatesRemoved(p0: Array<out IceCandidate>?) {
Timber.tag("VoiceChatFragment").d("On ice candidates removed")
}
override fun onRemoveStream(p0: MediaStream?) {
Timber.tag("VoiceChatFragment").d("On remove stream")
}
override fun onRenegotiationNeeded() {
Timber.tag("VoiceChatFragment").d("On renegotiation needed")
}
override fun onAddTrack(p0: RtpReceiver?, p1: Array<out MediaStream>?) {
Timber.tag("VoiceChatFragment").d("On add track")
}
}
开放类PeerConnectionObserver:PeerConnection.Observer{
覆盖IceCandidate(p0:ICEScandidate?){
Timber.tag(“VoiceChatFragment”).d(“冰上候选人”)
}
覆盖数据通道(p0:数据通道?){
Timber.tag(“VoiceChatFragment”).d(“在数据通道上”)
}
重写OniconConnectionReceivingChange(p0:布尔值){
Timber.tag(“VoiceChatFragment”).d(“冰上连接接收变更”)
}
重写连接更改(p0:PeerConnection.IceConnectionState?){
Timber.tag(“VoiceChatFragment”).d(“冰上连接变更”)
}
覆盖更改(p0:PeerConnection.IceGatheringState?){
Timber.tag(“VoiceChatFragment”).d(“关于冰收集的变化”)
}
覆盖ADStream(p0:MediaStream?){
Timber.tag(“VoiceChatFragment”).d(“添加流”)
}
覆盖fun onSignalingChange(p0:PeerConnection.SignalingState?){
Timber.tag(“VoiceChatFragment”).d(“关于信号变化”)
}
覆盖已删除的onIceCandidatesRemoved(p0:Array?){
Timber.tag(“VoiceChatFragment”).d(“在冰上移除”)
}
覆盖onRemoveStream(p0:MediaStream?){
Timber.tag(“VoiceChatFragment”).d(“在移除流上”)
}
覆盖重新协商所需的乐趣(){
Timber.tag(“VoiceChatFragment”).d(“需要重新谈判”)
}
覆盖ADDROCK上的乐趣(p0:RTPRECIVER?,p1:Array?){
Timber.tag(“VoiceChatFragment”).d(“在添加轨道上”)
}
}
open class AppSdpObserver : SdpObserver {
override fun onSetFailure(p0: String?) {
Timber.tag("VoiceChatFragment").d("On set failure. Reason $p0")
}
override fun onSetSuccess() {
Timber.tag("VoiceChatFragment").d("On set success")
}
override fun onCreateSuccess(p0: SessionDescription?) {
Timber.tag("VoiceChatFragment").d("On create success")
}
override fun onCreateFailure(p0: String?) {
Timber.tag("VoiceChatFragment").d("On create failure. Reason $p0")
}
}
open class PeerConnectionObserver : PeerConnection.Observer {
override fun onIceCandidate(p0: IceCandidate?) {
Timber.tag("VoiceChatFragment").d("On ice candidates")
}
override fun onDataChannel(p0: DataChannel?) {
Timber.tag("VoiceChatFragment").d("On Data Channel")
}
override fun onIceConnectionReceivingChange(p0: Boolean) {
Timber.tag("VoiceChatFragment").d("On Ice connection receiving change")
}
override fun onIceConnectionChange(p0: PeerConnection.IceConnectionState?) {
Timber.tag("VoiceChatFragment").d("On ice connection change")
}
override fun onIceGatheringChange(p0: PeerConnection.IceGatheringState?) {
Timber.tag("VoiceChatFragment").d("On ice gathering change")
}
override fun onAddStream(p0: MediaStream?) {
Timber.tag("VoiceChatFragment").d("On Add stream")
}
override fun onSignalingChange(p0: PeerConnection.SignalingState?) {
Timber.tag("VoiceChatFragment").d("On Signaling change")
}
override fun onIceCandidatesRemoved(p0: Array<out IceCandidate>?) {
Timber.tag("VoiceChatFragment").d("On ice candidates removed")
}
override fun onRemoveStream(p0: MediaStream?) {
Timber.tag("VoiceChatFragment").d("On remove stream")
}
override fun onRenegotiationNeeded() {
Timber.tag("VoiceChatFragment").d("On renegotiation needed")
}
override fun onAddTrack(p0: RtpReceiver?, p1: Array<out MediaStream>?) {
Timber.tag("VoiceChatFragment").d("On add track")
}
}