Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hls video not playing on iOS #699

Closed
intelligence opened this issue Aug 21, 2019 · 14 comments
Closed

Hls video not playing on iOS #699

intelligence opened this issue Aug 21, 2019 · 14 comments

Comments

@intelligence
Copy link

Current Behavior

Struggling with getting HLS content from Vimeo to work. As it is now, it works perfectly on desktop in both Safari and Chrome. But on iOS the video won't load and there's no errors in the console. I've tried using the HLS stream available on your demo site, but to no avail either. Surprisingly I am able to use HLS on your demo on my phone.

onReady is not triggered on iOS.

Updated to latest version of react-player, same issue.
Tried using newest version of hls.js, same issue.

I've been working on this project for some time and have not seen this issue before. I did however switch from selfhosted mp4 to HLS from Vimeo on my last stint on the project, so it might have been there all the time. Only tested on desktop afaik.

Expected Behavior

Media should play

Reduced test case

https://heuristic-lewin-2f590c.netlify.com/

ReactPlayer implementation

<ReactPlayer 
  ref={this.ref}
  url='https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8'
  width='100%'
  height='100%'
  playing={this.state.playing}
  onReady={this.onReady}
  onEnded={this.onEnd}
  onPlay={this.onPlay}
  onPause={this.onPause}
  onError={(e) => console.log('onError', e)}
  playsinline={true}
  config={{
    file: { 
      attributes: { 
        preload: 'none',
        //forceHLS: true,
      },
      hlsOptions: {
        //autoStartLoad: false,
        startLevel: 3
      }
    } 
  }}
/>
@paulincai
Copy link

Hi there,
IOS will handle HLS outside the react-player. Please see the configuration I use in order to prevent IOS from using HLS with player.
This config is a direct prop of your ReactPlayer tag you will just need to determine the variable isSafari based on your context.
I personally get it this way
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)

