@mux/blurup
Advanced tools
Comparing version 0.2.3 to 1.0.0
@@ -1,2 +0,2 @@ | ||
import { imageDimensionsFromData } from 'image-dimensions'; | ||
import { imageDimensionsFromStream } from 'image-dimensions'; | ||
@@ -37,6 +37,7 @@ const defaultOptions = { | ||
if (quality >= 1) { | ||
imageURL.searchParams.set('width', 16 * quality); | ||
imageURL.searchParams.set('height', 16 * quality); | ||
if (isNaN(quality) || quality < 1) { | ||
throw new Error('[@mux/blurup] Quality must be greater or equal to 1'); | ||
} | ||
imageURL.searchParams.set('width', 16 * quality); | ||
imageURL.searchParams.set('height', 16 * quality); | ||
@@ -53,24 +54,9 @@ time = parseFloat(time); | ||
const response = await fetch(imageURL, { headers: { Accept: `image/${type}` } }); | ||
const fetchOptions = { headers: { Accept: `image/${type}` } }; | ||
if (response.status === 403) { | ||
if (typeof options.thumbnailToken !== 'undefined') { | ||
throw new Error( | ||
`[@mux/blurup] Error fetching thumbnail. 403: Forbidden. The thumbnailToken option may be invalid. See https://docs.mux.com/guides/video/secure-video-playback for more information.` | ||
); | ||
} else { | ||
throw new Error( | ||
`[@mux/blurup] Error fetching thumbnail. 403: Forbidden. This Playback ID may require a thumbnail token. See https://docs.mux.com/guides/video/secure-video-playback for more information.` | ||
); | ||
} | ||
} else if (response.status >= 400) { | ||
throw new Error( | ||
`[@mux/blurhash] Error fetching thumbnail. ${response.status}: ${response.statusText}` | ||
); | ||
} | ||
const [{ width, height }, imageDataURL] = await Promise.all([ | ||
getSourceImageDimensions(new URL(imageURL), fetchOptions), | ||
getTinyImageDataURL(new URL(imageURL), fetchOptions), | ||
]); | ||
const arrayBuffer = await response.arrayBuffer(); | ||
const base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer))); | ||
const imageDataURL = `data:${response.headers.get('content-type')};base64,${base64String}`; | ||
const { width, height } = imageDimensionsFromData(arrayBuffer); | ||
const aspectRatio = width / height; | ||
@@ -92,4 +78,42 @@ const blurDataURL = | ||
async function getSourceImageDimensions(imageURL, fetchOptions) { | ||
// we also want to fetch the full-size source image from mux, | ||
// so that we can measure its width and height | ||
imageURL.searchParams.delete('width'); | ||
imageURL.searchParams.delete('height'); | ||
const response = await fetch(imageURL, fetchOptions); | ||
validateResponse(imageURL, response); | ||
return imageDimensionsFromStream(response.body); | ||
} | ||
async function getTinyImageDataURL(imageURL, fetchOptions) { | ||
const response = await fetch(imageURL, fetchOptions); | ||
validateResponse(imageURL, response); | ||
const arrayBuffer = await response.arrayBuffer(); | ||
const base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer))); | ||
return `data:${response.headers.get('content-type')};base64,${base64String}`; | ||
} | ||
function validateResponse(imageURL, response) { | ||
if (response.status === 403) { | ||
if (imageURL.searchParams.has('token')) { | ||
throw new Error( | ||
`[@mux/blurup] Error fetching thumbnail. 403: Forbidden. The thumbnailToken option may be invalid. See https://docs.mux.com/guides/video/secure-video-playback for more information.` | ||
); | ||
} else { | ||
throw new Error( | ||
`[@mux/blurup] Error fetching thumbnail. 403: Forbidden. This Playback ID may require a thumbnail token. See https://docs.mux.com/guides/video/secure-video-playback for more information.` | ||
); | ||
} | ||
} else if (response.status >= 400) { | ||
throw new Error( | ||
`[@mux/blurhash] Error fetching thumbnail. ${response.status}: ${response.statusText}` | ||
); | ||
} | ||
} | ||
function svgBlurImage(tinyImageDataURL, width, height, stdDeviation) { | ||
const svg = /*html*/`<svg xmlns="http://www.w3.org/2000/svg" ${width ? `width="${width}"` : ''} ${height ? `height="${height}"` : ''}><filter id="b" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="${stdDeviation}"/><feComponentTransfer><feFuncA type="discrete" tableValues="1 1"/></feComponentTransfer></filter><g filter="url(#b)"><image width="100%" height="100%" preserveAspectRatio="xMidYMid slice" href="${tinyImageDataURL}"/></g></svg>`; | ||
const svg = /*html*/ `<svg xmlns="http://www.w3.org/2000/svg" ${width ? `width="${width}"` : ''} ${height ? `height="${height}"` : ''}><filter id="b" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="${stdDeviation}"/><feComponentTransfer><feFuncA type="discrete" tableValues="1 1"/></feComponentTransfer></filter><g filter="url(#b)"><image width="100%" height="100%" preserveAspectRatio="xMidYMid slice" href="${tinyImageDataURL}"/></g></svg>`; | ||
return svg.replace(/#/g, '%23'); | ||
@@ -96,0 +120,0 @@ } |
{ | ||
"name": "@mux/blurup", | ||
"version": "0.2.3", | ||
"version": "1.0.0", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "description": "Generate a blurry image placeholder for a Mux video.", |
@@ -39,3 +39,3 @@ # @mux/blurup | ||
| blur | `number` | Standard deviation of the Gaussian blur. | `20` | | ||
| quality | `number` | Quality of the output image. Increase this value to see more details but also increase the length of the data URL. | `1` | | ||
| quality | `number` | Quality of the output image. Increase this value to see more details but also increase the length of the data. Set a quality greater than or equal to 1. URL. | `1` | | ||
| thumbnailToken | `string` | Videos with playback restrictions may require a thumbnail token. See https://docs.mux.com/guides/video/secure-video-playback for details. | `undefined` | | ||
@@ -42,0 +42,0 @@ | type | `webp` `png` `jpg` | Image type to use in the output blurry image placeholder. | `webp` | |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
10040
119
0
2