react-native-youtube-iframe
react-native-youtube-iframe copied to clipboard
Inner player crashes if selected in iOS Voiceover while showing thumbnail
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
accessibleprop towebViewProps(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-iframeversion : 1.4.1react-native-webview11.0.2Expo- 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>
);
};
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