diff --git a/examples/react/src/App.tsx b/examples/react/src/App.tsx
index d34b6041..03a69f33 100644
--- a/examples/react/src/App.tsx
+++ b/examples/react/src/App.tsx
@@ -504,6 +504,12 @@ const App = () => {
{renderLoadButton('https://www.tiktok.com/@scout2015/video/6718335390845095173', 'Test B')}
+
| Custom |
diff --git a/package-lock.json b/package-lock.json
index ef66be46..83a4aa75 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,7 @@
"cloudflare-video-element": "^1.3.4",
"dash-video-element": "^0.3.0",
"hls-video-element": "^1.5.9",
+ "peertube-video-element": "^1.1.0",
"spotify-audio-element": "^1.0.3",
"tiktok-video-element": "^0.1.1",
"twitch-video-element": "^0.1.5",
@@ -798,6 +799,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz",
"integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==",
"devOptional": true,
+ "peer": true,
"dependencies": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
@@ -2451,6 +2453,12 @@
"ce-la-react": "^0.3.0"
}
},
+ "node_modules/media-played-ranges-mixin": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/media-played-ranges-mixin/-/media-played-ranges-mixin-0.1.0.tgz",
+ "integrity": "sha512-zTsvkleu5sAyTsPVxDI+KUbCwy/lXwHgOPi3ER9S3lhtAWhGTQH6qxvfrVMym1cvoLU36SPbVr6Qe8Zxyc0WpA==",
+ "license": "MIT"
+ },
"node_modules/media-tracks": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/media-tracks/-/media-tracks-0.3.4.tgz",
@@ -2828,6 +2836,16 @@
"isarray": "0.0.1"
}
},
+ "node_modules/peertube-video-element": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/peertube-video-element/-/peertube-video-element-1.1.0.tgz",
+ "integrity": "sha512-yQ8X+0X+dZfAD+yLiQJlRdyMHLHr8PB3SQUA49z2heTaLvGDhPzLUJLqOa2NHQbjtVgd5L1z+RBRoBZLlnpplA==",
+ "license": "MIT",
+ "dependencies": {
+ "media-played-ranges-mixin": "^0.1.0",
+ "media-tracks": "^0.3.0"
+ }
+ },
"node_modules/pidtree": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz",
@@ -2888,6 +2906,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
@@ -2899,6 +2918,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
diff --git a/package.json b/package.json
index c17ed3b1..456dcee4 100644
--- a/package.json
+++ b/package.json
@@ -54,6 +54,7 @@
"cloudflare-video-element": "^1.3.4",
"dash-video-element": "^0.3.0",
"hls-video-element": "^1.5.9",
+ "peertube-video-element": "^1.1.0",
"spotify-audio-element": "^1.0.3",
"tiktok-video-element": "^0.1.1",
"twitch-video-element": "^0.1.5",
diff --git a/src/patterns.ts b/src/patterns.ts
index 37809c31..19a60830 100644
--- a/src/patterns.ts
+++ b/src/patterns.ts
@@ -13,6 +13,8 @@ export const MATCH_URL_WISTIA =
export const MATCH_URL_SPOTIFY = /open\.spotify\.com\/(\w+)\/(\w+)/i;
export const MATCH_URL_TWITCH = /(?:www\.|go\.)?twitch\.tv\/([a-zA-Z0-9_]+|(videos?\/|\?video=)\d+)($|\?)/;
export const MATCH_URL_TIKTOK = /tiktok\.com\/(?:player\/v1\/|share\/video\/|@[^/]+\/video\/)([0-9]+)/;
+export const MATCH_URL_PEERTUBE = /(?:videos\/(?:watch|embed)|\/w)\/([^/?#&\s]+)/;
+
const canPlayFile = (url: string, test: (u: string) => boolean) => {
if (Array.isArray(url)) {
@@ -42,4 +44,5 @@ export const canPlay = {
spotify: (url: string) => MATCH_URL_SPOTIFY.test(url),
twitch: (url: string) => MATCH_URL_TWITCH.test(url),
tiktok: (url: string) => MATCH_URL_TIKTOK.test(url),
+ peertube: (url: string)=> MATCH_URL_PEERTUBE.test(url)
};
diff --git a/src/players.ts b/src/players.ts
index 10a4d1e6..bacb83c9 100644
--- a/src/players.ts
+++ b/src/players.ts
@@ -93,6 +93,15 @@ const Players: PlayerEntry[] = [
() => import(/* webpackChunkName: 'reactPlayerTiktok' */ 'tiktok-video-element/react')
) as React.LazyExoticComponent>,
},
+ {
+ key: 'peertube',
+ name: 'PeerTube',
+ canPlay: canPlay.peertube,
+ canEnablePIP: () => false,
+ player: lazy(
+ () => import(/* webpackChunkName: 'reactPlayerTiktok' */ 'peertube-video-element/react')
+ ) as React.LazyExoticComponent>,
+ },
{
key: 'html',
name: 'html',
diff --git a/src/types.ts b/src/types.ts
index 411f4f2b..f43acbf5 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -5,6 +5,7 @@ import type YouTubeVideoElement from 'youtube-video-element';
import type VimeoVideoElement from 'vimeo-video-element';
import type TwitchVideoElement from 'twitch-video-element';
import type TikTokVideoElement from 'tiktok-video-element';
+import type PeerTubeVideoElement from 'peertube-video-element';
interface VideoHTMLAttributes extends MediaHTMLAttributes {
height?: number | string | undefined;
@@ -55,4 +56,5 @@ export interface Config {
vimeo?: VimeoVideoElement['config'];
wistia?: Record;
youtube?: YouTubeVideoElement['config'];
+ peertube?: PeerTubeVideoElement['config'];
}
|