UNPKG

cloudinary-video-player

Version:
130 lines (124 loc) 4.14 kB
import './download-button.js'; import { g as getCloudinaryUrl, o as omit } from './index2.js'; import './_videojs-proxy.js'; import './_commonjsHelpers.js'; import './video-player.const.js'; import './cloudinary-config-from-options.js'; import './cloudinary-url-prefix.js'; const SharePlugin = function () { let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; let playerInstance = arguments.length > 1 ? arguments[1] : undefined; const player = playerInstance || this; player.addClass('vjs-share'); const addDownloadButton = () => { const controlBar = player.getChild('ControlBar'); if (!controlBar || controlBar.getChild('ShareDownloadButton')) { return; } const children = controlBar.children(); const insertBeforeIndex = children.findIndex(c => c.name_ === 'FullscreenToggle'); controlBar.addChild('ShareDownloadButton', {}, insertBeforeIndex !== -1 ? insertBeforeIndex : undefined); }; const removeDownloadButton = () => { if (!player.controlBar) { return; } const btn = player.controlBar.getChild('ShareDownloadButton'); if (btn) { player.controlBar.removeChild(btn); } }; const getDownloadUrl = () => { const source = player.currentSource?.(); if (!source) { return null; } // Strip format / codec related transformation arrays const STRIP_KEYS = ['format', 'video_codec', 'streaming_profile']; const stripKeysDeep = value => { if (Array.isArray(value)) { return value.map(stripKeysDeep); } if (value && typeof value === 'object') { const cleaned = omit(value, STRIP_KEYS); Object.keys(cleaned).forEach(k => { cleaned[k] = stripKeysDeep(cleaned[k]); }); return cleaned; } return value; }; const transformations = stripKeysDeep(player.cloudinary.transformation() || {}); const filename = player.cloudinary.currentPublicId()?.split('/')?.pop(); const baseOptions = { ...player.cloudinary.cloudinaryConfig(), ...transformations, resource_type: 'video', format: 'mp4', video_codec: 'h264', flags: `streaming_attachment:${filename}` }; // For ABR - download a limited-size video if (source.isAdaptive) { Object.assign(baseOptions, { crop: 'limit', width: 1920, height: 1920 }); } // For audio sources, set the format to mp3 if (player.cloudinary.source()?.getType() === 'AudioSource') { Object.assign(baseOptions, { format: 'mp3', video_codec: undefined }); } return getCloudinaryUrl(player.cloudinary.currentPublicId(), baseOptions); }; const download = () => { const url = getDownloadUrl(); if (!url) { console.warn('Share plugin: Unable to resolve download URL.'); return; } const MAX_ATTEMPTS = 60; // 60 tries / 10s interval const INTERVAL_MS = 10000; const RETRY_STATUS_CODES = [423]; const triggerDownload = () => { const a = document.createElement('a'); a.href = url; a.download = ''; document.body.appendChild(a); a.click(); document.body.removeChild(a); }; const btn = player.controlBar?.getChild('ShareDownloadButton'); const setPreparingState = isPreparing => { btn?.setPreparing?.(isPreparing); }; const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); const fetchDownload = async function () { let attempt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; const response = await fetch(url, { method: 'HEAD' }); if (RETRY_STATUS_CODES.includes(response.status) && attempt < MAX_ATTEMPTS) { await wait(INTERVAL_MS); return fetchDownload(attempt + 1); } setPreparingState(false); triggerDownload(); }; setPreparingState(true); fetchDownload(); }; if (options.download) { addDownloadButton(); } player.share = { download, addDownloadButton, removeDownloadButton }; }; export { SharePlugin as default };