client-sdk-react-native
client-sdk-react-native copied to clipboard
VideoTrack Surface conflict on Android when rendering in FlatList with multi-column layout
Describe the bug
When rendering LiveKit’s VideoView components in a paginated FlatList with multiple tiles per screen (e.g. two columns or a grid of video tiles), we are experiencing severe rendering glitches on Android: • The same participant’s video appears in multiple tiles, even though each tile is meant to render a different participant. • Occasionally, a tile shows a blend or flicker of multiple video streams. • In some cases, a tile appears black or blank. • The issue only happens on Android, and does not occur on iOS. • If we switch to rendering a single column (1 tile per page), the problem disappears entirely.
Context & Observations • We are rendering a horizontal FlatList with paging enabled. • Each page shows up to 6 participants in a 2-column layout (e.g. 2x3 grid). • We suspect the issue is related to how Android handles SurfaceView, possibly due to view recycling or overlapping surfaces.
I am entirely sure that there is no issue with any missing keys or something like that. On iOS it works perfectly smooth.
https://github.com/user-attachments/assets/ca1dca70-1691-4013-a3fc-b085c603f449
To Reproduce
Steps to reproduce the behavior:
- Go to '...'
- Click on '....'
- Scroll down to '....'
- See error
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Device Info:
- Device:
- OS: Android
Dependencies Info (please reference your package-lock.json or yarn.lock file, not just your package.json):
"@livekit/react-native": "2.6.5" "livekit-client": "2.9.8" "@livekit/react-native-expo-plugin": "^1.0.1" "@livekit/react-native-webrtc": "125.0.9"
Additional context Add any other context about the problem here, such as crash logs and stack traces if applicable.
Update: it doesn't matter if it's one or two column layout, it always occurs when it's in the Flatlist. I tried to not render the pages that are out of the viewport but it also didn't help. it seems like the surface view cannot manage mounting/unmount properly within a flatlist.
Hmm, can you provide a code example of how you're rendering the items in your horizontal flat list (with styles included)? AFAIK I haven't seen this in our example app, which uses a horizontal flat list to render the participants.
@davidliu I just found out that is not actually related to how it's rendered on my end, that would be actually weird because I had no changes in this area lately but that issue started occurring suddenly. It turned out that react-native-reanimated@^3.17.1 introduced it, when I downgrade it to 3.16.7 it starts working properly again. Can you please try it on your end?
worth to add that I am using some Animated.View components as a wrappers for individual video tracks, it is responsible for some exiting/entering animations as well as layout transitions
For some context, hardware rendered views (i.e. the video view) can't be clipped in software rendering. If the Animated.View lets the view take up as much space as it wanted within its view, you'd get the issue you're seeing. Generally the fix would be to make sure that the view's width/height are constrained to where it's supposed to be.
I can find this open bug mentioned on react-native-animated, which has a workaround to get the layout dimensions of the flat list and setting a fixed dimension on the container.
https://github.com/software-mansion/react-native-reanimated/pull/5758/files
Try the workaround and see if that fixes it for you. If not, providing a code sample that I could try out would be greatly helpful.
actually we explicitly set dimensions of particular video track container (Animated.View). The point is that everything works properly in 3.16.7 and breaks in 3.17.1, so there must be some significant change in the reanimated library that causes such a conflict. For now we are fine to use the previous version but if possible let's keep this issue open for tracking eventual other issues.