Skip to content

Commit

Permalink
Feat: players (#361)
Browse files Browse the repository at this point in the history
* hls clappr & dplayer

* vime player

* plyr player

* plyr instance

* openPlayer

* added opt groups in playback options

* shaka player

* separated player's props

* shaka DPlayer

* Shaka Clappr

* Clappr declaration

* Add PlayerEvents type

* Plyr imporvements

* OpenPlayer improvements

* Simplified hls configuration with getConfiguredHlsInstance

* simplified shakaP2PEngine configuration

* mediaelement test

* simplified render func

* shaka import improvements

* fixed playback options

* Clappr shakaP2PEngine

* shaka Plyr

* p2p engine destroy

* refactored HLS integration in players

* hls mediaElement player container

* configure shaka events

* Plyr improvements

* remove window.Hls on cleanup

* refactored cleanup logic for openPlayer

* small adjustments

* small adjustments

* MediaElement bug fixed

* shaka improvements

* clappr styles

* shaka clappr

* type declaration

* global declaration

* fixed type errors

* Add HLS & shaka support check and error message for unsupported browsers

* Refactor useQueryParams hook to improve readability and performance

* add custom quality selector for hlsjs player

* Fix select-container alignment issue in Hlsjs.css

* removed redundant code

* Add playsInline attribute to video elements in players

* test vime with mp4

* Add vidstack player

* Update HLS provider library

* Improve types

* simplified vidstack player setup

* p2p config improvements

* fix type error

* changed default player

* added debug mode from query params

* Removed Vime player since it will be deprecated

* fixed naming

---------

Co-authored-by: Andriy Lysnevych <[email protected]>
  • Loading branch information
DimaDemchenko and mrlika authored May 10, 2024
1 parent abf623e commit e7be84f
Show file tree
Hide file tree
Showing 30 changed files with 1,659 additions and 141 deletions.
2 changes: 1 addition & 1 deletion demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
"dplayer": "^1.27.1",
"mux.js": "^6.3.0",
"p2p-media-loader-core": "workspace:*",
"p2p-media-loader-demo": "workspace:*",
"p2p-media-loader-hlsjs": "workspace:*",
"p2p-media-loader-shaka": "workspace:*",
"p2p-media-loader-demo": "workspace:*",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
68 changes: 68 additions & 0 deletions demo/public/mejs-controls.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 8 additions & 1 deletion packages/p2p-media-loader-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,17 @@
"clean-with-modules": "rimraf node_modules && pnpm clean"
},
"dependencies": {
"@vidstack/react": "^1.11.21",
"d3": "^7.9.0",
"dplayer": "^1.27.1",
"hls.js": "^1.5.7",
"mediaelement": "^7.0.5",
"openplayerjs": "^2.14.3",
"p2p-media-loader-core": "workspace:*",
"p2p-media-loader-hlsjs": "workspace:*"
"p2p-media-loader-hlsjs": "workspace:*",
"p2p-media-loader-shaka": "workspace:*",
"plyr": "^3.7.8",
"shaka-player": "^4.7.13"
},
"devDependencies": {
"@types/d3": "^7.4.3",
Expand Down
82 changes: 54 additions & 28 deletions packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,56 @@
import "./demo.css";
import type Hls from "hls.js";
import { PlaybackOptions } from "./PlaybackOptions";
import { PLAYERS } from "../constants";
import { DEBUG_COMPONENT_ENABLED, PLAYERS } from "../constants";
import { useQueryParams } from "../hooks/useQueryParams";
import { HlsjsPlayer } from "./players/Hlsjs";
import { HlsjsPlayer } from "./players/hlsjs/Hlsjs";
import { useCallback, useMemo, useRef, useState } from "react";
import { DownloadStatsChart } from "./chart/DownloadStatsChart";
import { NodeNetwork } from "./nodeNetwork/NodeNetwork";
import { DebugTools } from "./debugTools/DebugTools";
import { DownloadStats } from "../types";
import { DownloadStats, PlayerKey } from "../types";
import { HlsjsDPlayer } from "./players/hlsjs/HlsjsDPLayer";
import { HlsjsClapprPlayer } from "./players/hlsjs/HlsjsClapprPlayer";
import { HlsjsPlyr } from "./players/hlsjs/HlsjsPlyr";
import { HlsjsOpenPlayer } from "./players/hlsjs/HlsjsOpenPlayer";
import { Shaka } from "./players/shaka/Shaka";
import { ShakaDPlayer } from "./players/shaka/ShakaDPlayer";
import { ShakaClappr } from "./players/shaka/ShakaClappr";
import { HlsjsMediaElement } from "./players/hlsjs/HlsjsMediaElement";
import { ShakaPlyr } from "./players/shaka/ShakaPlyr";
import { HlsJsP2PEngine } from "p2p-media-loader-hlsjs";
import Hls from "hls.js";
import { HlsjsVidstack } from "./players/hlsjs/HlsjsVidstack";

type DemoProps = {
debugToolsEnabled?: boolean;
};

const HlsWithP2PType = HlsJsP2PEngine.injectMixin(Hls);

declare global {
interface Window {
Hls: typeof Hls;
videoPlayer?: { destroy?: () => void };
shaka?: unknown;
Hls?: typeof HlsWithP2PType;
LevelSelector: unknown;
DashShakaPlayback: unknown;
}
}

export type Player = (typeof PLAYERS)[number];

type DemoProps = {
debugToolsEnabled?: boolean;
const playerComponents = {
openPlayer_hls: HlsjsOpenPlayer,
plyr_hls: HlsjsPlyr,
clappr_hls: HlsjsClapprPlayer,
dplayer_hls: HlsjsDPlayer,
hlsjs_hls: HlsjsPlayer,
shaka: Shaka,
dplayer_shaka: ShakaDPlayer,
clappr_shaka: ShakaClappr,
mediaElement_hls: HlsjsMediaElement,
plyr_shaka: ShakaPlyr,
vidstack_hls: HlsjsVidstack,
};

export const P2PVideoDemo = ({ debugToolsEnabled }: DemoProps) => {
export const P2PVideoDemo = ({ debugToolsEnabled = false }: DemoProps) => {
const data = useRef<DownloadStats>({
httpDownloaded: 0,
p2pDownloaded: 0,
Expand Down Expand Up @@ -72,26 +99,23 @@ export const P2PVideoDemo = ({ debugToolsEnabled }: DemoProps) => {
}, []);

const handlePlaybackOptionsUpdate = (url: string, player: string) => {
if (!PLAYERS.includes(player as Player)) return;
if (!(player in PLAYERS)) return;
setURLQueryParams({ streamUrl: url, player });
};

const renderPlayer = () => {
switch (queryParams.player) {
case "hlsjs":
return (
<HlsjsPlayer
streamUrl={queryParams.streamUrl}
announceTrackers={trackers}
onPeerConnect={onPeerConnect}
onPeerDisconnect={onPeerDisconnect}
onChunkDownloaded={onChunkDownloaded}
onChunkUploaded={onChunkUploaded}
/>
);
default:
return null;
}
const PlayerComponent = playerComponents[queryParams.player as PlayerKey];

return PlayerComponent ? (
<PlayerComponent
streamUrl={queryParams.streamUrl}
announceTrackers={trackers}
onPeerConnect={onPeerConnect}
onPeerDisconnect={onPeerDisconnect}
onChunkDownloaded={onChunkDownloaded}
onChunkUploaded={onChunkUploaded}
/>
) : null;
};

return (
Expand Down Expand Up @@ -125,7 +149,9 @@ export const P2PVideoDemo = ({ debugToolsEnabled }: DemoProps) => {
)}
</div>
</div>
{debugToolsEnabled && <DebugTools />}
{(debugToolsEnabled || queryParams.debug === DEBUG_COMPONENT_ENABLED) && (
<DebugTools />
)}
</>
);
};
38 changes: 31 additions & 7 deletions packages/p2p-media-loader-demo/src/components/PlaybackOptions.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useRef } from "react";
import { PLAYERS } from "../constants";
import { PlayerKey, PlayerName } from "../types";

type PlaybackOptions = {
updatePlaybackOptions: (url: string, player: string) => void;
Expand All @@ -17,6 +18,17 @@ export const PlaybackOptions = ({

const isHttps = window.location.protocol === "https:";

const hlsPlayers: Partial<Record<PlayerKey, PlayerName>> = {};
const shakaPlayers: Partial<Record<PlayerKey, PlayerName>> = {};

Object.entries(PLAYERS).forEach(([key, name]) => {
if (key.includes("hls")) {
hlsPlayers[key as PlayerKey] = name;
} else if (key.includes("shaka")) {
shakaPlayers[key as PlayerKey] = name;
}
});

const handleApply = () => {
const player = playerSelectRef.current?.value;
const streamUrl = streamUrlInputRef.current?.value;
Expand All @@ -34,6 +46,7 @@ export const PlaybackOptions = ({
Video URL{isHttps ? " (HTTPS only)" : ""}:
</label>
<input
key={streamUrl}
className="item"
defaultValue={streamUrl}
id="streamUrl"
Expand All @@ -45,16 +58,27 @@ export const PlaybackOptions = ({
<label htmlFor="player">Player:</label>
<select
className="item"
key={currentPlayer}
key={String(currentPlayer)}
ref={playerSelectRef}
id="player"
defaultValue={currentPlayer}
defaultValue={String(currentPlayer)}
>
{PLAYERS.map((player) => (
<option key={player} value={player}>
{player}
</option>
))}
<optgroup label="Hls.js P2P Engine (HLS Only)">
{Object.entries(hlsPlayers).map(([key, name]) => (
<option key={key} value={key}>
{name}
</option>
))}
</optgroup>
{Object.keys(shakaPlayers).length > 0 && (
<optgroup label="Shaka Players">
{Object.entries(shakaPlayers).map(([key, name]) => (
<option key={key} value={key}>
{name}
</option>
))}
</optgroup>
)}
</select>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export const DebugTools = () => {
return (
<div className="demo-container dev-container">
<DebugSelector />
<a href="modules-demo/index.html">ES modules demo</a>
</div>
);
};
9 changes: 9 additions & 0 deletions packages/p2p-media-loader-demo/src/components/demo.css
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,12 @@
display: flex;
gap: 1em;
}

.error-message {
margin-top: 1em;
padding: 1em;
background-color: #f8d7da;
border: 1px solid #f5c6cb;
border-radius: 0.25rem;
color: #721c24;
}
67 changes: 0 additions & 67 deletions packages/p2p-media-loader-demo/src/components/players/Hlsjs.tsx

This file was deleted.

Loading

0 comments on commit e7be84f

Please sign in to comment.