const config = {
      file: {
        forceHLS: !isSafari,
        forceVideo: true,
        hlsVersion: '0.12.4',
        attributes: {
          poster: feed && feed.actionUrl && feed.actionUrl.image,
          disablePictureInPicture: true
        }
      }
    }```

@cookpete cookpete closed this as completed Sep 2, 2019
@intelligence
Copy link
Author

Great, thanks! I've been using video.js previously and if I remember correctly it checks this by itself.

@cookpete Maybe good idea to include or state this above example in the docs to avoid confusion? :)

Thanks for a great video player!

@cookpete
Copy link
Owner

cookpete commented Sep 3, 2019

@cookpete Maybe good idea to include or state this above example in the docs to avoid confusion?

There is already a crude check for iOS which prevents hls.js from kicking in:

https://github.com/CookPete/react-player/blob/4c4e0b5fb3321d1454017426d8adf2bb37ce1ac8/src/players/FilePlayer.js#L122-L124

I'm assuming this problem occurred because your URL changed and could no longer be parsed as a HLS stream. forceHls is already in the readme under the file config:

image

@mrcportillo
Copy link

Hi guys, I wonder if someone can give me an idea to solve my problem. I'm using HLS streaming in my app and faced this issue (hsl not working in IOS). The problem is that I'm using hlsOptions property with a specific xhrSetup config to set an authentication token for every chunk. Since IOS don't use hls.js I have no idea where I can put the authentication config.
Any Ideas?
thanks!

@pankaz
Copy link

pankaz commented Jul 22, 2021

Facing the same issue as @mrcportillo. Any guidance on how to tackle this would be really appreciated. 😇

@CanTheAlmighty
Copy link

Hi guys, I wonder if someone can give me an idea to solve my problem. I'm using HLS streaming in my app and faced this issue (hsl not working in IOS). The problem is that I'm using hlsOptions property with a specific xhrSetup config to set an authentication token for every chunk. Since IOS don't use hls.js I have no idea where I can put the authentication config.
Any Ideas?
thanks!

I solved this issue a while ago using ONLY query params, as header params are never to be trusted with HLS, for example:

mysite.com/somevideo?auth=<authtoken>

For the initial video, on my backend, I retrieve the playlist from S3, and then sign each segment, sort of like "if end lines with .m3u8 add a ?auth="

mysite.com/somevideo/720p/playlist.m3u8?auth=<authtoken>

And finally I also sign all chunks using AWS Cloudfront tokens (this depends where you are hosting your video).

But in essence, everything relies on using only authentication via query params.

@pedramp20
Copy link

@CanTheAlmighty Can you please elaborate more? I am trying to exactly play hls using cloudfornt signed url. Everything works perfectly on Windows and Android but fails on iOS.

This code works everywhere beside iOS

<ReactPlayer
    url={source} //this source url WITHOUT APPENDED TOKEN: https://xxxxxxxx.cloudfront.net/{path}/{path.m3u8}
    controls={true}
    config={{
      file: {
        hlsOptions: {
          xhrSetup: function xhrSetup(xhr, url) {
            xhr.setRequestHeader(
              "Access-Control-Allow-Headers",
              "Content-Type, Accept, X-Requested-With"
            );
            xhr.setRequestHeader(
              "Access-Control-Allow-Origin",
              "*"
            );
            xhr.setRequestHeader(
              "Access-Control-Allow-Credentials",
              "true"
            );
            xhr.open('GET', url + token); // token is formatted like: ?Policy=foo&Key-Pair-Id=bar&Signature=foobar
          }
        }
      }
    }}
  />

Do you just append the token to the url and do not setup xhr?

<ReactPlayer
    url={source+token} //this source url with APPENDED TOKEN: https://xxxxxxxx.cloudfront.net/{path}/{path.m3u8}?Policy=foo&Key-Pair-Id=bar&Signature=foobar
    controls={true}
  />

I tried and didnt work for me?

@mrcportillo
Copy link

@pedramp20 the thing with ios is that doesn't use hls.js but his own HLS implementation ignoring whatever configuration you are passing through react-player to hls.js. I think what @CanTheAlmighty is trying to say is to implement something like this https://azure.microsoft.com/es-es/blog/how-to-make-token-authorized-aes-encrypted-hls-stream-working-in-safari/

@karaulovskin
Copy link

karaulovskin commented Oct 20, 2022

Hi there,
Please, HELLP ME not working autoplay youtube on iOS, what am I doing wrong?

<ReactPlayer
    className='react-player'
    playsInline
    playing={playing}
    muted={muted}
    url={url}
    width='100%'
    height='100%'
    config={{
        file: {},
        youtube: {
            playerVars: {
                disablekb: 1,
                modestbranding: 1,
                showinfo: 0,
                iv_load_policy: 3,
                origin: 0,
                disablePictureInPicture: true,
                rel: 1,
            },
        },
        vimeo: {
            playerOptions: {}
        }
    }}
/>

@bytecode-praveen
Copy link

Hi there, Please, HELLP ME not working autoplay youtube on iOS, what am I doing wrong?

<ReactPlayer
    className='react-player'
    playsInline
    playing={playing}
    muted={muted}
    url={url}
    width='100%'
    height='100%'
    config={{
        file: {},
        youtube: {
            playerVars: {
                disablekb: 1,
                modestbranding: 1,
                showinfo: 0,
                iv_load_policy: 3,
                origin: 0,
                disablePictureInPicture: true,
                rel: 1,
            },
        },
        vimeo: {
            playerOptions: {}
        }
    }}
/>

Autoplay is disabled in most of the new age browsers, It will now work in iOS

@Sundaram1911
Copy link

Hi @cookpete , we are trying to play singed url using react player but in the IOS things are not same, we faced same issue above,
so my question is that can we disbale that IS_IOS crude check in your react player and can we play video (.m3u8) in the react player instead of playing in the native player. please help !! your comment will be appreciated Thanks.

@cookpete
Copy link
Owner

@Sundaram1911 Check out #1560

@jwshyns
Copy link

jwshyns commented Aug 24, 2023

@CanTheAlmighty Can you please elaborate more? I am trying to exactly play hls using cloudfornt signed url. Everything works perfectly on Windows and Android but fails on iOS.

This code works everywhere beside iOS

<ReactPlayer
    url={source} //this source url WITHOUT APPENDED TOKEN: https://xxxxxxxx.cloudfront.net/{path}/{path.m3u8}
    controls={true}
    config={{
      file: {
        hlsOptions: {
          xhrSetup: function xhrSetup(xhr, url) {
            xhr.setRequestHeader(
              "Access-Control-Allow-Headers",
              "Content-Type, Accept, X-Requested-With"
            );
            xhr.setRequestHeader(
              "Access-Control-Allow-Origin",
              "*"
            );
            xhr.setRequestHeader(
              "Access-Control-Allow-Credentials",
              "true"
            );
            xhr.open('GET', url + token); // token is formatted like: ?Policy=foo&Key-Pair-Id=bar&Signature=foobar
          }
        }
      }
    }}
  />

Do you just append the token to the url and do not setup xhr?

<ReactPlayer
    url={source+token} //this source url with APPENDED TOKEN: https://xxxxxxxx.cloudfront.net/{path}/{path.m3u8}?Policy=foo&Key-Pair-Id=bar&Signature=foobar
    controls={true}
  />

I tried and didnt work for me?

This is likely a bit late for @pedramp20, but if like me, you came across this thread because you're having trouble with using CloudFront signed URLs for HLS on iOS this gist may help.

@joshephan
Copy link

Hi there, IOS will handle HLS outside the react-player. Please see the configuration I use in order to prevent IOS from using HLS with player. This config is a direct prop of your ReactPlayer tag you will just need to determine the variable isSafari based on your context. I personally get it this way const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)

const config = {
      file: {
        forceHLS: !isSafari,
        forceVideo: true,
        hlsVersion: '0.12.4',
        attributes: {
          poster: feed && feed.actionUrl && feed.actionUrl.image,
          disablePictureInPicture: true
        }
      }
    }```

this is not working. I don't understand why this issue is closed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests