TheWidlarzGroup / react-native-video

A <Video /> component for react-native
https://thewidlarzgroup.github.io/react-native-video/
MIT License
7.17k stars 2.89k forks source link

[iOS] Energy consumption is very high, even when app is in the background #2947

Closed Nesh108 closed 1 year ago

Nesh108 commented 1 year ago

Bug

Platform

Which player are you experiencing the problem on:

Environment info

React native info output:

System:
    OS: macOS 12.6.1
    CPU: (10) x64 Apple M1 Pro
    Memory: 32.00 MB / 32.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 19.0.1 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 8.19.2 - /usr/local/bin/npm
    Watchman: 2022.10.31.00 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.11.3 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 22.1, iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1
    Android SDK:
      API Levels: 23, 28, 29, 30, 31, 32, 33
      Build Tools: 28.0.3, 29.0.0, 29.0.2, 29.0.3, 30.0.2, 30.0.3, 31.0.0, 32.0.0, 32.1.0, 33.0.0, 33.0.0
      System Images: android-21 | Intel x86 Atom_64, android-21 | Google APIs Intel x86 Atom_64, android-30 | Google APIs ARM 64 v8a, android-30 | Google Play ARM 64 v8a, android-31 | Google APIs Intel x86 Atom_64, android-32 | Google APIs ARM 64 v8a, android-32 | Google Play ARM 64 v8a
      Android NDK: 20.1.5948944
  IDEs:
    Android Studio: 2021.3 AI-213.7172.25.2113.9123335
    Xcode: 14.1/14B47b - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.13 - /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/javac
  npmPackages:
    @react-native-community/cli: 9.0.0 => 9.0.0
    react: 18.2.0 => 18.2.0
    react-native: 0.69.5 => 0.69.5
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Library version: commit #8013b9a19763a326aa94b0967e9e8925ffd63693

Steps To Reproduce

  1. Run app with Xcode debug on iOS
  2. Check Energy tab in Debug navigator
  3. Start audio/video
  4. Notice energy impact
  5. Put app in background (don't kill it)
  6. Notice how the app still has high consumption (leading iOS to eventually kill the app for overusing the CPU)

Note: This high CPU doesn't happen if the audio/video has not been started.

Expected behaviour

  1. Run app with Xcode debug on iOS
  2. Check Energy tab in Debug navigator
  3. Start audio/video
  4. Notice usage
  5. Put app in background (don't kill it)
  6. The app should have a decreased energy impact when in background

Note

This is why I believe some people are having issues with background audio/video playing on iOS, so it might be important to look into it.

Component:


<Video source={{uri: this.props.media}}
      ref={(ref) => {
          this.player = ref;
      }}
      key={this.props.media.id}
      paused={this.state.paused}
      onLoad={this.setDuration.bind(this)}
      onProgress={this.setTime.bind(this)}
      progressUpdateInterval={this.state.isActive ? 1000 : 9999999}
      ignoreSilentSwitch={'ignore'}
      playInBackground={true}
      playWhenInactive={true}
      repeat={false}
      onEnd={this.onEnd} />
EfosaSO commented 1 year ago

@Nesh108 we've been experiencing similar battery drain issues and have not been able to narrow it down yet. Our first thought was it was related to PiP features, your issue makes me think otherwise now and may be something else.

Did you enable background audio on your xcode project?

Nesh108 commented 1 year ago

@EfosaSO Yes, it is enabled.

What I am noticing is that backgrounding the app causes the CPU to skyrocket to 100% and because of that, iOS decides to terminate the app when the screen is off.

iphonic commented 1 year ago

Do we have any update on this issue, facing the same? Using the library to play Audios mostly it plays in the background and drains the battery highly.

Nesh108 commented 1 year ago

For us, it turned out to be an issue with another library (rn-placeholder), which was causing the issue.

Basically, to generalise the problem: anything that makes the app use too much CPU even when backgrounded will trigger iOS to flag it and kill it. So, profile your app and see if that's the case then start removing chunks of your app until the CPU spikes disappear and work your way back.

iphonic commented 6 months ago

@freeboub This issue still exist in the latest beta version 6.0.0-beta.8 using RN 0.71.11, the energy consumption goes higher when the app sent to background and kills the app, I am playing Audio using the player. How to handle, many active users are affected.

oddlyspaced commented 2 months ago

Hello folks, in our internal testing we also noticed our iOS app causing a lot of battery drain while being in the background. We profiled our app using XCode instruments -> CPU Profiler and noticed some method calls related to AVFCore happening while the app was in the background. We made some comparisons internally and figured out that the Video component was causing the battery drain, even after passing all the pause and background related props properly.

We landed on the following component as a basic solution :

interface IStateAwareVideoProps {
    ref?: React.MutableRefObject<Video>;
    props: VideoProperties;
}

export const StateAwareVideo = ({ ref, props }: IStateAwareVideoProps) => {
    const appState = useRef(AppState.currentState);
    const [appStateVisible, setAppStateVisible] = useState(appState.current);

    useEffect(() => {
        const subscription = AppState.addEventListener(
            'change',
            (nextAppState) => {
                appState.current = nextAppState;
                setAppStateVisible(appState.current);
            },
        );

        return () => {
            subscription.remove();
        };
    }, []);

    return (
        <>
            {appStateVisible === 'active' ? (
                <Video ref={ref} {...props} />
            ) : (
                <View />
            )}
        </>
    );
};

After testing, with this, our app was no longer using unnecessary battery in the background.