Skip to content

Commit 8674b95

Browse files
authored
feat: CldVideoPlayer support for Next.js 13 App Router (#265)
# Description With the App Router, we no longer have access to the <Head component. CldVideoPlayer was utilizing this component in order to load a stylesheet, preventing the need to include it from the project, but without <Head, the player breaks. Given this is no longer an option, this includes the CSS and associated files on build so that they're able to be imported from within the App Router project, allowing the stylesheet to be imported for a working player. This is currently downloading the assets from unpkg, where the player is officially hosted, though future iterations may include these files from the cloudinary-video-player node_module, though thats currently on hold for performance reasons. See #181 This also deprecates the `version` prop as we're no longer able to reliably grab assets based on the configured version (or at all for that matter). In future versions using the node module, the assets will be synced based on the installed dependency via next-cloudinary without configuration available. ## Issue Ticket Number Fixes #248 <!-- Specify above which issue this fixes by referencing the issue number (`#<ISSUE_NUMBER>`) or issue URL. --> <!-- Example: Fixes https://github.com/colbyfayock/next-cloudinary/issues/<ISSUE_NUMBER> --> ## Type of change <!-- Please select all options that are applicable. --> - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Fix or improve the documentation - [ ] This change requires a documentation update # Checklist <!-- These must all be followed and checked. --> - [ ] I have followed the contributing guidelines of this project as mentioned in [CONTRIBUTING.md](/CONTRIBUTING.md) - [ ] I have created an [issue](https://github.com/colbyfayock/next-cloudinary/issues) ticket for this PR - [ ] I have checked to ensure there aren't other open [Pull Requests](https://github.com/colbyfayock/next-cloudinary/pulls) for the same update/change? - [ ] I have performed a self-review of my own code - [ ] I have run tests locally to ensure they all pass - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes needed to the documentation
1 parent 52bad18 commit 8674b95

File tree

8 files changed

+99
-5
lines changed

8 files changed

+99
-5
lines changed

docs/pages/cldvideoplayer/basic-usage.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ import { CldVideoPlayer } from 'next-cloudinary';
3434
/>
3535
```
3636

37+
If you're using the Next.js 13 App Router, you must additionally import the Cloudinary Video Player stylesheet:
38+
39+
```jsx
40+
import 'next-cloudinary/dist/cld-video-player.css';
41+
```
42+
3743
<CldVideoPlayer
3844
width="1620"
3945
height="1080"

docs/pages/cldvideoplayer/configuration.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ import OgImage from '../../components/OgImage';
3939
| showLogo | boolea | `true` | Show the Cloudinary logo on Player | `false` |
4040
| src | string | - | **Required**: Video public ID | `"videos/my-video"` |
4141
| transformation | object/array | - | Transformations to apply to the video | `{ width: 200, height: 200, crop: 'fill' }` |
42-
| version | string | `"1.9.4"` | Cloudinary Video Player version | `"1.9.4"` |
43-
| videoRef | Ref | - | React ref to access video element | See Refs Below |
42+
| version | string | `"1.9.14"` | **Deprecated** | - ` |
43+
| videoRef | Ref | - | React ref to access video element | See Refs Below |
4444
| width | string/number | - | **Required**: Player width | `1920` |
4545

4646
Missing an option from the [Video Player docs](https://cloudinary.com/documentation/video_player_api_reference) you'd like to see? [Create an issue](https://github.com/colbyfayock/next-cloudinary/issues/new?assignees=&labels=Type%3A+Feature&template=feature_request.md&title=%5BFeature%5D+)!

next-cloudinary/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"dotenv": "^16.0.3",
2828
"jest": "^29.2.2",
2929
"jest-environment-jsdom": "^29.2.2",
30+
"mkdirp": "^3.0.1",
3031
"ts-jest": "^29.0.3",
3132
"tsup": "^6.6.3",
3233
"typescript": "^4.9.4"
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { Plugin } from 'esbuild'
2+
import path from 'path';
3+
import { createWriteStream } from 'fs';
4+
import { mkdirp } from 'mkdirp';
5+
import https from 'https';
6+
7+
const version = '1.9.14';
8+
9+
const assets = [
10+
`https://unpkg.com/cloudinary-video-player@${version}/dist/cld-video-player.css`,
11+
{
12+
directory: 'fonts',
13+
assets: [
14+
`https://unpkg.com/cloudinary-video-player@${version}/dist/fonts/cloudinary_icon_for_black_bg.svg`,
15+
`https://unpkg.com/cloudinary-video-player@${version}/dist/fonts/cloudinary_icon_for_white_bg.svg`,
16+
]
17+
}
18+
];
19+
20+
let hasWrittenAssets = false;
21+
22+
export const plugin: Plugin = {
23+
name: 'copy-assets',
24+
setup: async () => {
25+
const rootPath = path.join(__dirname, '../');
26+
const distPath = path.join(rootPath, 'dist');
27+
28+
if ( hasWrittenAssets ) return;
29+
30+
await mkdirp(distPath);
31+
32+
for ( const asset of assets ) {
33+
34+
if ( typeof asset === 'string' ) {
35+
const writePath = path.join(distPath, path.basename(asset));
36+
await downloadFile(asset, writePath);
37+
console.log(`Wrote ${asset} to ${writePath}`);
38+
} else if ( typeof asset.directory === 'string' ) {
39+
await mkdirp(path.join(distPath, asset.directory));
40+
41+
for ( const dirAsset of asset.assets ) {
42+
const writePath = path.join(distPath, asset.directory, path.basename(dirAsset));
43+
await downloadFile(dirAsset, writePath);
44+
console.log(`Wrote ${dirAsset} to ${writePath}`);
45+
}
46+
}
47+
}
48+
49+
hasWrittenAssets = true;
50+
}
51+
}
52+
53+
/**
54+
* downloadFile
55+
*/
56+
57+
function downloadFile(assetUrl: string, writePath: string) {
58+
return new Promise<void>((resolve) => {
59+
const file = createWriteStream(writePath);
60+
https.get(assetUrl, function(response) {
61+
response.pipe(file);
62+
file.on('finish', () => {
63+
file.close();
64+
resolve();
65+
});
66+
});
67+
})
68+
}

next-cloudinary/src/components/CldVideoPlayer/CldVideoPlayer.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,18 @@ const CldVideoPlayer = (props: CldVideoPlayerProps) => {
3232
onEnded,
3333
src,
3434
transformation,
35-
version = '1.9.4',
35+
version = '1.9.14',
3636
quality = 'auto',
3737
width,
3838
} = props as CldVideoPlayerProps;
3939

4040
const playerTransformations = Array.isArray(transformation) ? transformation : [transformation];
4141
let publicId = src;
4242

43+
if ( typeof props.version === 'string' ) {
44+
console.warn('The version prop will no longer be supported in future versions due to the unreliability of coordinating assets');
45+
}
46+
4347
// If the publicId/src is a URL, attempt to parse it as a Cloudinary URL
4448
// to get the public ID alone
4549

next-cloudinary/tests/nextjs-app/app/page.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"use client";
22

3-
import { CldImage, CldUploadWidget } from '../../../';
3+
import { CldImage, CldUploadWidget, CldVideoPlayer } from '../../../';
4+
5+
import '../../../dist/cld-video-player.css';
46

57
export default function Home() {
68
return (
@@ -12,6 +14,12 @@ export default function Home() {
1214
sources: ['local', 'camera']
1315
}}
1416
/>
17+
<CldVideoPlayer
18+
id="test"
19+
width="1620"
20+
height="1080"
21+
src={`videos/mountain-stars`}
22+
/>
1523
</>
1624
)
1725
}

next-cloudinary/tsup.config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { defineConfig } from 'tsup'
2+
import { plugin as CopyAssetsPlugin } from './plugins/copy-assets';
23

34
export default defineConfig({
45
minify: true,
56
target: 'es2018',
67
external: ['react'],
78
sourcemap: true,
89
dts: true,
9-
format: ['esm', 'cjs']
10+
format: ['esm', 'cjs'],
11+
esbuildPlugins: [CopyAssetsPlugin]
1012
})

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4990,6 +4990,11 @@ minimatch@^3.0.4, minimatch@^3.1.1:
49904990
dependencies:
49914991
brace-expansion "^1.1.7"
49924992

4993+
mkdirp@^3.0.1:
4994+
version "3.0.1"
4995+
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50"
4996+
integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==
4997+
49934998
mri@^1.1.0:
49944999
version "1.2.0"
49955000
resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"

0 commit comments

Comments
 (0)