diff --git a/examples/react/src/App.tsx b/examples/react/src/App.tsx
index 48a53714..78fdfa1d 100644
--- a/examples/react/src/App.tsx
+++ b/examples/react/src/App.tsx
@@ -238,6 +238,9 @@ const App = () => {
},
vimeo: {
color: 'ffffff'
+ },
+ spotify: {
+ preferVideo: true
}
}}
onLoadStart={() => console.log('onLoadStart')}
@@ -467,6 +470,19 @@ const App = () => {
{renderLoadButton('https://home.wistia.com/medias/bq6epni33s', 'Test C')}
+
| Custom |
diff --git a/package-lock.json b/package-lock.json
index d62d9093..65e6f851 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,6 +14,8 @@
"dash-video-element": "^0.1.5",
"deepmerge": "^4.0.0",
"hls-video-element": "^1.5.5",
+ "spotify-audio-element": "^1.0.1",
+ "twitch-video-element": "^0.1.0",
"vimeo-video-element": "^1.5.1",
"wistia-video-element": "^1.3.2",
"youtube-video-element": "^1.6.0"
@@ -3283,6 +3285,12 @@
"integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==",
"dev": true
},
+ "node_modules/spotify-audio-element": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/spotify-audio-element/-/spotify-audio-element-1.0.1.tgz",
+ "integrity": "sha512-Uc30QxulPAoWxkMSVeMGcHmEij9KXedzbsliwlhNWnZP2Fgkz1Ifl2laj0poAXiqUDdJTWapfUI9IkGkhwgTEg==",
+ "license": "MIT"
+ },
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -3485,6 +3493,12 @@
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"dev": true
},
+ "node_modules/twitch-video-element": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/twitch-video-element/-/twitch-video-element-0.1.0.tgz",
+ "integrity": "sha512-9aV0OD9/QtMqV554RkjOHxg/WzMjDwxtp1l+M0OXIaQiLOrrL16FYqyng6g0dm9NY3Sx35ybdGTmDC/NvC3Xkw==",
+ "license": "MIT"
+ },
"node_modules/type-detect": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
diff --git a/package.json b/package.json
index b9c225c9..1751a693 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,8 @@
"dash-video-element": "^0.1.5",
"deepmerge": "^4.0.0",
"hls-video-element": "^1.5.5",
+ "spotify-audio-element": "^1.0.1",
+ "twitch-video-element": "^0.1.0",
"vimeo-video-element": "^1.5.1",
"wistia-video-element": "^1.3.2",
"youtube-video-element": "^1.6.0"
diff --git a/src/patterns.ts b/src/patterns.ts
index d5ba2d51..8d824450 100644
--- a/src/patterns.ts
+++ b/src/patterns.ts
@@ -10,6 +10,8 @@ export const MATCH_URL_YOUTUBE =
export const MATCH_URL_VIMEO = /vimeo\.com\/(?!progressive_redirect).+/;
export const MATCH_URL_WISTIA =
/(?:wistia\.(?:com|net)|wi\.st)\/(?:medias|embed)\/(?:iframe\/)?([^?]+)/;
+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+)($|\?)/;
const canPlayFile = (url: string, test: (u: string) => boolean) => {
if (Array.isArray(url)) {
@@ -36,4 +38,6 @@ export const canPlay = {
vimeo: (url: string) =>
MATCH_URL_VIMEO.test(url) && !VIDEO_EXTENSIONS.test(url) && !HLS_EXTENSIONS.test(url),
wistia: (url: string) => MATCH_URL_WISTIA.test(url),
+ spotify: (url: string) => MATCH_URL_SPOTIFY.test(url),
+ twitch: (url: string) => MATCH_URL_TWITCH.test(url),
};
diff --git a/src/players.ts b/src/players.ts
index 1ab6ca18..04bd2f4f 100644
--- a/src/players.ts
+++ b/src/players.ts
@@ -66,6 +66,24 @@ const Players: PlayerEntry[] = [
() => import(/* webpackChunkName: 'reactPlayerWistia' */ 'wistia-video-element/react')
) as React.LazyExoticComponent>,
},
+ {
+ key: 'spotify',
+ name: 'Spotify',
+ canPlay: canPlay.spotify,
+ canEnablePIP: () => false,
+ player: lazy(
+ () => import(/* webpackChunkName: 'reactPlayerSpotify' */ 'spotify-audio-element/react')
+ ) as React.LazyExoticComponent>,
+ },
+ {
+ key: 'twitch',
+ name: 'Twitch',
+ canPlay: canPlay.twitch,
+ canEnablePIP: () => false,
+ player: lazy(
+ () => import(/* webpackChunkName: 'reactPlayerTwitch' */ 'twitch-video-element/react')
+ ) as React.LazyExoticComponent>,
+ },
{
key: 'html',
name: 'html',
diff --git a/src/types.ts b/src/types.ts
index 2d49cf03..ad4773a9 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1,4 +1,9 @@
import type { MediaHTMLAttributes, SyntheticEvent } from 'react';
+import type HlsVideoElement from 'hls-video-element';
+import type SpotifyAudioElement from 'spotify-audio-element';
+import type YouTubeVideoElement from 'youtube-video-element';
+import type VimeoVideoElement from 'vimeo-video-element';
+import type TwitchVideoElement from 'twitch-video-element';
interface VideoHTMLAttributes extends MediaHTMLAttributes {
height?: number | string | undefined;
@@ -39,11 +44,13 @@ export interface PreviewProps {
}
export interface Config {
- html?: Record;
- hls?: Record;
dash?: Record;
+ hls?: HlsVideoElement['config'];
+ html?: Record;
mux?: Record;
- youtube?: Record;
- vimeo?: Record;
+ spotify?: SpotifyAudioElement['config'];
+ twitch?: TwitchVideoElement['config'];
+ vimeo?: VimeoVideoElement['config'];
wistia?: Record;
+ youtube?: YouTubeVideoElement['config'];
}
|