Приложение
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
package calls.data.remote
|
||||
|
||||
import android.content.Context
|
||||
import android.media.AudioAttributes
|
||||
import android.media.AudioFocusRequest
|
||||
import android.media.AudioManager
|
||||
import android.os.Build
|
||||
|
||||
class CallAudioManager(private val context: Context) {
|
||||
private val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
private var originalMode: Int = AudioManager.MODE_NORMAL
|
||||
private var originalIsSpeakerphoneOn: Boolean = false
|
||||
|
||||
fun startCallMode(isVideoCall: Boolean) {
|
||||
originalMode = audioManager.mode
|
||||
originalIsSpeakerphoneOn = audioManager.isSpeakerphoneOn
|
||||
|
||||
audioManager.mode = AudioManager.MODE_IN_COMMUNICATION
|
||||
setSpeakerphoneOn(isVideoCall)
|
||||
|
||||
// Запрашиваем фокус аудио
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val playbackAttributes = AudioAttributes.Builder()
|
||||
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||
.build()
|
||||
val focusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
|
||||
.setAudioAttributes(playbackAttributes)
|
||||
.build()
|
||||
audioManager.requestAudioFocus(focusRequest)
|
||||
}
|
||||
}
|
||||
|
||||
fun setSpeakerphoneOn(on: Boolean) {
|
||||
audioManager.isSpeakerphoneOn = on
|
||||
}
|
||||
|
||||
fun stopCallMode() {
|
||||
audioManager.mode = originalMode
|
||||
audioManager.isSpeakerphoneOn = originalIsSpeakerphoneOn
|
||||
audioManager.abandonAudioFocus(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package calls.data.remote
|
||||
|
||||
import android.content.Context
|
||||
import org.webrtc.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class GroupWebRtcManager @Inject constructor(private val context: Context) {
|
||||
private val peerConnections = ConcurrentHashMap<String, PeerConnection>()
|
||||
private val factory: PeerConnectionFactory by lazy { createFactory() }
|
||||
|
||||
private fun createFactory(): PeerConnectionFactory {
|
||||
PeerConnectionFactory.initialize(
|
||||
PeerConnectionFactory.InitializationOptions.builder(context).createInitializationOptions()
|
||||
)
|
||||
return PeerConnectionFactory.builder()
|
||||
.setVideoEncoderFactory(DefaultVideoEncoderFactory(EglBase.create().eglBaseContext, true, true))
|
||||
.setVideoDecoderFactory(DefaultVideoDecoderFactory(EglBase.create().eglBaseContext))
|
||||
.createPeerConnectionFactory()
|
||||
}
|
||||
|
||||
fun addParticipant(userId: String, observer: PeerConnection.Observer): PeerConnection? {
|
||||
val iceServers = listOf(
|
||||
PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer()
|
||||
)
|
||||
val pc = factory.createPeerConnection(iceServers, observer)
|
||||
if (pc != null) {
|
||||
peerConnections[userId] = pc
|
||||
}
|
||||
return pc
|
||||
}
|
||||
|
||||
fun removeParticipant(userId: String) {
|
||||
peerConnections[userId]?.dispose()
|
||||
peerConnections.remove(userId)
|
||||
}
|
||||
|
||||
fun getPeerConnection(userId: String): PeerConnection? = peerConnections[userId]
|
||||
|
||||
fun closeAll() {
|
||||
peerConnections.values.forEach { it.dispose() }
|
||||
peerConnections.clear()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package calls.data.remote
|
||||
|
||||
import android.content.Context
|
||||
import org.webrtc.*
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class WebRtcManager @Inject constructor(private val context: Context) {
|
||||
private var peerConnection: PeerConnection? = null
|
||||
private val factory: PeerConnectionFactory by lazy { createFactory() }
|
||||
|
||||
// Аудио и видео источники
|
||||
private val videoSource by lazy { factory.createVideoSource(false) }
|
||||
private val audioSource by lazy { factory.createAudioSource(MediaConstraints()) }
|
||||
|
||||
private fun createFactory(): PeerConnectionFactory {
|
||||
PeerConnectionFactory.initialize(
|
||||
PeerConnectionFactory.InitializationOptions.builder(context).createInitializationOptions()
|
||||
)
|
||||
return PeerConnectionFactory.builder()
|
||||
.setVideoEncoderFactory(DefaultVideoEncoderFactory(EglBase.create().eglBaseContext, true, true))
|
||||
.setVideoDecoderFactory(DefaultVideoDecoderFactory(EglBase.create().eglBaseContext))
|
||||
.createPeerConnectionFactory()
|
||||
}
|
||||
|
||||
fun initializePeerConnection(observer: PeerConnection.Observer) {
|
||||
val iceServers = listOf(
|
||||
PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer()
|
||||
)
|
||||
peerConnection = factory.createPeerConnection(iceServers, observer)
|
||||
}
|
||||
|
||||
fun createOffer(observer: SdpObserver) {
|
||||
peerConnection?.createOffer(observer, MediaConstraints())
|
||||
}
|
||||
|
||||
fun setRemoteDescription(sdp: String, type: SessionDescription.Type, observer: SdpObserver) {
|
||||
peerConnection?.setRemoteDescription(observer, SessionDescription(type, sdp))
|
||||
}
|
||||
|
||||
fun addIceCandidate(candidate: IceCandidate) {
|
||||
peerConnection?.addIceCandidate(candidate)
|
||||
}
|
||||
|
||||
fun close() {
|
||||
peerConnection?.dispose()
|
||||
peerConnection = null
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user