Skip to content

Commit

Permalink
v1.1.2 (#7)
Browse files Browse the repository at this point in the history
* v1.1.0

* [v1.1.2] move effect to hooks

* v1.1.2

* [v1.1.2] all listeners & jest test
  • Loading branch information
mkhuda authored Aug 27, 2021
1 parent c4459e3 commit 816bdda
Show file tree
Hide file tree
Showing 12 changed files with 646 additions and 166 deletions.
31 changes: 25 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
# @mkhuda/react-shaka-player [![Build Status](https://app.travis-ci.com/mkhuda/react-shaka-player.svg?branch=main)](https://app.travis-ci.com/mkhuda/react-shaka-player) [![npm version](https://badge.fury.io/js/%40mkhuda%2Freact-shaka-player.svg)](https://badge.fury.io/js/%40mkhuda%2Freact-shaka-player)
# @mkhuda/react-shaka-player [![Build Status](https://app.travis-ci.com/mkhuda/react-shaka-player.svg?branch=main)](https://app.travis-ci.com/mkhuda/react-shaka-player) [![npm version](https://badge.fury.io/js/%40mkhuda%2Freact-shaka-player.svg)](https://badge.fury.io/js/%40mkhuda%2Freact-shaka-player) ![npm](https://img.shields.io/npm/v/shaka-player?label=shaka-player)

React video player built with [Shaka Player](https://github.com/google/shaka-player). [ROADMAP](https://github.com/mkhuda/react-shaka-player/wiki/Initial-Roadmap)
React video player built on top of [Shaka Player](https://github.com/google/shaka-player).
> [ROADMAP](https://github.com/mkhuda/react-shaka-player/wiki/Initial-Roadmap)
> [EXAMPLE & USAGES](https://github.com/mkhuda/react-shaka-player/wiki/Usages-&-Examples)
## Installation

Use the package manager [yarn](https://classic.yarnpkg.com/en/) or [npm](https://www.npmjs.com/) to install `react-shaka-player`.

```bash
yarn add @mkhuda/react-shaka-player
yarn add @mkhuda/react-shaka-player shaka-player

or

npm install @mkhuda/react-shaka-player
npm install @mkhuda/react-shaka-player shaka-player
```

## Usage

```javascript
// don't forget to import controls.css from shaka-player lib
import "shaka-player/dist/controls.css";
import Player from "@mkhuda/react-shaka-player";
import ReactShakaPlayer from "@mkhuda/react-shaka-player";

function App() {
return <Player autoPlay={true} src={"https://yourvideohere.mpd"} />;
return <ReactShakaPlayer autoPlay={true} src={"https://yourvideohere.mpd"} />;
}
```

Expand Down Expand Up @@ -56,6 +60,21 @@ function App() {
}
```

## Props

This is main props for the components:

| |Description |Type |
|----------------|-------------------------------|-----------------------------|
|src|MPD or HLS to play |string |
|config |Changes configuration settings on Shaka Player. Reference: [shaka.extern.PlayerConfiguration](https://shaka-player-demo.appspot.com/docs/api/shaka.extern.html#.PlayerConfiguration) | object |
|uiConfig |Changes configuration settings for UI elements. Reference: [shaka.extern.UIConfiguration](https://shaka-player-demo.appspot.com/docs/api/shaka.extern.html#.UIConfiguration) | object |
|onLoad |Catch `Shaka.Player`, `Shaka.ui.Overlay` and `HTMLVideoElement` for manual usages or improvement of configuration. see: [PlayerRefs](https://github.com/mkhuda/react-shaka-player/blob/c4459e31027a08165007d03c9a08ff8a3e5de3dc/src/types/index.ts#L3) |object: PlayerRefs => func|
|onPlay|Catch when media is playing |func|
|onPlause|Catch when media is paused |func|
|onBuffering |Catch `onBuffering` status when playing |bool => func|
|onPlayerError |Catch `error` when playing. Reference: [Shaka.Player.ErrorEvent](https://shaka-player-demo.appspot.com/docs/api/shaka.Player.html#.event:ErrorEvent) |{Shaka.extern.Error} => func|

## Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Expand Down
11 changes: 2 additions & 9 deletions demo/index.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
import React from "react";
import ReactDOM from "react-dom";
import Player from "@mkhuda/react-shaka-player";
import ReactShakaPlayer from "@mkhuda/react-shaka-player";
import "shaka-player/dist/controls.css";

function App() {
let playerRef = React.useRef(null);

// Copyright: https://dashif.org/
const video =
"https://livesim.dashif.org/livesim/chunkdur_1/ato_7/testpic4_8s/Manifest300.mpd";

return (
<div className="video-container">
<Player
className="player-container"
playerClassName="player-class"
autoPlay
src={video}
/>
<ReactShakaPlayer autoPlay={true} playsInline={true} src={video} />
</div>
);
}
Expand Down
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"name": "@mkhuda/react-shaka-player",
"version": "1.1.1",
"version": "1.1.2",
"description": "React video player built with Shaka-Player",
"main": "dist/cjs.js",
"author": "Muhammad K. Huda",
"license": "MIT",
"scripts": {
"build": "rimraf dist && rollup -c --perf",
"start": "rimraf dist && DEV=1 rollup -c --watch",
"test": "jest"
"test": "jest",
"watch": "rollup -c --watch"
},
"dependencies": {
"rollup": "^2.56.2",
Expand All @@ -24,11 +25,15 @@
"@rollup/plugin-node-resolve": "^13.0.4",
"@rollup/plugin-replace": "^3.0.0",
"@rollup/plugin-typescript": "^8.2.5",
"@types/enzyme": "^3.10.9",
"@types/jest": "^27.0.1",
"@types/react": "^17.0.18",
"@types/react-dom": "^17.0.9",
"@types/react-test-renderer": "^17.0.1",
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.3",
"babel-jest": "^27.0.6",
"enzyme": "^3.11.0",
"enzyme-to-json": "^3.6.2",
"jest": "^27.0.6",
"postcss": "^8.3.6",
"prettier": "^2.3.2",
Expand Down
5 changes: 5 additions & 0 deletions src/hooks/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import usePlayer from "./usePlayer";
import usePlayerListener from "./usePlayerListener";
import useUIListener from "./useUIListener";

export { usePlayer, usePlayerListener, useUIListener };
62 changes: 62 additions & 0 deletions src/hooks/usePlayer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import * as Shaka from "shaka-player/dist/shaka-player.ui";
import * as React from "react";

import { PlayerProps } from "../types/";

const usePlayer = (
videoRef: React.MutableRefObject<HTMLVideoElement>,
uiContainerRef: React.MutableRefObject<HTMLDivElement>,
props: PlayerProps
) => {
const [player, setPlayer] = React.useState<Shaka.Player | null>(null);
const [ui, setUi] = React.useState<Shaka.ui.Overlay | null>(null);

React.useEffect(() => {
Shaka.polyfill.installAll();

const player = new Shaka.Player(videoRef.current);
setPlayer(player);

if (player) {
const ui = new Shaka.ui.Overlay(
player,
uiContainerRef.current,
videoRef.current
);
setUi(ui);
}

return () => {
player.destroy();
if (ui) {
ui.destroy();
}
};
}, []);

React.useEffect(() => {
if (player && props.onLoad) {
props.onLoad({
player: player,
ui: ui,
videoElement: videoRef.current,
});
}
}, [player]);

React.useEffect(() => {
if (player && props.config) {
player.configure(props.config);
}
}, [player, props.config]);

React.useEffect(() => {
if (player && props.src && Shaka.Player.isBrowserSupported()) {
player.load(props.src);
}
}, [player, props.src]);

return { player, ui };
};

export default usePlayer;
18 changes: 18 additions & 0 deletions src/hooks/usePlayerListener.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as Shaka from "shaka-player/dist/shaka-player.ui";
import * as React from "react";

import { PlayerProps } from "../types";

const usePlayerListener = (player: Shaka.Player, props: PlayerProps) => {
React.useEffect(() => {
const _onBufferingEvent = (bufferStatus: any) => {
const boolOfBuffering: boolean = bufferStatus.buffering;
props.onBuffering(boolOfBuffering);
};
if (player && props.onBuffering) {
player.addEventListener("buffering", _onBufferingEvent);
}
}, [player]);
};

export default usePlayerListener;
32 changes: 32 additions & 0 deletions src/hooks/useUIListener.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as Shaka from "shaka-player/dist/shaka-player.ui";
import * as React from "react";

import { PlayerProps } from "../types";

const useUIListener = (
ui: Shaka.ui.Overlay,
player: Shaka.Player,
props: PlayerProps
) => {
React.useEffect(() => {
if (ui && props.uiConfig) {
ui.configure(props.uiConfig);
}
}, [ui, props]);

React.useEffect(() => {
if (player) {
const mediaElement = player.getMediaElement();
const _onPlay = () => {
props.onPlay && props.onPlay();
};
const _onPause = () => {
props.onPause && props.onPause();
};
mediaElement.addEventListener("play", _onPlay);
mediaElement.addEventListener("pause", _onPause);
}
}, [player]);
};

export default useUIListener;
78 changes: 25 additions & 53 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,68 +1,40 @@
import * as Shaka from "shaka-player/dist/shaka-player.ui";
import * as React from "react";
import * as Hooks from "./hooks";

import { PlayerProps } from "./types/";

const Player = (props: PlayerProps) => {
const uiContainerRef = React.useRef<HTMLDivElement>(null);
const videoRef = React.useRef<HTMLVideoElement>(null);
const uiContainerRef = React.useRef<HTMLDivElement>(null);

const [player, setPlayer] = React.useState<Shaka.Player | null>(null);
const [ui, setUi] = React.useState<Shaka.ui.Overlay | null>(null);

React.useEffect(() => {
Shaka.polyfill.installAll();

const player = new Shaka.Player(videoRef.current);
setPlayer(player);

if (player) {
const ui = new Shaka.ui.Overlay(
player,
uiContainerRef.current,
videoRef.current
);
setUi(ui);
if (props.onLoad) {
props.onLoad({
player: player,
ui: ui,
videoElement: videoRef.current,
});
}
}

return () => {
player.destroy();
if (ui) {
ui.destroy();
}
};
}, []);

React.useEffect(() => {
if (player && props.config) {
player.configure(props.config);
}
}, [player, props.config]);

React.useEffect(() => {
if (player && props.src && Shaka.Player.isBrowserSupported()) {
player.load(props.src);
}
}, [player, props.src]);

const { className, playerClassName, onLoad, ...newProps } = props;
const { player, ui } = Hooks.usePlayer(videoRef, uiContainerRef, props);
Hooks.usePlayerListener(player, props);
Hooks.useUIListener(ui, player, props);

const {
className,
playerClassName,
config,
uiConfig,
onLoad,
onPlay,
onPause,
onBuffering,
onPlayerError,
...newProps
} = props;

const style = {
maxWidth: "100%",
width: "100%",
};

return (
<div ref={uiContainerRef} className={props.className}>
<div style={style} ref={uiContainerRef} className={props.className}>
<video
ref={videoRef}
className={props.playerClassName}
style={{
maxWidth: "100%",
width: "100%",
}}
style={style}
{...newProps}
/>
</div>
Expand Down
8 changes: 7 additions & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ export interface PlayerRefs {

export interface PlayerProps {
src?: string;
config?: any;
config?: shaka.extern.PlayerConfiguration | any;
uiConfig?: shaka.extern.UIConfiguration | any;
autoPlay?: boolean | undefined;
playsInline?: boolean | undefined;
children?: any;
className?: string;
playerClassName?: string;
onLoad?(data: PlayerRefs): void;
onPlay?(): void | undefined;
onPause?(): void | undefined;
onPlayerError?(event: Shaka.extern.Error): void;
onBuffering?(event: boolean): void;
}
Loading

0 comments on commit 816bdda

Please sign in to comment.