TheWidlarzGroup / react-native-video

A <Video /> component for react-native
http://thewidlarzgroup.github.io/react-native-video/
MIT License
7.15k stars 2.88k forks source link

No video playback on Android 10 (API 29) and Android 11 (API 30) #2473

Closed scottkz closed 2 years ago

scottkz commented 3 years ago

Bug

Using a basic implementation of the player using react-native, I have tried with both native controls and as shown here custom controls, the video will not produce video playback, but only audio playback on an Android emulator running API 29 or 30. I have tried all different versions of both react-native and react-native-video to no avail. I have tried with and without linking and using the README's guide to >=5.0 setup on Android. Nothing seems to be working.

Now, it does work great on iOS and any Android emulator running API 28 and 27 as that's as far back as I've tested so far. I've tried searching for this issue, but can't find it anywhere so that leads me to believe it's something I'm doing otherwise I'd expect it to be a huge deal for this library. Please let me know if I'm just missing something simple here. Thanks!

Platform

Which player are you experiencing the problem on:

Environment info

React native info output:

System:
    OS: macOS 11.4
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 494.74 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.17.5 - ~/.nvm/versions/node/v14.17.5/bin/node
    Yarn: 1.22.11 - ~/.nvm/versions/node/v14.17.5/bin/yarn
    npm: 6.14.14 - ~/.nvm/versions/node/v14.17.5/bin/npm
    Watchman: 2021.06.07.00 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.10.2 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4
    Android SDK: Not Found
  IDEs:
    Android Studio: 4.1 AI-201.8743.12.41.7042882
    Xcode: 12.5.1/12E507 - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.11 - /usr/local/opt/jenv/shims/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2 
    react-native: 0.65.1 => 0.65.1 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Library version: 5.1.1 / 5.0.1 / 4.2.0 / 3.2.0

Steps To Reproduce

  1. react-native init VideoDemo
  2. yarn add react-native-video react-native-media-controls react-native-slider
  3. Write VideoPlayer.js a shown below and import it into App.js as a child component
  4. cd ios && pod install
  5. Open android/build.gradle in Android Studio
  6. Build project and run on any emulator using API 29 or 30
  7. If that doesn't work configure android files using suggested configurations (exo-player, implementation with appcompat, etc.)
  8. cd android && ./gradlew clean
  9. Try to rebuild project again in Android Studio
  10. Attempt to run on emulator again with API 29 or 30

Expected behaviour

  1. The video to actually show the content and not just audio.
  2. When I seek to a certain time, for the video to show from that point moving forward.

Reproducible sample code

VideoPlayer.js

import React, {useState, useRef} from 'react';
import {Dimensions, View, Platform, StatusBar} from 'react-native';
import MediaControls, {PLAYER_STATES} from 'react-native-media-controls';
import Video from 'react-native-video';

const VideoPlayer = () => {
  //  The video we will play on the player.
  const uri =
    'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4';

  const videoPlayer = useRef(null);
  const [duration, setDuration] = useState(0);
  const [paused, setPaused] = useState(true);

  const [currentTime, setCurrentTime] = useState(0);
  const [playerState, setPlayerState] = useState(PLAYER_STATES.PAUSED);
  const [isLoading, setIsLoading] = useState(true);
  const [isFullscreen, setIsFullscreen] = useState(false);

  const onSeek = seek => {
    videoPlayer.current.seek(seek);
  };

  const onSeeking = currentVideoTime => setCurrentTime(currentVideoTime);

  const onPaused = newState => {
    setPaused(!paused);
    setPlayerState(newState);
  };

  const onReplay = () => {
    videoPlayer.current.seek(0);
    setCurrentTime(0);
    if (Platform.OS === 'android') {
      setPlayerState(PLAYER_STATES.PAUSED);
      setPaused(true);
    } else {
      setPlayerState(PLAYER_STATES.PLAYING);
      setPaused(false);
    }
  };

  const onProgress = data => {
    if (!isLoading) {
      setCurrentTime(data.currentTime);
    }
  };

  const onLoad = data => {
    setDuration(Math.round(data.duration));
    setIsLoading(false);
  };

  const onLoadStart = () => setIsLoading(true);

  const onEnd = () => {
    setPlayerState(PLAYER_STATES.ENDED);
    setCurrentTime(duration);
  };

  const videoDims = {
    height: (Dimensions.get('window').width * 9) / 16,
    width: Dimensions.get('window').width,
  };

  return (
    <View>
      <Video
        ref={ref => (videoPlayer.current = ref)}
        resizeMode={'cover'}
        source={{uri}}
        style={videoDims}
        paused={paused}
        onLoadStart={onLoadStart}
        onLoad={onLoad}
        onProgress={onProgress}
        onEnd={onEnd}
      />
      <MediaControls
        isFullScreen={false}
        duration={duration}
        isLoading={isLoading}
        progress={currentTime}
        onPaused={onPaused}
        onReplay={onReplay}
        onSeek={onSeek}
        onSeeking={onSeeking}
        mainColor={'orange'}
        playerState={playerState}
        sliderStyle={{containerStyle: {}, thumbStyle: {}, trackStyle: {}}}
      />
    </View>
  );
};

