Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI frame drop while loading (initial buffer) the video #2744

Closed
matinzd opened this issue Jun 25, 2022 · 14 comments · Fixed by #2848
Closed

UI frame drop while loading (initial buffer) the video #2744

matinzd opened this issue Jun 25, 2022 · 14 comments · Fixed by #2848
Labels
Platform: iOS triage needed Help needed to confirm the issue

Comments

@matinzd
Copy link

matinzd commented Jun 25, 2022

Bug

The main UI thread is being blocked by loading the video in the initial buffer, causing the UI to drop to 5-20 fps.

Platform

Which player are you experiencing the problem on:

  • iOS

Environment info

React native info output:

System:
    OS: macOS 12.4
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 315.81 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.15.0 - ~/.nvm/versions/node/v16.15.0/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 8.5.5 - ~/.nvm/versions/node/v16.15.0/bin/npm
    Watchman: 2022.05.16.00 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.11.2 - /Users/matin/.rvm/gems/ruby-3.0.2/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 21.4, iOS 15.4, macOS 12.3, tvOS 15.4, watchOS 8.5
    Android SDK:
      API Levels: 28, 29, 30, 31
      Build Tools: 28.0.3, 29.0.2, 30.0.2, 30.0.3, 31.0.0, 31.0.0
      System Images: android-27 | Google APIs Intel x86 Atom, android-29 | Google Play Intel x86 Atom, android-29 | Google Play Intel x86 Atom_64, android-30 | Google APIs Intel x86 Atom, android-30 | Google Play ARM 64 v8a, android-30 | Google Play Intel x86 Atom, android-30 | Google Play Intel x86 Atom_64, android-31 | Google APIs Intel x86 Atom_64, android-S | Google Play Intel x86 Atom_64
      Android NDK: 23.0.7344513-beta4
  IDEs:
    Android Studio: 4.2 AI-202.7660.26.42.7351085
    Xcode: 13.3/13E113 - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.10 - /usr/local/opt/openjdk@11/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2 
    react-native: 0.68.2 => 0.68.2 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found
info React Native v0.69.0 is now available (your project is running on v0.68.2).
info Changelog: https://github.com/facebook/react-native/releases/tag/v0.69.0.
info Diff: https://react-native-community.github.io/upgrade-helper/?from=0.68.2.
info To upgrade, run "react-native upgrade".

Library version: https://github.com/react-native-video/react-native-video.git#054abcac8e1dcb738b0b679f8b496474f8a159e5

Steps To Reproduce

  1. Create a list of items with FlatList
  2. Load the video when item is viewable
  3. Try scrolling

Expected behaviour

  1. Not having frame drop

Reproducible sample code

interface Props extends VideoProperties {
  isInViewport: boolean
  autoPlay?: boolean
}

export const VideoPlayer = ({
  isInViewport = false,
  autoPlay = false,
  source,
  ...rest
}: Props) => {
  const {ref, ...player} = useVideoPlayer(isInViewport, autoPlay)

  return (
    <Pressable onPress={() => {}}>
      {isInViewport && (
        <Video
          {...rest}
          style={[styles.video, rest.style]}
          source={source}
          resizeMode={'contain'}
          playInBackground={false}
          playWhenInactive={false}
          ignoreSilentSwitch={'ignore'}
          ref={ref}
          paused={player.paused}
          muted={player.muted}
          onProgress={player.onProgress}
        />
      )}
      {!isInViewport && (
        <Image
          source={{uri: rest.poster}}
          resizeMode={'contain'}
          style={styles.video}
        />
      )}
      <VideoOverlay {...player} />
    </Pressable>
  )
}

Screen record

https://drive.google.com/file/d/1O-S3wdNHIk_somhq-bSwDwaZ3HiAVR8A/view?usp=sharing

@matinzd matinzd changed the title Frame drop while loading (initial buffer) the video UI frame drop while loading (initial buffer) the video Jun 25, 2022
@hueniverse hueniverse added Platform: iOS triage needed Help needed to confirm the issue labels Jun 25, 2022
@jpike88
Copy link

jpike88 commented Jul 14, 2022

I have the same problem. I present my video, and there's a moment of lockup in animation, interaction when the video is initially loading.

