David Liu

More fixing up sample app

... ... @@ -9,5 +9,7 @@ class InjectionNames {
const val DISPATCHER_UNCONFINED = "dispatcher_unconfined"
const val SIGNAL_JSON_ENABLED = "signal_json_enabled"
const val OPTIONS_VIDEO_HW_ACCEL = "options_video_hw_accel"
}
}
\ No newline at end of file
... ...
... ... @@ -7,6 +7,7 @@ import dagger.Provides
import org.webrtc.*
import org.webrtc.audio.AudioDeviceModule
import org.webrtc.audio.JavaAudioDeviceModule
import javax.inject.Named
import javax.inject.Singleton
... ... @@ -76,8 +77,6 @@ class RTCModule {
}
return JavaAudioDeviceModule.builder(appContext)
.setUseHardwareAcousticEchoCanceler(true)
.setUseHardwareNoiseSuppressor(true)
.setAudioRecordErrorCallback(audioRecordErrorCallback)
.setAudioTrackErrorCallback(audioTrackErrorCallback)
.setAudioRecordStateCallback(audioRecordStateCallback)
... ... @@ -95,16 +94,35 @@ class RTCModule {
fun eglContext(eglBase: EglBase): EglBase.Context = eglBase.eglBaseContext
@Provides
fun videoEncoderFactory(eglContext: EglBase.Context): VideoEncoderFactory =
fun videoEncoderFactory(
@Named(InjectionNames.OPTIONS_VIDEO_HW_ACCEL)
videoHwAccel: Boolean,
eglContext: EglBase.Context
): VideoEncoderFactory {
return if (videoHwAccel) {
DefaultVideoEncoderFactory(
eglContext,
true,
true
)
} else {
SoftwareVideoEncoderFactory()
}
}
@Provides
fun videoDecoderFactory(eglContext: EglBase.Context): VideoDecoderFactory =
fun videoDecoderFactory(
@Named(InjectionNames.OPTIONS_VIDEO_HW_ACCEL)
videoHwAccel: Boolean,
eglContext: EglBase.Context,
): VideoDecoderFactory {
return if (videoHwAccel) {
DefaultVideoDecoderFactory(eglContext)
} else {
SoftwareVideoDecoderFactory()
}
}
@Provides
@Singleton
... ... @@ -127,5 +145,8 @@ class RTCModule {
.createPeerConnectionFactory()
}
@Provides
@Named(InjectionNames.OPTIONS_VIDEO_HW_ACCEL)
fun videoHwAccel() = false
}
}
\ No newline at end of file
... ...
... ... @@ -199,6 +199,11 @@ constructor(
override fun onUpdateParticipants(updates: List<Model.ParticipantInfo>) {
for (info in updates) {
val participantSid = Participant.Sid(info.sid)
if(localParticipant?.sid == participantSid) {
localParticipant?.updateFromInfo(info)
}
val isNewParticipant = remoteParticipants.contains(participantSid)
val participant = getOrCreateRemoteParticipant(participantSid, info)
... ...
... ... @@ -16,7 +16,7 @@ class SubscriberTransportObserver(
override fun onAddTrack(receiver: RtpReceiver, streams: Array<out MediaStream>) {
val track = receiver.track() ?: return
Timber.v { "onAddTrack: $track, ${streams.fold("") { sum, it -> "$sum, $it" }}" }
Timber.v { "onAddTrack: ${track.kind()}, ${track.id()}, ${streams.fold("") { sum, it -> "$sum, $it" }}" }
engine.listener?.onAddTrack(track, streams)
}
... ...
... ... @@ -29,6 +29,12 @@ class LocalParticipant(sid: Sid, name: String? = null) :
var engine: RTCEngine? = null
val listener: Listener? = null
fun updateFromInfo(info: Model.ParticipantInfo) {
sid = Sid(info.sid)
name = info.identity
metadata = info.metadata
}
suspend fun publishAudioTrack(
track: LocalAudioTrack,
options: LocalTrackPublicationOptions? = null
... ...
package io.livekit.android.room.track
class RemoteAudioTrack(
sid: Track.Sid,
sid: Sid,
playbackEnabled: Boolean = true,
name: String,
rtcTrack: org.webrtc.AudioTrack
) : AudioTrack(name, rtcTrack), RemoteTrack {
override var sid: Track.Sid = sid
override var sid: Sid = sid
var playbackEnabled = playbackEnabled
internal set
... ...
... ... @@ -3,6 +3,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<application
android:name=".SampleApplication"
... ...
package io.livekit.android.sample
import android.media.AudioManager
import android.os.Bundle
import android.os.Parcelable
import androidx.appcompat.app.AppCompatActivity
import com.github.ajalt.timberkt.Timber
import com.snakydesign.livedataextensions.combineLatest
import com.xwray.groupie.GroupieAdapter
import io.livekit.android.sample.databinding.CallActivityBinding
... ... @@ -25,6 +27,7 @@ class CallActivity : AppCompatActivity() {
setContentView(binding.root)
// Viewpager setup
val adapter = GroupieAdapter()
binding.viewPager.apply {
this.adapter = adapter
... ... @@ -39,6 +42,22 @@ class CallActivity : AppCompatActivity() {
val items = participants.map { participant -> ParticipantItem(room, participant) }
adapter.update(items)
}
val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
with(audioManager) {
isSpeakerphoneOn = true
isMicrophoneMute = false
mode = AudioManager.MODE_IN_COMMUNICATION
}
val result = audioManager.requestAudioFocus(
{ },
AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN
)
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
Timber.v { "Audio focus request granted for VOICE_CALL streams" }
} else {
Timber.v { "Audio focus request failed" }
}
}
... ...
... ... @@ -35,6 +35,7 @@ class CallViewModel(
ConnectOptions(false),
object : Room.Listener {
override fun onConnect(room: Room) {
updateParticipants(room)
}
override fun onDisconnect(room: Room, error: Exception?) {
... ... @@ -61,6 +62,7 @@ class CallViewModel(
}
override fun onReconnect(room: Room) {
updateParticipants(room)
}
override fun onStartRecording(room: Room) {
... ...
... ... @@ -28,10 +28,6 @@ class ParticipantItem(
override fun bind(viewBinding: ParticipantItemBinding, position: Int) {
viewBinding.run {
val existingTrack = getVideoTrack()
if (existingTrack != null) {
setupVideoIfNeeded(existingTrack, viewBinding)
} else {
remoteParticipant.listener = object : RemoteParticipant.Listener {
override fun onSubscribe(
videoTrack: RemoteVideoTrackPublication,
... ... @@ -43,6 +39,9 @@ class ParticipantItem(
}
}
}
val existingTrack = getVideoTrack()
if (existingTrack != null) {
setupVideoIfNeeded(existingTrack, viewBinding)
}
}
}
... ... @@ -60,6 +59,7 @@ class ParticipantItem(
return
}
videoBound = true
Timber.v { "adding renderer to $videoTrack" }
videoTrack.addRenderer(viewBinding.renderer)
}
... ...
... ... @@ -7,11 +7,12 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!--
<org.webrtc.SurfaceViewRenderer
android:id="@+id/pip_video_view"
android:layout_height="144dp"
android:layout_width="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp" />
-->
</FrameLayout>
... ...