export default VideoPlayer;

logact (debug mode) outputs:

W/unknown:ViewManagerPropertyUpdater: Could not find generated setter for class com.brentvatne.react.ReactVideoViewManager
W/ReactNativeJS: 'Warning: componentWillMount has been renamed, and is not recommended for use.
W/ReactNativeJS: 'Warning: componentWillReceiveProps has been renamed, and is not recommended for use.
W/MediaPlayer: setScreenOnWhilePlaying(true) is ineffective without a SurfaceHolder

not sure if these may help

Link to the repository: https://github.com/scottkatzelnick/rn-video-demo

Video sample

Google Drive link to video running on an Android Emulator (Pixel 3a API 30, rn v65.1, library version 5.1.1): https://drive.google.com/file/d/1GneDCXCll1P_6C6Mt9EUIV7J5P-9SwBd/view?usp=sharing

UberMC commented 2 years ago

Does using a video that is https solve it?

scottkz commented 2 years ago

Does using a video that is https solve it?

No it does not. I actually tried it first with my Vimeo private links which are all https, and then that lead me to testing. I tried the big bunny url but simply forgot the "s" on http. It plays the audio, and progresses, just to a black screen either way.

Edit:

It does work on Android emulators running API 28 and lower. So I'm wondering if it's just an emulator issue somehow.

stanciualex commented 2 years ago

Using an emulator with API 28 and Android 9.0 (instead of API 30 and Android 11.0) solved the problem for me as well.

scottkz commented 2 years ago

Using an emulator with API 28 and Android 9.0 (instead of API 30 and Android 11.0) solved the problem for me as well.

Glad to see you had the same experience, well not glad, but at least we can say it's either an issue with react-native-video on newer API's or emulator resource issues with newer API's. My only concern is I don't have a physical Android device and didn't want to leave it to chance that a physical device would just work. Can anyone confirm that react-native-video is also having issue on physical devices running API 29 or higher?

anutting commented 2 years ago

I can confirm this is an issue on physical devices. My Pixel 4 XL on Android 11 does not play videos, but every emulator I use works just fine.

EDIT: Oddly enough, when my Pixel 4 XL is connected to the metro server in dev mode videos load fine. Any help here is appreciated.

scottkz commented 2 years ago

I can confirm this is an issue on physical devices. My Pixel 4 XL on Android 11 does not play videos, but every emulator I use works just fine.

EDIT: Oddly enough, when my Pixel 4 XL is connected to the metro server in dev mode videos load fine. Any help here is appreciated.

Thank you for the info. I'm glad I didn't leave it to chance and just used Vimeo's player API instead. It's super frustrating, and a little mind boggling that this doesn't work correctly on the most recent versions of the Android SDK (29,30 and presumably 31).

I much rather use this library on Android devices just like I do on the iOS side, but like with most things, the iOS is running much smoother. I guess all we can do is hope the devs see this.

Also, are the emulators you're using running Android 10 or higher. I'm curious how you are getting that to display video and not just audio as that was how I found this issue. If possible could you share your grade files showing how you setup this library and a super basic example of how you have it working? Just to try to see if I can spot a difference somewhere. Thanks.

davitN commented 2 years ago

Same thing here ((. any solution yet?

edritech93 commented 2 years ago

same issue for me

jrpeters89 commented 2 years ago

Anyone get this figured out by chance?

lranches-gemini commented 2 years ago

This solution seems to be the only one that works https://github.com/yqritc/Android-ScalableVideoView/issues/52#issuecomment-1014817588

DonGlover commented 1 year ago

Has it been determined that we are SoL on newer versions of Android and need to find a different solution?

UberMC commented 1 year ago

I think your problem is that while your implementation is basic, it certainly is not official code, and the problem lies most likely in your logic or an bug in one of the optional onLoadStart, ect... prop . I've tested with a more basic implementation that works fine on newer APIs using physical devices. Could also be the video you're loading in.

DonGlover commented 1 year ago

@UberMC I thought of that so I tried the sample file https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_10mb.mp4 (since http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4 appears to be a dead link) and got the same results.