Description
Describe the bug
On physical iOS devices, when a video live stream has no segment length and no available bitrates, the JWPlayer freezes the entire app. The player shows a black screen (or a stuck view), and it's impossible to dismiss or recover from it, even if the player is wrapped in a React Native component.
This issue occurs only on physical iOS devices – not on Android, nor on iOS Simulator.
To Reproduce
Use the Example app with a HLS stream that has no actual content. The master .m3u8 file includes variant playlists (qualities), but those variant .m3u8 files return empty responses (no .ts segments).
Steps to reproduce the behavior:
Launch a React Native app using @jwplayer/jwplayer-react-native
Use a video source URL with a valid master .m3u8 but invalid or unauthorized .ts segment files
Run the app on a physical iOS device
JWPlayer renders and freezes, blocking all input
{
license: 'SUPER_SECRET_LICENCE',
preload: 'auto',
autostart: true,
title: 'Single Inline Linear Preroll',
playlist: [
{
title: 'Single Inline Linear Preroll',
file: 'LIVE STREAM URL',
},
],
backgroundAudioEnabled: true,
}
Expected behavior
JWPlayer should gracefully handle invalid or unreachable streams. For example, trigger an error event (onPlayerError) and allow the app to dismiss or replace the player component. The player should not block the UI or freeze the entire app when stream content is not playable.
Screenshots / Visual evidence
If applicable, add screenshots or recordings to help explain your problem. (Required if reproduction is not 100% reliable)
Desktop (please complete the following information):
If you are having a build issue, we would like to know about your machine.
- Result of
npx react-native info
Device(s) affected
Device: any physical iPhone
JWPlayer SDK Version: @jwplayer/jwplayer-react-native 1.0.3
Additional context
While the root cause in our case is likely an implementation issue (stream URL shouldn't be exposed if it's not valid), JWPlayer should still handle such edge cases more gracefully. The current behavior causes the entire app to hang with no way to recover unless the component is forcibly removed from the view hierarchy.
Here is an example of a master playlist (.m3u8) used for testing:
#EXTM3U
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=380000,BANDWIDTH=480000,RESOLUTION=640x360,FRAME-RATE=25.000,CODECS="avc1.4d401e,mp4a.40.2",CLOSED-CAPTIONS=NONE
tracks-v4a1/mono.m3u8
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=480000,BANDWIDTH=600000,RESOLUTION=852x480,FRAME-RATE=25.000,CODECS="avc1.4d401e,mp4a.40.2",CLOSED-CAPTIONS=NONE
tracks-v3a1/mono.m3u8
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=730000,BANDWIDTH=910000,RESOLUTION=1280x720,FRAME-RATE=25.000,CODECS="avc1.4d401f,mp4a.40.2",CLOSED-CAPTIONS=NONE
tracks-v2a1/mono.m3u8
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=1060000,BANDWIDTH=1320000,RESOLUTION=1920x1080,FRAME-RATE=25.000,CODECS="avc1.4d4028,mp4a.40.2",CLOSED-CAPTIONS=NONE
tracks-v1a1/mono.m3u8