diff --git a/package-lock.json b/package-lock.json index 3f87c99..74b22cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,8 @@ "lucide-react": "^1.16.0", "next": "14.2.35", "next-intl": "^4.12.0", + "plyr": "^3.7.8", + "plyr-react": "^5.3.0", "react": "^18", "react-dom": "^18", "react-hook-form": "^7.76.0", @@ -4002,6 +4004,17 @@ "dev": true, "license": "MIT" }, + "node_modules/core-js": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz", + "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -4042,6 +4055,12 @@ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "license": "MIT" }, + "node_modules/custom-event-polyfill": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz", + "integrity": "sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==", + "license": "MIT" + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -6270,6 +6289,12 @@ "dev": true, "license": "MIT" }, + "node_modules/loadjs": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loadjs/-/loadjs-4.3.0.tgz", + "integrity": "sha512-vNX4ZZLJBeDEOBvdr2v/F+0aN5oMuPu7JTqrMwp+DtgK+AryOlpy6Xtm2/HpNr+azEa828oQjOtWsB6iDtSfSQ==", + "license": "MIT" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7005,6 +7030,44 @@ "node": ">= 6" } }, + "node_modules/plyr": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/plyr/-/plyr-3.7.8.tgz", + "integrity": "sha512-yG/EHDobwbB/uP+4Bm6eUpJ93f8xxHjjk2dYcD1Oqpe1EcuQl5tzzw9Oq+uVAzd2lkM11qZfydSiyIpiB8pgdA==", + "license": "MIT", + "dependencies": { + "core-js": "^3.26.1", + "custom-event-polyfill": "^1.0.7", + "loadjs": "^4.2.0", + "rangetouch": "^2.0.1", + "url-polyfill": "^1.1.12" + } + }, + "node_modules/plyr-react": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/plyr-react/-/plyr-react-5.3.0.tgz", + "integrity": "sha512-m36/HrpHwg1N2rq3E31E8/kpAH55vk6qHUg17MG4uu9jbWYxnkN39lLmZQwxW7/qpDPfW5aGUJ6R3u23V0R3zA==", + "license": "MIT", + "dependencies": { + "plyr": "^3.7.7", + "react-aptor": "^2.0.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "plyr": "^3.7.7", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "plyr": { + "optional": false + }, + "react": { + "optional": true + } + } + }, "node_modules/po-parser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/po-parser/-/po-parser-2.1.1.tgz", @@ -7264,6 +7327,12 @@ ], "license": "MIT" }, + "node_modules/rangetouch": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/rangetouch/-/rangetouch-2.0.1.tgz", + "integrity": "sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA==", + "license": "MIT" + }, "node_modules/re-resizable": { "version": "6.11.2", "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-6.11.2.tgz", @@ -7286,6 +7355,23 @@ "node": ">=0.10.0" } }, + "node_modules/react-aptor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-aptor/-/react-aptor-2.0.0.tgz", + "integrity": "sha512-YnCayokuhAwmBBP4Oc0bbT2l6ApfsjbY3DEEVUddIKZEBlGl1npzjHHzWnSqWuboSbMZvRqUM01Io9yiIp1wcg==", + "license": "MIT", + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, "node_modules/react-date-object": { "version": "2.1.9", "resolved": "https://registry.npmjs.org/react-date-object/-/react-date-object-2.1.9.tgz", @@ -8698,6 +8784,12 @@ "punycode": "^2.1.0" } }, + "node_modules/url-polyfill": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/url-polyfill/-/url-polyfill-1.1.14.tgz", + "integrity": "sha512-p4f3TTAG6ADVF3mwbXw7hGw+QJyw5CnNGvYh5fCuQQZIiuKUswqcznyV3pGDP9j0TSmC4UvRKm8kl1QsX1diiQ==", + "license": "MIT" + }, "node_modules/use-callback-ref": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", diff --git a/package.json b/package.json index bcfcde7..dcce7d4 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,8 @@ "lucide-react": "^1.16.0", "next": "14.2.35", "next-intl": "^4.12.0", + "plyr": "^3.7.8", + "plyr-react": "^5.3.0", "react": "^18", "react-dom": "^18", "react-hook-form": "^7.76.0", diff --git a/src/components/templates/BrandedVideoPlayer.tsx b/src/components/templates/BrandedVideoPlayer.tsx new file mode 100644 index 0000000..58318ad --- /dev/null +++ b/src/components/templates/BrandedVideoPlayer.tsx @@ -0,0 +1,88 @@ +"use client"; + +import { useEffect, useRef } from "react"; +import Plyr, { type APITypes } from "plyr-react"; +import "plyr-react/plyr.css"; + +interface BrandedVideoPlayerProps { + src: string; + poster?: string; + /** Plyr aspect ratio, e.g. "16:9" | "1:1" | "9:16". */ + ratio?: string; + className?: string; +} + +/** + * FlatRender-branded video player (Plyr via plyr-react) for template demo videos. + * + * Branding: accent + controls use the FlatRender blue via Plyr CSS custom + * properties on the wrapper. + * + * Download protection: NO download control is exposed (Plyr replaces the native + * controls so the browser's download menu never appears); the underlying + *