indigo-player
indigo-player copied to clipboard
Provide a React component
Description
Provide a npm module that exposes a Player component for React.
Idea: import Player from 'indigo-player/react'
(currently not available, this is merely an idea).
Code sample
import React, { useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import IndigoPlayer from 'indigo-player';
const CHUNKS_PATH = `https://cdn.jsdelivr.net/npm/indigo-player@${
IndigoPlayer.VERSION
}/lib/`;
export default function Player({ config, chunksPath }) {
const container = useRef(null);
useEffect(() => {
IndigoPlayer.setChunksPath(chunksPath);
}, [chunksPath]);
useEffect(() => {
const player = IndigoPlayer.init(container.current, config);
return () => player.destroy();
}, [config]);
return <div ref={container} />;
}
Player.propTypes = {
config: PropTypes.shape({}).isRequired,
chunksPath: PropTypes.string,
};
Player.defaultProps = {
config: undefined,
chunksPath: CHUNKS_PATH,
};
- [x] Proper cleanup when
player.destroy()
is called. - [ ] Find a proper way to expose the
player
API which is returned byIndigoPlayer.init
. - I'm not convinced about the
IndigoPlayer.setChunksPath
implementation for libraries. Chunks never really worked out-of-the-box when including an npm lib.
Find a proper way to expose the player API which is returned by IndigoPlayer.init
You could have a prop called onPlayerDraw
or some such that fires after a player is ready and sends back the player along with anything else that is needed, like if (typeof onPlayerDraw === 'function') onPlayerDraw({player});
It would allow you to get the player API to the user if they want it (some may not need it) and allow them to run their own functionality to deal with the player draw (like autoplay checks and the like).
I've had to use the same thing on a React project to notify a parent component that a child component is now hidden.
Thought about it too but using a callback on a sync instruction (IndigoPlayer.init is sync) feels a bit counter-intuitive. One thing I'd like to try is using the useRef
hook to create a reference to the player in combination with the useImperativeHandle
hook to provide strictly the player API in the ref.
Eg:
const player = useRef();
// Access controller
// eg: player.current.play(), player.current.pause(), ...
// Access state
// indigo-player can provide these kind of hooks, eg: `usePlayerState(ref)`
const [playerState, setPlayerState] = useState(null);
useEffect(() => {
if (player.current) {
player.current.addListener(Events.STATE_CHANGE, state => setPlayerState(state));
return () => player.current.removeListener(Events.STATE_CHANGE);
}
}, [player.current]);
// eg: access state like playerState.playing, playerState.paused, ...
<Player ref={player} config={config} />
I'll have a play with this in the upcoming days.
Any updates on this idea @matvp91 ?
@FreddyJD not at the moment, I've recently merged in https://github.com/matvp91/indigo-player/pull/53 which is a first step in a better module structure. Once I've cleared out the other roadblocks (and maintain backwards compatibility), you'll be able to install indigo-player
as a module. This would make it a whole lot easier to wrap it around a React component.
Edit: The following code should get you started, simply run yarn add indigo-player
(or npm) and you're good to go:
import React from "react";
import ReactDOM from "react-dom";
import indigoPlayer from "indigo-player";
import "indigo-player/lib/indigo-theme.css";
function App() {
const ref = React.useRef();
React.useEffect(() => {
indigoPlayer.init(ref.current, {
sources: [
{
type: "mp4",
src:
"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
},
],
});
}, []);
return (
<div>
<div ref={ref} />
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
Although there is no official integration for indigo-player with React yet, the sample above should get anyone going who wants to implement this in React.
@matvp91 Thanks for the sample.
Unfortunately I'm new to both React and Typescript and thought I'd found a holy-grail here, but alas I can't get it to work as is.
Property 'init' does not exist on type 'typeof import("/home/jon/source/myapp/node_modules/indigo-player/src/index")'.
I did manage to fix an issue with the useRef usage by making the following change:
const ref = useRef<HTMLDivElement>(null);