Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
xuning
/
livekitAndroidXuningTest
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
davidliu
2022-02-24 04:06:34 +0900
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Committed by
GitHub
2022-02-24 04:06:34 +0900
Commit
0e576a14a8b9bfcab6ca730c7f21a3ee077c41c8
0e576a14
1 parent
3db2694d
fix state not being recomputed when track is attached (#61)
显示空白字符变更
内嵌
并排对比
正在显示
4 个修改的文件
包含
91 行增加
和
30 行删除
livekit-android-sdk/src/test/java/io/livekit/android/BaseTest.kt
livekit-android-sdk/src/test/java/io/livekit/android/room/participant/RemoteParticipantTest.kt
sample-app-compose/src/main/java/io/livekit/android/composesample/ParticipantItem.kt
sample-app-compose/src/main/java/io/livekit/android/composesample/VideoItem.kt
livekit-android-sdk/src/test/java/io/livekit/android/BaseTest.kt
查看文件 @
0e576a1
...
...
@@ -7,7 +7,7 @@ import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.mockito.junit.MockitoJUnit
@
ExperimentalCoroutinesApi
@
OptIn(ExperimentalCoroutinesApi::class)
abstract class BaseTest {
// Uncomment to enable logging in tests.
//@get:Rule
...
...
@@ -19,6 +19,6 @@ abstract class BaseTest {
@get:Rule
var coroutineRule = TestCoroutineRule()
@
ExperimentalCoroutinesApi
@
OptIn(ExperimentalCoroutinesApi::class)
fun runTest(testBody: suspend TestScope.() -> Unit) = coroutineRule.scope.runTest(testBody = testBody)
}
...
...
livekit-android-sdk/src/test/java/io/livekit/android/room/participant/RemoteParticipantTest.kt
查看文件 @
0e576a1
package io.livekit.android.room.participant
import io.livekit.android.
coroutines.TestCoroutineRule
import io.livekit.android.
BaseTest
import io.livekit.android.room.SignalClient
import io.livekit.android.room.track.TrackPublication
import io.livekit.android.util.flow
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import livekit.LivekitModels
import org.junit.Assert.*
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.Mockito
class RemoteParticipantTest {
@OptIn(ExperimentalCoroutinesApi::class)
class RemoteParticipantTest : BaseTest() {
@get:Rule
var coroutineRule = TestCoroutineRule()
lateinit var signalClient: SignalClient
lateinit var participant: RemoteParticipant
...
...
@@ -50,7 +52,6 @@ class RemoteParticipantTest {
val newTrackInfo = LivekitModels.ParticipantInfo.newBuilder(INFO)
.addTracks(TRACK_INFO)
.build()
participant.updateFromInfo(newTrackInfo)
assertEquals(1, participant.tracks.values.size)
...
...
@@ -58,6 +59,54 @@ class RemoteParticipantTest {
}
@Test
fun tracksFlow() = runTest {
val newTrackInfo = LivekitModels.ParticipantInfo.newBuilder(INFO)
.addTracks(TRACK_INFO)
.build()
val emissions = mutableListOf<Map<String, TrackPublication>>()
val job = launch {
participant::tracks.flow.collect {
emissions.add(it)
}
}
assertEquals(1, emissions.size)
assertEquals(emptyMap<String, TrackPublication>(), emissions.first())
participant.updateFromInfo(newTrackInfo)
job.cancel()
assertEquals(2, emissions.size)
assertEquals(1, emissions[1].size)
}
@Test
fun audioTracksFlow() = runTest {
val newTrackInfo = LivekitModels.ParticipantInfo.newBuilder(INFO)
.addTracks(TRACK_INFO)
.build()
val emissions = mutableListOf<Map<String, TrackPublication>>()
val job = launch {
participant::audioTracks.flow.collect {
emissions.add(it)
}
}
assertEquals(1, emissions.size)
assertEquals(emptyMap<String, TrackPublication>(), emissions.first())
participant.updateFromInfo(newTrackInfo)
job.cancel()
assertEquals(2, emissions.size)
assertEquals(1, emissions[1].size)
}
@Test
fun updateFromInfoRemovesTrack() {
val newTrackInfo = LivekitModels.ParticipantInfo.newBuilder(INFO)
.addTracks(TRACK_INFO)
...
...
sample-app-compose/src/main/java/io/livekit/android/composesample/ParticipantItem.kt
查看文件 @
0e576a1
...
...
@@ -2,7 +2,6 @@ package io.livekit.android.composesample
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Icon
import androidx.compose.material.Surface
import androidx.compose.material.Text
...
...
@@ -21,8 +20,6 @@ import io.livekit.android.composesample.ui.theme.NoVideoBackground
import io.livekit.android.room.Room
import io.livekit.android.room.participant.ConnectionQuality
import io.livekit.android.room.participant.Participant
import io.livekit.android.room.track.Track
import io.livekit.android.room.track.VideoTrack
import io.livekit.android.util.flow
/**
...
...
@@ -50,33 +47,20 @@ fun ParticipantItem(
}
}
) {
val (videoCamOff, identityBar, identityText, muteIndicator, connectionIndicator) = createRefs()
val videoTrack = participant.getTrackPublication(Track.Source.SCREEN_SHARE)?.track as? VideoTrack
?: participant.getTrackPublication(Track.Source.CAMERA)?.track as? VideoTrack
?: videoTracks.values.firstOrNull()?.track as? VideoTrack
val (videoItem, identityBar, identityText, muteIndicator, connectionIndicator) = createRefs()
if (videoTrack != null && videoTrack.enabled) {
VideoItemTrackSelector(
room = room,
participant = participant,
modifier = Modifier.fillMaxSize()
)
} else {
Icon(
painter = painterResource(id = R.drawable.outline_videocam_off_24),
contentDescription = null,
tint = Color.White,
modifier = Modifier.constrainAs(videoCamOff) {
modifier = Modifier.constrainAs(videoItem) {
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
start.linkTo(parent.start)
end.linkTo(parent.end)
width = Dimension.wrapContent
height = Dimension.wrapContent
width = Dimension.fillToConstraints
height = Dimension.fillToConstraints
}
)
}
Surface(
color = Color(0x80000000),
...
...
sample-app-compose/src/main/java/io/livekit/android/composesample/VideoItem.kt
查看文件 @
0e576a1
package io.livekit.android.composesample
import androidx.compose.foundation.layout.Box
import androidx.compose.material.Icon
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.viewinterop.AndroidView
import com.github.ajalt.timberkt.Timber
import io.livekit.android.renderer.TextureViewRenderer
import io.livekit.android.room.Room
import io.livekit.android.room.participant.Participant
...
...
@@ -12,7 +18,7 @@ import io.livekit.android.room.track.Track
import io.livekit.android.room.track.VideoTrack
import io.livekit.android.room.track.video.ComposeVisibility
import io.livekit.android.util.flow
import kotlinx.coroutines.flow.
map
import kotlinx.coroutines.flow.
*
/**
* Widget for displaying a VideoTrack. Handles the Compose <-> AndroidView interop needed to use
...
...
@@ -24,6 +30,7 @@ fun VideoItem(
videoTrack: VideoTrack,
modifier: Modifier = Modifier
) {
val videoSinkVisibility = remember(room, videoTrack) { ComposeVisibility() }
var boundVideoTrack by remember { mutableStateOf<VideoTrack?>(null) }
var view: TextureViewRenderer? by remember { mutableStateOf(null) }
...
...
@@ -91,9 +98,21 @@ fun VideoItemTrackSelector(
val subscribedVideoTracksFlow by remember(participant) {
mutableStateOf(
participant::videoTracks.flow
.map { tracks -> tracks.values.filter { pub -> pub.subscribed } }
.flatMapLatest { videoTracks ->
combine(
videoTracks.values
.map { trackPublication ->
// Re-emit when track changes
trackPublication::track.flow
.map { trackPublication }
}
) { trackPubs ->
trackPubs.toList().filter { trackPublication -> trackPublication.track != null }
}
}
)
}
val videoTracks by subscribedVideoTracksFlow.collectAsState(initial = emptyList())
val videoTrack = videoTracks.firstOrNull { pub -> pub.source == Track.Source.SCREEN_SHARE }?.track as? VideoTrack
?: videoTracks.firstOrNull { pub -> pub.source == Track.Source.CAMERA }?.track as? VideoTrack
...
...
@@ -105,5 +124,14 @@ fun VideoItemTrackSelector(
videoTrack = videoTrack,
modifier = modifier
)
} else {
Box(modifier = modifier) {
Icon(
painter = painterResource(id = R.drawable.outline_videocam_off_24),
contentDescription = null,
tint = Color.White,
modifier = Modifier.align(Alignment.Center)
)
}
}
}
\ No newline at end of file
...
...
请
注册
或
登录
后发表评论