cookpete / react-player

A React component for playing a variety of URLs, including file paths, YouTube, Facebook, Twitch, SoundCloud, Streamable, Vimeo, Wistia and DailyMotion
https://cookpete.github.io/react-player
MIT License
9.34k stars 1.15k forks source link

Add request headers to the url? #434

Closed snly2386 closed 6 years ago

snly2386 commented 6 years ago

Can the video support adding request headers (e.g. some sort of authorization for protected videos) to the url property?

cookpete commented 6 years ago

Looks like this is not possible. See https://security.stackexchange.com/a/175698.

aderbas commented 5 years ago

I "solved" using fetch

try{
  const result = await fetch(<url>, {
    headers: {
      Authorization: "<token>"
    },
  });
  const blob = await result.blob();
  if(blob){
    this.setState({ fileName: URL.createObjectURL(blob), playing: true});
  }
}catch(err){ }
itsalb3rt commented 4 years ago

I "solved" using fetch

try{
  const result = await fetch(<url>, {
    headers: {
      Authorization: "<token>"
    },
  });
  const blob = await result.blob();
  if(blob){
    this.setState({ fileName: URL.createObjectURL(blob), playing: true});
  }
}catch(err){ }

This work! no only for react-player, i use this in react-h5-audio-player.

Thanks

Rijon1810 commented 3 years ago

try{ const result = await fetch(, { headers: { Authorization: "" }, }); const blob = await result.blob(); if(blob){ this.setState({ fileName: URL.createObjectURL(blob), playing: true}); } }catch(err){ }

in server it take too much time load. what is the solution?

Frikster commented 2 years ago

If you're using django you could use sessions, django signals and nginx and solve this on the backend rather than frontend.

Place in views.py that will check for authentication:

class GetUserMixin(object):
    def get_user(self, request):
        user_pk = request.session.get(AUTHENTICATION_USER_SESSION_KEY)
        return get_user_model().objects.get(pk=user_pk)

Signal, which can be placed anywhere, I place it in urls.py:

def user_logged_in_receiver(sender, **kwargs):
    kwargs['request'].session[AUTHENTICATION_USER_SESSION_KEY] = kwargs['user'].pk

user_logged_in.connect(user_logged_in_receiver)

make nginx receive the url you put in the player and let it proxy to your endpoint in views.py that then uses get_user to retrieve the user from your session and thereby huzzah, no more "AnonymousUser" annoyance.

Then the normal thing to do is check user.is_authenticated (or whatever other attribute you care about checking for) and add the 'XAccel-Redirect' header so that nginx will redirect to the protected path that then finally gives the client the video media file segments. See Protect Django media files per user basis with nginx

wparam commented 2 years ago

I "solved" using fetch

try{
  const result = await fetch(<url>, {
    headers: {
      Authorization: "<token>"
    },
  });
  const blob = await result.blob();
  if(blob){
    this.setState({ fileName: URL.createObjectURL(blob), playing: true});
  }
}catch(err){ }

It does't work for progressive downloading.

ARFayyaz commented 1 year ago

I "solved" using fetch

try{
  const result = await fetch(<url>, {
    headers: {
      Authorization: "<token>"
    },
  });
  const blob = await result.blob();
  if(blob){
    this.setState({ fileName: URL.createObjectURL(blob), playing: true});
  }
}catch(err){ }

It does't work for progressive downloading.

Yup, doesnt work for progressive downloading. Any suggestions?

Nusab19 commented 10 months ago

Yup, doesnt work for progressive downloading. Any suggestions?

Solution From :

I was facing problem of the audio file being not seekable. I had to pass some headers for the server to accept ranges. As React Player doesn't support sending headers, I had to modify the XHR request sent by HLS when loading the stream.

Here's what I did:

config={{
        file: {
          hlsOptions: {
            forceHLS: true,
            debug: false,
            xhrSetup: function (xhr) {
              xhr.setRequestHeader("Accept-Ranges", "bytes");
              xhr.setRequestHeader("Content-Length", "7437847");
              xhr.setRequestHeader("Content-Range", "bytes 0-7437846/7437847");
            },
          },
        },
      }}

You can also pass Authorization header if you want.

zeyadetman commented 1 month ago

Solved it by creating two instances of the ReactPlayer, one to get the authorized link and the other one to stream the audio.

const [finalAudioUrl, setFinalAudioUrl] = useState("");

{
  !finalAudioUrl && (
    <ReactPlayer
      url={src}
      config={{
        file: {
          forceHLS: true,
          hlsOptions: {
            xhrSetup: async function (xhr, url) {
              xhr.open("GET", url);
              xhr.setRequestHeader("Authorization", `Bearer ${token}`);
              xhr.addEventListener("progress", function () {
                if (this.responseURL && !finalAudioUrl) {
                  setFinalAudioUrl(this.responseURL);
                  this.abort();
                }
              });
            },
          },
        },
      }}
      style={{ display: "none" }}
    />
  );
}

<ReactPlayer ref={ref} url={finalAudioUrl} />;