client-sdk-react-native icon indicating copy to clipboard operation
client-sdk-react-native copied to clipboard

VideoTrack Surface conflict on Android when rendering in FlatList with multi-column layout

Open arekkubaczkowski opened this issue 8 months ago • 6 comments

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:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. 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.

arekkubaczkowski avatar Mar 21 '25 09:03 arekkubaczkowski

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.

arekkubaczkowski avatar Mar 21 '25 11:03 arekkubaczkowski

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 avatar Mar 22 '25 10:03 davidliu

@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?

arekkubaczkowski avatar Mar 24 '25 09:03 arekkubaczkowski

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

arekkubaczkowski avatar Mar 24 '25 09:03 arekkubaczkowski

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.

davidliu avatar Mar 24 '25 16:03 davidliu

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.

arekkubaczkowski avatar Mar 25 '25 11:03 arekkubaczkowski