sanity-plugin-mux-input 2.16.0 → 2.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +916 -78
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +916 -78
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/actions/upload.ts +47 -7
- package/src/components/AddCaptionDialog.tsx +28 -9
- package/src/components/DraggableWatermark.tsx +877 -0
- package/src/components/EditCaptionDialog.tsx +4 -2
- package/src/components/UploadConfiguration.tsx +259 -59
- package/src/components/Uploader.tsx +7 -1
- package/src/components/VideoPlayer.tsx +2 -0
- package/src/hooks/useMediaMetadata.ts +3 -0
- package/src/util/convertWatermarkToMux.ts +160 -0
- package/src/util/formatDriveShareLink.ts +64 -0
- package/src/util/roundPxString.ts +16 -0
- package/src/util/types.ts +43 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format Google Drive share links as Google Drive export links.
|
|
3
|
+
* Supported formats:
|
|
4
|
+
* - https://drive.google.com/uc?id=<ID>...
|
|
5
|
+
* - https://drive.google.com/open?id=<ID>...
|
|
6
|
+
* - https://drive.google.com/file/d/<ID>...
|
|
7
|
+
* - https://drive.google.com/folder/<ID>...
|
|
8
|
+
*
|
|
9
|
+
* @param url Google Drive share link to format.
|
|
10
|
+
* @returns Google Drive export link (URL passthrough if not share link).
|
|
11
|
+
*/
|
|
12
|
+
export function formatDriveShareLink(url: string): string {
|
|
13
|
+
// Export link formatter.
|
|
14
|
+
const formatExportLink = (id: string) => {
|
|
15
|
+
return `https://drive.google.com/uc?export=download&id=${id}`
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// URL formatting.
|
|
19
|
+
try {
|
|
20
|
+
// Parse URL.
|
|
21
|
+
const trimmed = url.trim()
|
|
22
|
+
const parsed = new URL(trimmed)
|
|
23
|
+
|
|
24
|
+
// Enforce strict host name.
|
|
25
|
+
if (parsed.hostname !== 'drive.google.com') {
|
|
26
|
+
throw new Error('URL is not from Google Drive.')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Look for ID in search parameters.
|
|
30
|
+
const id = parsed.searchParams.get('id') || ''
|
|
31
|
+
if (id.length) {
|
|
32
|
+
return formatExportLink(id)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Look for ID in path name.
|
|
36
|
+
const path = parsed.pathname.split('/') || []
|
|
37
|
+
|
|
38
|
+
// Path is /file/d/<ID>...
|
|
39
|
+
if (path.includes('file') && path.includes('d')) {
|
|
40
|
+
const index =
|
|
41
|
+
path.findIndex((value: string) => {
|
|
42
|
+
return value === 'd'
|
|
43
|
+
}) + 1
|
|
44
|
+
const fileId = path.at(index) || ''
|
|
45
|
+
return formatExportLink(fileId)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Path is /folder/<ID>...
|
|
49
|
+
if (path.includes('folders')) {
|
|
50
|
+
const index =
|
|
51
|
+
path.findIndex((value: string) => {
|
|
52
|
+
return value === 'folders'
|
|
53
|
+
}) + 1
|
|
54
|
+
const folderId = path.at(index) || ''
|
|
55
|
+
return formatExportLink(folderId)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// URL not recognized.
|
|
59
|
+
throw new Error('URL was not recognized.')
|
|
60
|
+
} catch {
|
|
61
|
+
// URL passthrough by default.
|
|
62
|
+
return url
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rounds the numeric part of a px string to the nearest integer.
|
|
3
|
+
* Returns undefined if the value is not a valid px string or not a finite number.
|
|
4
|
+
* Avoids sending 0px (and JS -0); snaps to ±1 instead.
|
|
5
|
+
*/
|
|
6
|
+
export function roundPxString(value: unknown): string | undefined {
|
|
7
|
+
if (typeof value !== 'string') return undefined
|
|
8
|
+
const trimmed = value.trim()
|
|
9
|
+
if (!trimmed.endsWith('px')) return undefined
|
|
10
|
+
const n = Number(trimmed.slice(0, -2))
|
|
11
|
+
if (!Number.isFinite(n)) return undefined
|
|
12
|
+
let rounded = Math.round(n)
|
|
13
|
+
// Avoid sending 0px (and JS -0); keep sign when negative.
|
|
14
|
+
if (rounded === 0) rounded = n < 0 ? -1 : 1
|
|
15
|
+
return `${rounded}px`
|
|
16
|
+
}
|
package/src/util/types.ts
CHANGED
|
@@ -274,12 +274,52 @@ export function isAutogeneratedTrack(
|
|
|
274
274
|
|
|
275
275
|
export type UploadTextTrack = AutogeneratedTextTrack | CustomTextTrack
|
|
276
276
|
|
|
277
|
+
/**
|
|
278
|
+
* Watermark configuration for UI (draggable position)
|
|
279
|
+
*/
|
|
280
|
+
export interface WatermarkConfig {
|
|
281
|
+
enabled: boolean
|
|
282
|
+
imageUrl?: string
|
|
283
|
+
/**
|
|
284
|
+
* Aspect ratio (width / height) of the watermark image.
|
|
285
|
+
* Used to convert between our center-based UI coords and Mux overlay margins.
|
|
286
|
+
*/
|
|
287
|
+
imageAspectRatio?: number
|
|
288
|
+
/**
|
|
289
|
+
* Optional explicit Mux `overlay_settings`.
|
|
290
|
+
* When set, these values should be used as-is for the upload request and preview.
|
|
291
|
+
* @see {@link https://www.mux.com/docs/guides/add-watermarks-to-your-videos}
|
|
292
|
+
*/
|
|
293
|
+
overlay_settings?: MuxOverlaySettings
|
|
294
|
+
position?: {
|
|
295
|
+
x: number // percentage (0-100)
|
|
296
|
+
y: number // percentage (0-100)
|
|
297
|
+
}
|
|
298
|
+
size?: number // percentage of video width (0-100)
|
|
299
|
+
opacity?: number // 0-1 (converted to percentage string for Mux API)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Mux overlay_settings format for watermark API
|
|
304
|
+
* @see {@link https://www.mux.com/docs/guides/add-watermarks-to-your-videos}
|
|
305
|
+
*/
|
|
306
|
+
export interface MuxOverlaySettings {
|
|
307
|
+
vertical_align: 'top' | 'middle' | 'bottom'
|
|
308
|
+
vertical_margin: string // percentage (e.g., "10%") or pixels (e.g., "40px")
|
|
309
|
+
horizontal_align: 'left' | 'center' | 'right'
|
|
310
|
+
horizontal_margin: string // percentage (e.g., "10%") or pixels (e.g., "40px")
|
|
311
|
+
width?: string // percentage (e.g., "25%") or pixels (e.g., "80px")
|
|
312
|
+
height?: string // percentage or pixels
|
|
313
|
+
opacity?: string // percentage string (e.g., "90%")
|
|
314
|
+
}
|
|
315
|
+
|
|
277
316
|
export interface UploadConfig
|
|
278
317
|
extends Pick<MuxInputConfig, 'max_resolution_tier' | 'normalize_audio' | 'video_quality'> {
|
|
279
318
|
static_renditions: StaticRenditionResolution[]
|
|
280
319
|
text_tracks: UploadTextTrack[]
|
|
281
320
|
signed_policy: boolean
|
|
282
321
|
public_policy: boolean
|
|
322
|
+
watermark?: WatermarkConfig
|
|
283
323
|
drm_policy: boolean
|
|
284
324
|
}
|
|
285
325
|
|
|
@@ -309,7 +349,7 @@ export interface MuxNewAssetSettings
|
|
|
309
349
|
/** The time offset in seconds from the beginning of the video indicating the clip's ending marker. */
|
|
310
350
|
end_time?: number
|
|
311
351
|
/** This parameter is required for text type tracks. */
|
|
312
|
-
type
|
|
352
|
+
type?: 'video' | 'audio' | 'text'
|
|
313
353
|
/** Type of text track. This parameter only supports subtitles value. */
|
|
314
354
|
text_type?: 'subtitles'
|
|
315
355
|
/** The language code value must be a valid BCP 47 specification compliant value. */
|
|
@@ -320,6 +360,8 @@ export interface MuxNewAssetSettings
|
|
|
320
360
|
closed_captions?: boolean
|
|
321
361
|
/** This optional parameter should be used tracks with type of text and text_type set to subtitles. */
|
|
322
362
|
passthrough?: string
|
|
363
|
+
/** Overlay settings for watermarks. Used when adding a watermark image as a second input. */
|
|
364
|
+
overlay_settings?: MuxOverlaySettings
|
|
323
365
|
}[]
|
|
324
366
|
|
|
325
367
|
/** An array of playback policy names that you want applied to this asset and available through playback_ids. */
|