Screen.Recording.2022-07-14.at.11.32.29.mov

See video. First presentation, I'm actually trying to gesture to dismiss the modal early.

Second time, I wait a moment for video to actually load, then I play with gesture. You can see it works that time. (Yes it's fullscreen gesture, in the video I pulled down from top but doesn't matter, it works if I pull down from anywhere like it should)

@jpike88
Copy link

jpike88 commented Jul 14, 2022

maybe related: https://stackoverflow.com/questions/30363502/maintaining-good-scroll-performance-when-using-avplayer

@pratishshr
Copy link

Getting this issue as well. If the video is autoplayed while scrolling, the scrolling stutters a bit.

@freeboub
Copy link
Collaborator

freeboub commented Aug 6, 2022

Is this ios only or do you also have the issue on android ?

@matinzd
Copy link
Author

matinzd commented Aug 6, 2022

Is this ios only or do you also have the issue on android ?

I didn’t have time to test it on Android.

@freeboub
Copy link
Collaborator

freeboub commented Aug 6, 2022

@matinzd It would be usefull ... ios implemenation has reacently been rewriten in swift, it can be a root cause.
Addtionnal question, did you test with older version ? (5.2)

@matinzd
Copy link
Author

matinzd commented Aug 6, 2022

@matinzd It would be usefull ... ios implemenation has reacently been rewriten in swift, it can be a root cause.
Addtionnal question, did you test with older version ? (5.2)

I am using this commit from master branch: https://github.com/react-native-video/react-native-video.git#054abcac8e1dcb738b0b679f8b496474f8a159e5

@matinzd
Copy link
Author

matinzd commented Aug 9, 2022

@matinzd It would be usefull ... ios implemenation has reacently been rewriten in swift, it can be a root cause. Addtionnal question, did you test with older version ? (5.2)

Ok, I tested it on android and it's working smoothly. This is the first performance issue I am facing on iOS which is fine on Android :)

@ckaznable
Copy link
Contributor

Same problem, but switch to 5.2.0 and it works well

@ngima
Copy link

ngima commented Aug 15, 2022

I am also having the similar issue in iOS.

In my case, UI freezes for a while while navigating to the video screen. And also while using textTracks & selectedTextTrack, performance degrades.

@sperko00
Copy link
Contributor

sperko00 commented Aug 18, 2022

I am having same issue in iOS with version 6.0.0-alpha.2.
When Video player is rendered application UI is blocked until video from external url is loaded which was not the case with version 5.2.0.
On Android it works fine.

UPDATE
I have managed to get this working by changing way of assigning AVPlayer in RCTVideo.swift.

In function setSrc() changing line 267

self._player = AVPlayer(playerItem: self._playerItem)

to

self._player = AVPlayer()
DispatchQueue.global(qos: .default).async {
     self._player?.replaceCurrentItem(with: playerItem)
}

seems to fix this issue.

@freeboub
Copy link
Collaborator

freeboub commented Sep 5, 2022

@sperko00 can you open a PR please ? Thank you

@matinzd
Copy link
Author

matinzd commented Sep 5, 2022

I am having same issue in iOS with version 6.0.0-alpha.2. When Video player is rendered application UI is blocked until video from external url is loaded which was not the case with version 5.2.0. On Android it works fine.

UPDATE I have managed to get this working by changing way of assigning AVPlayer in RCTVideo.swift.

In function setSrc() changing line 267

self._player = AVPlayer(playerItem: self._playerItem)

to

self._player = AVPlayer()
DispatchQueue.global(qos: .default).async {
     self._player?.replaceCurrentItem(with: playerItem)
}

seems to fix this issue.

Fix seems to be legit. This will unblock the main thread while replacing the source.

@wood1986
Copy link
Contributor

wood1986 commented Nov 2, 2022

@matinzd your change is not KVO-compliance. It will crash the app when changing the src so quick

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot remove an observer <NSKeyValueObservance 0x600003dfd230> for the key path "currentItem.hasEnabledAudio" from <AVPlayer 0x600002cf03a0>, most likely because the value for the key "currentItem" has changed without an appropriate KVO notification being sent. Check the KVO-compliance of the AVPlayer class.'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: iOS triage needed Help needed to confirm the issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants