Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/mux-video/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ export default buildConfig({
| `posterExtension` | `'webp' \| 'jpg' \| 'png'` | `"png"` | The image format to use for video posters. |
| `animatedGifExtension` | `'gif' \| 'webp'` | `"gif"` | The image format to use for animated preview thumbnails. |
| `adminThumbnail` | `'gif' \| 'image' \| 'none'` | `"gif"` | Specifies the type of thumbnail to display for videos in the collection list view. |
| `posterExtension` | `'jpg' \| 'png' \| 'webp'` | `"png"` | The file extension to use for generated poster images. |
| `animatedGifExtension` | `'gif' \| 'webp'` | `"gif"` | The file extension to use for generated animated gifs. |
| `onInitBehavior` | `"createOnly" \| "deleteOnly" \| "createAndDelete" \| "none"` | `"none"` | What to do on plugin initialization when there are discrepancies between videos in Mux and entries in the Payload collection. |
| `autoCreateOnWebhook` | `boolean` | `false` | If enabled, the Mux webhook will automatically create videos that are missing in Payload when webhooks are received from Mux. Useful for uploading videos directly in Mux and automatically backfilling them in Payload. |


Expand Down
77 changes: 76 additions & 1 deletion packages/mux-video/src/lib/onInitExtension.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,83 @@
import Mux from '@mux/mux-node'
import type { Payload } from 'payload'
import type { MuxVideoPluginOptions } from '../types'
import { getAssetMetadata } from './getAssetMetadata'

export const onInitExtension = (pluginOptions: MuxVideoPluginOptions, payload: Payload): void => {
export const onInitExtension = async (
pluginOptions: MuxVideoPluginOptions,
payload: Payload,
mux: Mux,
): Promise<void> => {
try {
if (pluginOptions.onInitBehavior === 'none') {
return
}

const videos = await mux.video.assets.list()
const ids = videos.data.map((video) => video.id)
const collection = (pluginOptions.extendCollection as string) ?? 'mux-video'

const existingVideos = await payload.find({
collection,
where: {
assetId: {
in: ids,
},
},
limit: videos.data.length,
})

const shouldCreate =
pluginOptions.onInitBehavior === 'createOnly' ||
pluginOptions.onInitBehavior === 'createAndDelete'
const shouldDelete =
pluginOptions.onInitBehavior === 'deleteOnly' ||
pluginOptions.onInitBehavior === 'createAndDelete'

if (shouldCreate) {
const missingVideos = videos.data.filter(
(video) => !existingVideos.docs.find((doc) => doc.assetId === video.id),
)
payload.logger.info(
`[payload-mux] Creating missing Mux video entries (${missingVideos.length})...`,
)

for (const video of missingVideos) {
await payload.create({
collection,
data: {
title: `Video ${video.id}`,
assetId: video.id,
...video,
...getAssetMetadata(video),
},
})
}
}

if (shouldDelete) {
const extraVideos = await payload.find({
collection,
limit: 100,
where: {
assetId: {
not_in: ids,
},
},
})
payload.logger.info(
`[payload-mux] Deleting extra Mux video entries (${extraVideos.docs.length})...`,
)

for (const video of extraVideos.docs) {
if (pluginOptions.onInitBehavior === 'createAndDelete') {
await payload.delete({
collection,
id: video.id,
})
}
}
}
} catch (err: unknown) {
payload.logger.error({ err, msg: 'Error in onInitExtension' })
}
Expand Down
2 changes: 1 addition & 1 deletion packages/mux-video/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const muxVideoPlugin =
await incomingConfig.onInit(payload)
}

onInitExtension(pluginOptions, payload)
await onInitExtension(pluginOptions, payload, mux)
}

return config
Expand Down
11 changes: 11 additions & 0 deletions packages/mux-video/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,17 @@ export type MuxVideoPluginOptions = {
*/
animatedGifExtension?: 'gif' | 'webp'

/**
* What to do with mismatching videos on initialization.
* - `"createOnly"`: Create entries for videos that do not exist in the Payload collection.
* - `"deleteOnly"`: Delete entries for videos that no longer exist on Mux.
* - `"createAndDelete"`: Create entries for missing videos and delete entries for videos that no longer exist on Mux.
* - `"none"`: Do nothing on initialization.
*
* @default "none"
*/
onInitBehavior?: "createOnly" | "deleteOnly" | "createAndDelete" | "none"

/**
* An optional function to determine whether the current request is allowed to upload files.
* Should return a boolean or a Promise resolving to a boolean.
Expand Down