davidliu
Committed by GitHub

Add more audio and video overrides (#82)

@@ -2,7 +2,6 @@ package io.livekit.android @@ -2,7 +2,6 @@ package io.livekit.android
2 2
3 import android.content.Context 3 import android.content.Context
4 import io.livekit.android.dagger.DaggerLiveKitComponent 4 import io.livekit.android.dagger.DaggerLiveKitComponent
5 -import io.livekit.android.dagger.LiveKitOverrides  
6 import io.livekit.android.dagger.create 5 import io.livekit.android.dagger.create
7 import io.livekit.android.room.Room 6 import io.livekit.android.room.Room
8 import io.livekit.android.room.RoomListener 7 import io.livekit.android.room.RoomListener
  1 +package io.livekit.android
  2 +
  3 +import okhttp3.OkHttpClient
  4 +import org.webrtc.VideoDecoderFactory
  5 +import org.webrtc.VideoEncoderFactory
  6 +import org.webrtc.audio.AudioDeviceModule
  7 +import org.webrtc.audio.JavaAudioDeviceModule
  8 +
  9 +/**
  10 + * Overrides to replace LiveKit internally used component with custom implementations.
  11 + */
  12 +data class LiveKitOverrides(
  13 + /**
  14 + * Override the [OkHttpClient] used by the library.
  15 + */
  16 + val okHttpClient: OkHttpClient? = null,
  17 +
  18 + /**
  19 + * Override the default [AudioDeviceModule].
  20 + */
  21 + val audioDeviceModule: AudioDeviceModule? = null,
  22 +
  23 + /**
  24 + * Called after default setup to allow for customizations on the [JavaAudioDeviceModule].
  25 + *
  26 + * Not used if [audioDeviceModule] is provided.
  27 + */
  28 + val javaAudioDeviceModuleCustomizer: ((builder: JavaAudioDeviceModule.Builder) -> Unit)? = null,
  29 +
  30 + /**
  31 + * Override the [VideoEncoderFactory] used by the library.
  32 + */
  33 + val videoEncoderFactory: VideoEncoderFactory? = null,
  34 +
  35 + /**
  36 + * Override the [VideoDecoderFactory] used by the library.
  37 + */
  38 + val videoDecoderFactory: VideoDecoderFactory? = null,
  39 +)
@@ -26,5 +26,8 @@ object InjectionNames { @@ -26,5 +26,8 @@ object InjectionNames {
26 26
27 // Overrides 27 // Overrides
28 internal const val OVERRIDE_OKHTTP = "override_okhttp" 28 internal const val OVERRIDE_OKHTTP = "override_okhttp"
  29 + internal const val OVERRIDE_AUDIO_DEVICE_MODULE = "override_audio_device_module"
  30 + internal const val OVERRIDE_JAVA_AUDIO_DEVICE_MODULE_CUSTOMIZER = "override_java_audio_device_module_customizer"
29 internal const val OVERRIDE_VIDEO_ENCODER_FACTORY = "override_video_encoder_factory" 31 internal const val OVERRIDE_VIDEO_ENCODER_FACTORY = "override_video_encoder_factory"
  32 + internal const val OVERRIDE_VIDEO_DECODER_FACTORY = "override_video_decoder_factory"
30 } 33 }
1 package io.livekit.android.dagger 1 package io.livekit.android.dagger
2 2
3 import android.content.Context 3 import android.content.Context
4 -import androidx.annotation.Nullable  
5 import dagger.BindsInstance 4 import dagger.BindsInstance
6 import dagger.Component 5 import dagger.Component
  6 +import io.livekit.android.LiveKitOverrides
7 import io.livekit.android.room.Room 7 import io.livekit.android.room.Room
8 -import okhttp3.OkHttpClient  
9 import org.webrtc.EglBase 8 import org.webrtc.EglBase
10 import org.webrtc.PeerConnectionFactory 9 import org.webrtc.PeerConnectionFactory
11 -import org.webrtc.VideoEncoderFactory  
12 -import javax.inject.Named  
13 import javax.inject.Singleton 10 import javax.inject.Singleton
14 11
15 @Singleton 12 @Singleton
@@ -19,6 +16,7 @@ import javax.inject.Singleton @@ -19,6 +16,7 @@ import javax.inject.Singleton
19 RTCModule::class, 16 RTCModule::class,
20 WebModule::class, 17 WebModule::class,
21 JsonFormatModule::class, 18 JsonFormatModule::class,
  19 + OverridesModule::class,
22 ] 20 ]
23 ) 21 )
24 internal interface LiveKitComponent { 22 internal interface LiveKitComponent {
@@ -33,16 +31,7 @@ internal interface LiveKitComponent { @@ -33,16 +31,7 @@ internal interface LiveKitComponent {
33 interface Factory { 31 interface Factory {
34 fun create( 32 fun create(
35 @BindsInstance appContext: Context, 33 @BindsInstance appContext: Context,
36 -  
37 - @BindsInstance  
38 - @Named(InjectionNames.OVERRIDE_OKHTTP)  
39 - @Nullable  
40 - okHttpClientOverride: OkHttpClient?,  
41 -  
42 - @BindsInstance  
43 - @Named(InjectionNames.OVERRIDE_VIDEO_ENCODER_FACTORY)  
44 - @Nullable  
45 - videoEncoderFactory: VideoEncoderFactory?, 34 + overridesModule: OverridesModule
46 ): LiveKitComponent 35 ): LiveKitComponent
47 } 36 }
48 } 37 }
@@ -53,15 +42,7 @@ internal fun LiveKitComponent.Factory.create( @@ -53,15 +42,7 @@ internal fun LiveKitComponent.Factory.create(
53 ): LiveKitComponent { 42 ): LiveKitComponent {
54 return create( 43 return create(
55 appContext = context, 44 appContext = context,
56 - okHttpClientOverride = overrides.okHttpClient,  
57 - videoEncoderFactory = overrides.videoEncoderFactory, 45 + overridesModule = OverridesModule(overrides)
58 ) 46 )
59 } 47 }
60 48
61 -/**  
62 - * Overrides to replace LiveKit internally used component with custom implementations.  
63 - */  
64 -data class LiveKitOverrides(  
65 - val okHttpClient: OkHttpClient? = null,  
66 - val videoEncoderFactory: VideoEncoderFactory? = null,  
67 -)  
  1 +package io.livekit.android.dagger
  2 +
  3 +import androidx.annotation.Nullable
  4 +import dagger.Module
  5 +import dagger.Provides
  6 +import io.livekit.android.LiveKitOverrides
  7 +import javax.inject.Named
  8 +
  9 +@Module
  10 +class OverridesModule(private val overrides: LiveKitOverrides) {
  11 +
  12 + @Provides
  13 + @Named(InjectionNames.OVERRIDE_OKHTTP)
  14 + @Nullable
  15 + fun okHttpClient() = overrides.okHttpClient
  16 +
  17 + @Provides
  18 + @Named(InjectionNames.OVERRIDE_AUDIO_DEVICE_MODULE)
  19 + @Nullable
  20 + fun audioDeviceModule() = overrides.audioDeviceModule
  21 +
  22 + @Provides
  23 + @Named(InjectionNames.OVERRIDE_JAVA_AUDIO_DEVICE_MODULE_CUSTOMIZER)
  24 + @Nullable
  25 + fun javaAudioDeviceModuleCustomizer() = overrides.javaAudioDeviceModuleCustomizer
  26 +
  27 + @Provides
  28 + @Named(InjectionNames.OVERRIDE_VIDEO_ENCODER_FACTORY)
  29 + @Nullable
  30 + fun videoEncoderFactory() = overrides.videoEncoderFactory
  31 +
  32 + @Provides
  33 + @Named(InjectionNames.OVERRIDE_VIDEO_DECODER_FACTORY)
  34 + @Nullable
  35 + fun videoDecoderFactory() = overrides.videoDecoderFactory
  36 +
  37 +}
@@ -20,7 +20,19 @@ import javax.inject.Singleton @@ -20,7 +20,19 @@ import javax.inject.Singleton
20 object RTCModule { 20 object RTCModule {
21 @Provides 21 @Provides
22 @Singleton 22 @Singleton
23 - fun audioModule(appContext: Context): AudioDeviceModule { 23 + @JvmSuppressWildcards
  24 + fun audioModule(
  25 + @Named(InjectionNames.OVERRIDE_AUDIO_DEVICE_MODULE)
  26 + @Nullable
  27 + audioDeviceModuleOverride: AudioDeviceModule?,
  28 + @Named(InjectionNames.OVERRIDE_JAVA_AUDIO_DEVICE_MODULE_CUSTOMIZER)
  29 + @Nullable
  30 + moduleCustomizer: ((builder: JavaAudioDeviceModule.Builder) -> Unit)?,
  31 + appContext: Context
  32 + ): AudioDeviceModule {
  33 + if (audioDeviceModuleOverride != null) {
  34 + return audioDeviceModuleOverride
  35 + }
24 36
25 // Set audio record error callbacks. 37 // Set audio record error callbacks.
26 val audioRecordErrorCallback = object : JavaAudioDeviceModule.AudioRecordErrorCallback { 38 val audioRecordErrorCallback = object : JavaAudioDeviceModule.AudioRecordErrorCallback {
@@ -80,14 +92,16 @@ object RTCModule { @@ -80,14 +92,16 @@ object RTCModule {
80 } 92 }
81 } 93 }
82 94
83 - return JavaAudioDeviceModule.builder(appContext) 95 + val builder = JavaAudioDeviceModule.builder(appContext)
84 .setUseHardwareAcousticEchoCanceler(true) 96 .setUseHardwareAcousticEchoCanceler(true)
85 .setUseHardwareNoiseSuppressor(true) 97 .setUseHardwareNoiseSuppressor(true)
86 .setAudioRecordErrorCallback(audioRecordErrorCallback) 98 .setAudioRecordErrorCallback(audioRecordErrorCallback)
87 .setAudioTrackErrorCallback(audioTrackErrorCallback) 99 .setAudioTrackErrorCallback(audioTrackErrorCallback)
88 .setAudioRecordStateCallback(audioRecordStateCallback) 100 .setAudioRecordStateCallback(audioRecordStateCallback)
89 .setAudioTrackStateCallback(audioTrackStateCallback) 101 .setAudioTrackStateCallback(audioTrackStateCallback)
90 - .createAudioDeviceModule() 102 +
  103 + moduleCustomizer?.invoke(builder)
  104 + return builder.createAudioDeviceModule()
91 } 105 }
92 106
93 @Provides 107 @Provides
@@ -124,8 +138,11 @@ object RTCModule { @@ -124,8 +138,11 @@ object RTCModule {
124 @Named(InjectionNames.OPTIONS_VIDEO_HW_ACCEL) 138 @Named(InjectionNames.OPTIONS_VIDEO_HW_ACCEL)
125 videoHwAccel: Boolean, 139 videoHwAccel: Boolean,
126 eglContext: EglBase.Context, 140 eglContext: EglBase.Context,
  141 + @Named(InjectionNames.OVERRIDE_VIDEO_DECODER_FACTORY)
  142 + @Nullable
  143 + videoDecoderFactoryOverride: VideoDecoderFactory?
127 ): VideoDecoderFactory { 144 ): VideoDecoderFactory {
128 - return if (videoHwAccel) { 145 + return videoDecoderFactoryOverride ?: if (videoHwAccel) {
129 DefaultVideoDecoderFactory(eglContext) 146 DefaultVideoDecoderFactory(eglContext)
130 } else { 147 } else {
131 SoftwareVideoDecoderFactory() 148 SoftwareVideoDecoderFactory()
@@ -8,7 +8,7 @@ import androidx.lifecycle.viewModelScope @@ -8,7 +8,7 @@ import androidx.lifecycle.viewModelScope
8 import com.github.ajalt.timberkt.Timber 8 import com.github.ajalt.timberkt.Timber
9 import io.livekit.android.LiveKit 9 import io.livekit.android.LiveKit
10 import io.livekit.android.RoomOptions 10 import io.livekit.android.RoomOptions
11 -import io.livekit.android.dagger.LiveKitOverrides 11 +import io.livekit.android.LiveKitOverrides
12 import io.livekit.android.room.Room 12 import io.livekit.android.room.Room
13 import io.livekit.android.room.participant.Participant 13 import io.livekit.android.room.participant.Participant
14 import io.livekit.android.room.participant.VideoTrackPublishDefaults 14 import io.livekit.android.room.participant.VideoTrackPublishDefaults