Description
URL's that don't match anything in canPlay
will result in react-player never finding a player, if a 'react-player/file' import is used.
Example url: https://api.test.com/DbHjaY7aZ4H8A121
This one does not match in the canPlay
function for files, because it doesn't have an extension. That's fine when using the normal 'react-player' import, because it will automatically fallback to the FilePlayer, even if a url does not match.
When using 'react-player/file' the fallback will not be provided to ReactPlayer, so then the canPlay
function will again return false, but we will never get a player, because we don't provide a fallback here to the createReactPlayer
function: https://github.com/cookpete/react-player/blob/v2.16.0/scripts/pre-publish.js#L10-L14
const generateSinglePlayers = async () => {
for (const { key, name } of players) {
const file = `
var createReactPlayer = require('./lib/ReactPlayer').createReactPlayer
var Player = require('./lib/players/${name}').default
module.exports = createReactPlayer([{
key: '${key}',
canPlay: Player.canPlay,
lazyPlayer: Player
}])
`
await writeFile(join('.', `${key}.js`), file)
}
}
And specifically this if fallback check here will not be 'truthy' when using the file import:
getActivePlayer = memoize((url) => {
for (const player of [...customPlayers, ...players]) {
if (player.canPlay(url)) {
return player;
}
}
if (fallback) {
return fallback;
}
return null;
});
There are two solutions here that would fix this:
- Providing a explicit fallback for only the file.js export like this:
var createReactPlayer = require("./lib/ReactPlayer").createReactPlayer;
var Player = require("./lib/players/FilePlayer").default;
module.exports = createReactPlayer(
[
{
key: "file",
canPlay: Player.canPlay,
lazyPlayer: Player,
},
],
{
key: "file",
canPlay: Player.canPlay,
lazyPlayer: Player,
},
);
this would fix it, because the fallback is provided, so when canPlay
returns false, we will still get the file player fallback. It seems a bit redundant tho
- always using the file player as a fallback no matter if the 'fallback' parameter is provided
- I think this makes the most sense, because that is also what is mentioned in the code for index.js: https://github.com/cookpete/react-player/blob/master/src/index.js#L4-L5
- So maybe we could get rid of this
return null
here and always return the file player:
getActivePlayer = memoize((url) => {
for (const player of [...customPlayers, ...players]) {
if (player.canPlay(url)) {
return player;
}
}
if (fallback) {
return fallback;
}
return {
key: 'file',
...
};
});
Let me know if something is unclear, or I can help with fixing this 🙂