react-native-youtube-iframe icon indicating copy to clipboard operation
react-native-youtube-iframe copied to clipboard

Inner player crashes if selected in iOS Voiceover while showing thumbnail

Open AlanSl opened this issue 4 years ago • 1 comments

Describe the bug On iOS with VoiceOver active, if an unplayed YouTube WebView is selected, it fails:

  • The thumbnail is replaced with an empty rectangle
  • The screen reader says:

    Indefinite time. Video playback. Elapsed time: zero seconds. Double tap to play or pause. Actions available.

  • A "play" accessibility label is read on the next item but double-tap to play on this does not work

It looks like YouTube's accessibility text generator expects video metadata to have been loaded before the item is selected, which won't happen unless the the video is set to autoplay. Strangely, after this happens there is a working play button a couple of swipes down but the default play button doesn't work so the user might just go back thinking the video failed and not discover this.

Android TalkBack works as expected.

To Reproduce

  • Add a video. I've tried many combinations of props and the only requirement to replicate is to not pass accessible prop to webViewProps (doing so disables accessibility features within the Youtube Player like pause or skip ahead). Even something simple like this has the problem:
<View>
  <YoutubePlayer
    height={height}
    videoId={videoId}
  />
</View>
  • Open the app in iOS (real device) with VoiceOver enabled in Accessibility Settings
  • Swipe right until the video frame is reached

Compare the behaviour with an autoplaying video, which does not have the problem (because the metadata is loaded before you can select the element). For example:

<View>
 <YoutubePlayer
   play={true}
   height={height}
   videoId={videoId}
 />
</View>

Expected behavior

Same behaviour as if the video is allowed to start buffering and download metadata before selecting it: no crash on select, just reads the description.

Smartphone (please complete the following information):

  • Device: iPhone SE
  • OS + version: iOS 14.4
  • react-native-youtube-iframe version : 1.4.1
  • react-native-webview 11.0.2
  • Expo - not used

Additional context

As a workaround you can make sure that the video auto-buffers if VoiceOver is on, for example:

export const Video = ({
  height,
  videoId,
  autoPlay = false,
  autoBuffer = false,
  screenReaderEnabled = false
}) => {
  // Workaround https://github.com/LonelyCpp/react-native-youtube-iframe/issues/119
  const voiceoverOn = Platform.OS === 'ios' && screenReaderEnabled;

  const [playing, setPlaying] = useState(voiceoverOn || autoPlay || autoBuffer);
  const [buffering, setBuffering] = useState(false);

  const handleChangeState = (event) => {
    if (event === 'buffering') {
      setBuffering(true);
    }
    if (event === 'playing') {
      setPlaying(buffering ? autoPlay : true);
      setBuffering(false);
    }
    if (event === 'paused') {
      setPlaying(false);
    }
  };

  return (
    <View>
      <YoutubePlayer
        play={playing}
        onChangeState={handleChangeState}
        height={height}
        videoId={videoId}
      />
    </View>
  );
};

AlanSl avatar Mar 23 '21 16:03 AlanSl

Hello, thanks for the very detailed report!!

I'm not quite sure how I can test Voiceover from my simulator, I'll try the accessibility inspector if I can see what the issue is.

Can you check how voiceover works on a webpage with an youtube iframe? I would expect it to behave in a similarly. For example you can try - https://codepen.io/SurajMDurgad/pen/KKVZBoQ

LonelyCpp avatar Mar 24 '21 18:03 LonelyCpp