import { r as resolve_wasm_src } from './file-url-a54881a3.js'; const ERROR_RESPONSE_BODY_READER = new Error("failed to get response body reader"); const ERROR_INCOMPLETED_DOWNLOAD = new Error("failed to complete download"); const HeaderContentLength = "Content-Length"; /** * Download content of a URL with progress. * * Progress only works when Content-Length is provided by the server. * */ const downloadWithProgress = async (url, cb) => { const resp = await fetch(url); let buf; try { // Set total to -1 to indicate that there is not Content-Type Header. const total = parseInt(resp.headers.get(HeaderContentLength) || "-1"); const reader = resp.body?.getReader(); if (!reader) throw ERROR_RESPONSE_BODY_READER; const chunks = []; let received = 0; for (;;) { const { done, value } = await reader.read(); const delta = value ? value.length : 0; if (done) { if (total != -1 && total !== received) throw ERROR_INCOMPLETED_DOWNLOAD; cb && cb({ url, total, received, delta, done }); break; } chunks.push(value); received += delta; cb && cb({ url, total, received, delta, done }); } const data = new Uint8Array(received); let position = 0; for (const chunk of chunks) { data.set(chunk, position); position += chunk.length; } buf = data.buffer; } catch (e) { console.log(`failed to send download progress event: `, e); // Fetch arrayBuffer directly when it is not possible to get progress. buf = await resp.arrayBuffer(); cb && cb({ url, total: buf.byteLength, received: buf.byteLength, delta: 0, done: true, }); } return buf; }; /** * toBlobURL fetches data from an URL and return a blob URL. * * Example: * * ```ts * await toBlobURL("http://localhost:3000/ffmpeg.js", "text/javascript"); * ``` */ const toBlobURL = async (url, mimeType, progress = false, cb) => { const buf = progress ? await downloadWithProgress(url, cb) : await (await fetch(url)).arrayBuffer(); const blob = new Blob([buf], { type: mimeType }); return URL.createObjectURL(blob); }; var FFMessageType; (function (FFMessageType) { FFMessageType["LOAD"] = "LOAD"; FFMessageType["EXEC"] = "EXEC"; FFMessageType["WRITE_FILE"] = "WRITE_FILE"; FFMessageType["READ_FILE"] = "READ_FILE"; FFMessageType["DELETE_FILE"] = "DELETE_FILE"; FFMessageType["RENAME"] = "RENAME"; FFMessageType["CREATE_DIR"] = "CREATE_DIR"; FFMessageType["LIST_DIR"] = "LIST_DIR"; FFMessageType["DELETE_DIR"] = "DELETE_DIR"; FFMessageType["ERROR"] = "ERROR"; FFMessageType["DOWNLOAD"] = "DOWNLOAD"; FFMessageType["PROGRESS"] = "PROGRESS"; FFMessageType["LOG"] = "LOG"; FFMessageType["MOUNT"] = "MOUNT"; FFMessageType["UNMOUNT"] = "UNMOUNT"; })(FFMessageType || (FFMessageType = {})); /** * Generate an unique message ID. */ const getMessageID = (() => { let messageID = 0; return () => messageID++; })(); const ERROR_NOT_LOADED = new Error("ffmpeg is not loaded, call `await ffmpeg.load()` first"); const ERROR_TERMINATED = new Error("called FFmpeg.terminate()"); /** * Provides APIs to interact with ffmpeg web worker. * * @example * ```ts * const ffmpeg = new FFmpeg(); * ``` */ class FFmpeg { #worker = null; /** * #resolves and #rejects tracks Promise resolves and rejects to * be called when we receive message from web worker. */ #resolves = {}; #rejects = {}; #logEventCallbacks = []; #progressEventCallbacks = []; loaded = false; /** * register worker message event handlers. */ #registerHandlers = () => { if (this.#worker) { this.#worker.onmessage = ({ data: { id, type, data }, }) => { switch (type) { case FFMessageType.LOAD: this.loaded = true; this.#resolves[id](data); break; case FFMessageType.MOUNT: case FFMessageType.UNMOUNT: case FFMessageType.EXEC: case FFMessageType.WRITE_FILE: case FFMessageType.READ_FILE: case FFMessageType.DELETE_FILE: case FFMessageType.RENAME: case FFMessageType.CREATE_DIR: case FFMessageType.LIST_DIR: case FFMessageType.DELETE_DIR: this.#resolves[id](data); break; case FFMessageType.LOG: this.#logEventCallbacks.forEach((f) => f(data)); break; case FFMessageType.PROGRESS: this.#progressEventCallbacks.forEach((f) => f(data)); break; case FFMessageType.ERROR: this.#rejects[id](data); break; } delete this.#resolves[id]; delete this.#rejects[id]; }; } }; /** * Generic function to send messages to web worker. */ #send = ({ type, data }, trans = [], signal) => { if (!this.#worker) { return Promise.reject(ERROR_NOT_LOADED); } return new Promise((resolve, reject) => { const id = getMessageID(); this.#worker && this.#worker.postMessage({ id, type, data }, trans); this.#resolves[id] = resolve; this.#rejects[id] = reject; signal?.addEventListener("abort", () => { reject(new DOMException(`Message # ${id} was aborted`, "AbortError")); }, { once: true }); }); }; on(event, callback) { if (event === "log") { this.#logEventCallbacks.push(callback); } else if (event === "progress") { this.#progressEventCallbacks.push(callback); } } off(event, callback) { if (event === "log") { this.#logEventCallbacks = this.#logEventCallbacks.filter((f) => f !== callback); } else if (event === "progress") { this.#progressEventCallbacks = this.#progressEventCallbacks.filter((f) => f !== callback); } } /** * Loads ffmpeg-core inside web worker. It is required to call this method first * as it initializes WebAssembly and other essential variables. * * @category FFmpeg * @returns `true` if ffmpeg core is loaded for the first time. */ load = (config = {}, { signal } = {}) => { if (!this.#worker) { this.#worker = new Worker(new URL(""+new URL('worker-6d6dd1a7.js', import.meta.url).href+"", self.location), { type: "module", }); this.#registerHandlers(); } return this.#send({ type: FFMessageType.LOAD, data: config, }, undefined, signal); }; /** * Execute ffmpeg command. * * @remarks * To avoid common I/O issues, ["-nostdin", "-y"] are prepended to the args * by default. * * @example * ```ts * const ffmpeg = new FFmpeg(); * await ffmpeg.load(); * await ffmpeg.writeFile("video.avi", ...); * // ffmpeg -i video.avi video.mp4 * await ffmpeg.exec(["-i", "video.avi", "video.mp4"]); * const data = ffmpeg.readFile("video.mp4"); * ``` * * @returns `0` if no error, `!= 0` if timeout (1) or error. * @category FFmpeg */ exec = ( /** ffmpeg command line args */ args, /** * milliseconds to wait before stopping the command execution. * * @defaultValue -1 */ timeout = -1, { signal } = {}) => this.#send({ type: FFMessageType.EXEC, data: { args, timeout }, }, undefined, signal); /** * Terminate all ongoing API calls and terminate web worker. * `FFmpeg.load()` must be called again before calling any other APIs. * * @category FFmpeg */ terminate = () => { const ids = Object.keys(this.#rejects); // rejects all incomplete Promises. for (const id of ids) { this.#rejects[id](ERROR_TERMINATED); delete this.#rejects[id]; delete this.#resolves[id]; } if (this.#worker) { this.#worker.terminate(); this.#worker = null; this.loaded = false; } }; /** * Write data to ffmpeg.wasm. * * @example * ```ts * const ffmpeg = new FFmpeg(); * await ffmpeg.load(); * await ffmpeg.writeFile("video.avi", await fetchFile("../video.avi")); * await ffmpeg.writeFile("text.txt", "hello world"); * ``` * * @category File System */ writeFile = (path, data, { signal } = {}) => { const trans = []; if (data instanceof Uint8Array) { trans.push(data.buffer); } return this.#send({ type: FFMessageType.WRITE_FILE, data: { path, data }, }, trans, signal); }; mount = (fsType, options, mountPoint) => { const trans = []; return this.#send({ type: FFMessageType.MOUNT, data: { fsType, options, mountPoint }, }, trans); }; unmount = (mountPoint) => { const trans = []; return this.#send({ type: FFMessageType.UNMOUNT, data: { mountPoint }, }, trans); }; /** * Read data from ffmpeg.wasm. * * @example * ```ts * const ffmpeg = new FFmpeg(); * await ffmpeg.load(); * const data = await ffmpeg.readFile("video.mp4"); * ``` * * @category File System */ readFile = (path, /** * File content encoding, supports two encodings: * - utf8: read file as text file, return data in string type. * - binary: read file as binary file, return data in Uint8Array type. * * @defaultValue binary */ encoding = "binary", { signal } = {}) => this.#send({ type: FFMessageType.READ_FILE, data: { path, encoding }, }, undefined, signal); /** * Delete a file. * * @category File System */ deleteFile = (path, { signal } = {}) => this.#send({ type: FFMessageType.DELETE_FILE, data: { path }, }, undefined, signal); /** * Rename a file or directory. * * @category File System */ rename = (oldPath, newPath, { signal } = {}) => this.#send({ type: FFMessageType.RENAME, data: { oldPath, newPath }, }, undefined, signal); /** * Create a directory. * * @category File System */ createDir = (path, { signal } = {}) => this.#send({ type: FFMessageType.CREATE_DIR, data: { path }, }, undefined, signal); /** * List directory contents. * * @category File System */ listDir = (path, { signal } = {}) => this.#send({ type: FFMessageType.LIST_DIR, data: { path }, }, undefined, signal); /** * Delete an empty directory. * * @category File System */ deleteDir = (path, { signal } = {}) => this.#send({ type: FFMessageType.DELETE_DIR, data: { path }, }, undefined, signal); } const mimes = { "3g2": "video/3gpp2", "3gp": "video/3gpp", "3gpp": "video/3gpp", "3mf": "model/3mf", "aac": "audio/aac", "ac": "application/pkix-attr-cert", "adp": "audio/adpcm", "adts": "audio/aac", "ai": "application/postscript", "aml": "application/automationml-aml+xml", "amlx": "application/automationml-amlx+zip", "amr": "audio/amr", "apng": "image/apng", "appcache": "text/cache-manifest", "appinstaller": "application/appinstaller", "appx": "application/appx", "appxbundle": "application/appxbundle", "asc": "application/pgp-keys", "atom": "application/atom+xml", "atomcat": "application/atomcat+xml", "atomdeleted": "application/atomdeleted+xml", "atomsvc": "application/atomsvc+xml", "au": "audio/basic", "avci": "image/avci", "avcs": "image/avcs", "avif": "image/avif", "aw": "application/applixware", "bdoc": "application/bdoc", "bin": "application/octet-stream", "bmp": "image/bmp", "bpk": "application/octet-stream", "btf": "image/prs.btif", "btif": "image/prs.btif", "buffer": "application/octet-stream", "ccxml": "application/ccxml+xml", "cdfx": "application/cdfx+xml", "cdmia": "application/cdmi-capability", "cdmic": "application/cdmi-container", "cdmid": "application/cdmi-domain", "cdmio": "application/cdmi-object", "cdmiq": "application/cdmi-queue", "cer": "application/pkix-cert", "cgm": "image/cgm", "cjs": "application/node", "class": "application/java-vm", "coffee": "text/coffeescript", "conf": "text/plain", "cpl": "application/cpl+xml", "cpt": "application/mac-compactpro", "crl": "application/pkix-crl", "css": "text/css", "csv": "text/csv", "cu": "application/cu-seeme", "cwl": "application/cwl", "cww": "application/prs.cww", "davmount": "application/davmount+xml", "dbk": "application/docbook+xml", "deb": "application/octet-stream", "def": "text/plain", "deploy": "application/octet-stream", "dib": "image/bmp", "disposition-notification": "message/disposition-notification", "dist": "application/octet-stream", "distz": "application/octet-stream", "dll": "application/octet-stream", "dmg": "application/octet-stream", "dms": "application/octet-stream", "doc": "application/msword", "dot": "application/msword", "dpx": "image/dpx", "drle": "image/dicom-rle", "dsc": "text/prs.lines.tag", "dssc": "application/dssc+der", "dtd": "application/xml-dtd", "dump": "application/octet-stream", "dwd": "application/atsc-dwd+xml", "ear": "application/java-archive", "ecma": "application/ecmascript", "elc": "application/octet-stream", "emf": "image/emf", "eml": "message/rfc822", "emma": "application/emma+xml", "emotionml": "application/emotionml+xml", "eps": "application/postscript", "epub": "application/epub+zip", "exe": "application/octet-stream", "exi": "application/exi", "exp": "application/express", "exr": "image/aces", "ez": "application/andrew-inset", "fdf": "application/fdf", "fdt": "application/fdt+xml", "fits": "image/fits", "g3": "image/g3fax", "gbr": "application/rpki-ghostbusters", "geojson": "application/geo+json", "gif": "image/gif", "glb": "model/gltf-binary", "gltf": "model/gltf+json", "gml": "application/gml+xml", "gpx": "application/gpx+xml", "gram": "application/srgs", "grxml": "application/srgs+xml", "gxf": "application/gxf", "gz": "application/gzip", "h261": "video/h261", "h263": "video/h263", "h264": "video/h264", "heic": "image/heic", "heics": "image/heic-sequence", "heif": "image/heif", "heifs": "image/heif-sequence", "hej2": "image/hej2k", "held": "application/atsc-held+xml", "hjson": "application/hjson", "hlp": "application/winhlp", "hqx": "application/mac-binhex40", "hsj2": "image/hsj2", "htm": "text/html", "html": "text/html", "ics": "text/calendar", "ief": "image/ief", "ifb": "text/calendar", "iges": "model/iges", "igs": "model/iges", "img": "application/octet-stream", "in": "text/plain", "ini": "text/plain", "ink": "application/inkml+xml", "inkml": "application/inkml+xml", "ipfix": "application/ipfix", "iso": "application/octet-stream", "its": "application/its+xml", "jade": "text/jade", "jar": "application/java-archive", "jhc": "image/jphc", "jls": "image/jls", "jp2": "image/jp2", "jpe": "image/jpeg", "jpeg": "image/jpeg", "jpf": "image/jpx", "jpg": "image/jpeg", "jpg2": "image/jp2", "jpgm": "image/jpm", "jpgv": "video/jpeg", "jph": "image/jph", "jpm": "image/jpm", "jpx": "image/jpx", "js": "text/javascript", "json": "application/json", "json5": "application/json5", "jsonld": "application/ld+json", "jsonml": "application/jsonml+json", "jsx": "text/jsx", "jt": "model/jt", "jxr": "image/jxr", "jxra": "image/jxra", "jxrs": "image/jxrs", "jxs": "image/jxs", "jxsc": "image/jxsc", "jxsi": "image/jxsi", "jxss": "image/jxss", "kar": "audio/midi", "ktx": "image/ktx", "ktx2": "image/ktx2", "less": "text/less", "lgr": "application/lgr+xml", "list": "text/plain", "litcoffee": "text/coffeescript", "log": "text/plain", "lostxml": "application/lost+xml", "lrf": "application/octet-stream", "m1v": "video/mpeg", "m21": "application/mp21", "m2a": "audio/mpeg", "m2v": "video/mpeg", "m3a": "audio/mpeg", "m4a": "audio/mp4", "m4p": "application/mp4", "m4s": "video/iso.segment", "ma": "application/mathematica", "mads": "application/mads+xml", "maei": "application/mmt-aei+xml", "man": "text/troff", "manifest": "text/cache-manifest", "map": "application/json", "mar": "application/octet-stream", "markdown": "text/markdown", "mathml": "application/mathml+xml", "mb": "application/mathematica", "mbox": "application/mbox", "md": "text/markdown", "mdx": "text/mdx", "me": "text/troff", "mesh": "model/mesh", "meta4": "application/metalink4+xml", "metalink": "application/metalink+xml", "mets": "application/mets+xml", "mft": "application/rpki-manifest", "mid": "audio/midi", "midi": "audio/midi", "mime": "message/rfc822", "mj2": "video/mj2", "mjp2": "video/mj2", "mjs": "text/javascript", "mml": "text/mathml", "mods": "application/mods+xml", "mov": "video/quicktime", "mp2": "audio/mpeg", "mp21": "application/mp21", "mp2a": "audio/mpeg", "mp3": "audio/mpeg", "mp4": "video/mp4", "mp4a": "audio/mp4", "mp4s": "application/mp4", "mp4v": "video/mp4", "mpd": "application/dash+xml", "mpe": "video/mpeg", "mpeg": "video/mpeg", "mpf": "application/media-policy-dataset+xml", "mpg": "video/mpeg", "mpg4": "video/mp4", "mpga": "audio/mpeg", "mpp": "application/dash-patch+xml", "mrc": "application/marc", "mrcx": "application/marcxml+xml", "ms": "text/troff", "mscml": "application/mediaservercontrol+xml", "msh": "model/mesh", "msi": "application/octet-stream", "msix": "application/msix", "msixbundle": "application/msixbundle", "msm": "application/octet-stream", "msp": "application/octet-stream", "mtl": "model/mtl", "musd": "application/mmt-usd+xml", "mxf": "application/mxf", "mxmf": "audio/mobile-xmf", "mxml": "application/xv+xml", "n3": "text/n3", "nb": "application/mathematica", "nq": "application/n-quads", "nt": "application/n-triples", "obj": "model/obj", "oda": "application/oda", "oga": "audio/ogg", "ogg": "audio/ogg", "ogv": "video/ogg", "ogx": "application/ogg", "omdoc": "application/omdoc+xml", "onepkg": "application/onenote", "onetmp": "application/onenote", "onetoc": "application/onenote", "onetoc2": "application/onenote", "opf": "application/oebps-package+xml", "opus": "audio/ogg", "otf": "font/otf", "owl": "application/rdf+xml", "oxps": "application/oxps", "p10": "application/pkcs10", "p7c": "application/pkcs7-mime", "p7m": "application/pkcs7-mime", "p7s": "application/pkcs7-signature", "p8": "application/pkcs8", "pdf": "application/pdf", "pfr": "application/font-tdpfr", "pgp": "application/pgp-encrypted", "pkg": "application/octet-stream", "pki": "application/pkixcmp", "pkipath": "application/pkix-pkipath", "pls": "application/pls+xml", "png": "image/png", "prc": "model/prc", "prf": "application/pics-rules", "provx": "application/provenance+xml", "ps": "application/postscript", "pskcxml": "application/pskc+xml", "pti": "image/prs.pti", "qt": "video/quicktime", "raml": "application/raml+yaml", "rapd": "application/route-apd+xml", "rdf": "application/rdf+xml", "relo": "application/p2p-overlay+xml", "rif": "application/reginfo+xml", "rl": "application/resource-lists+xml", "rld": "application/resource-lists-diff+xml", "rmi": "audio/midi", "rnc": "application/relax-ng-compact-syntax", "rng": "application/xml", "roa": "application/rpki-roa", "roff": "text/troff", "rq": "application/sparql-query", "rs": "application/rls-services+xml", "rsat": "application/atsc-rsat+xml", "rsd": "application/rsd+xml", "rsheet": "application/urc-ressheet+xml", "rss": "application/rss+xml", "rtf": "text/rtf", "rtx": "text/richtext", "rusd": "application/route-usd+xml", "s3m": "audio/s3m", "sbml": "application/sbml+xml", "scq": "application/scvp-cv-request", "scs": "application/scvp-cv-response", "sdp": "application/sdp", "senmlx": "application/senml+xml", "sensmlx": "application/sensml+xml", "ser": "application/java-serialized-object", "setpay": "application/set-payment-initiation", "setreg": "application/set-registration-initiation", "sgi": "image/sgi", "sgm": "text/sgml", "sgml": "text/sgml", "shex": "text/shex", "shf": "application/shf+xml", "shtml": "text/html", "sieve": "application/sieve", "sig": "application/pgp-signature", "sil": "audio/silk", "silo": "model/mesh", "siv": "application/sieve", "slim": "text/slim", "slm": "text/slim", "sls": "application/route-s-tsid+xml", "smi": "application/smil+xml", "smil": "application/smil+xml", "snd": "audio/basic", "so": "application/octet-stream", "spdx": "text/spdx", "spp": "application/scvp-vp-response", "spq": "application/scvp-vp-request", "spx": "audio/ogg", "sql": "application/sql", "sru": "application/sru+xml", "srx": "application/sparql-results+xml", "ssdl": "application/ssdl+xml", "ssml": "application/ssml+xml", "stk": "application/hyperstudio", "stl": "model/stl", "stpx": "model/step+xml", "stpxz": "model/step-xml+zip", "stpz": "model/step+zip", "styl": "text/stylus", "stylus": "text/stylus", "svg": "image/svg+xml", "svgz": "image/svg+xml", "swidtag": "application/swid+xml", "t": "text/troff", "t38": "image/t38", "td": "application/urc-targetdesc+xml", "tei": "application/tei+xml", "teicorpus": "application/tei+xml", "text": "text/plain", "tfi": "application/thraud+xml", "tfx": "image/tiff-fx", "tif": "image/tiff", "tiff": "image/tiff", "toml": "application/toml", "tr": "text/troff", "trig": "application/trig", "ts": "video/mp2t", "tsd": "application/timestamped-data", "tsv": "text/tab-separated-values", "ttc": "font/collection", "ttf": "font/ttf", "ttl": "text/turtle", "ttml": "application/ttml+xml", "txt": "text/plain", "u3d": "model/u3d", "u8dsn": "message/global-delivery-status", "u8hdr": "message/global-headers", "u8mdn": "message/global-disposition-notification", "u8msg": "message/global", "ubj": "application/ubjson", "uri": "text/uri-list", "uris": "text/uri-list", "urls": "text/uri-list", "vcard": "text/vcard", "vrml": "model/vrml", "vtt": "text/vtt", "vxml": "application/voicexml+xml", "war": "application/java-archive", "wasm": "application/wasm", "wav": "audio/wav", "weba": "audio/webm", "webm": "video/webm", "webmanifest": "application/manifest+json", "webp": "image/webp", "wgsl": "text/wgsl", "wgt": "application/widget", "wif": "application/watcherinfo+xml", "wmf": "image/wmf", "woff": "font/woff", "woff2": "font/woff2", "wrl": "model/vrml", "wsdl": "application/wsdl+xml", "wspolicy": "application/wspolicy+xml", "x3d": "model/x3d+xml", "x3db": "model/x3d+fastinfoset", "x3dbz": "model/x3d+binary", "x3dv": "model/x3d-vrml", "x3dvz": "model/x3d+vrml", "x3dz": "model/x3d+xml", "xaml": "application/xaml+xml", "xav": "application/xcap-att+xml", "xca": "application/xcap-caps+xml", "xcs": "application/calendar+xml", "xdf": "application/xcap-diff+xml", "xdssc": "application/dssc+xml", "xel": "application/xcap-el+xml", "xenc": "application/xenc+xml", "xer": "application/patch-ops-error+xml", "xfdf": "application/xfdf", "xht": "application/xhtml+xml", "xhtml": "application/xhtml+xml", "xhvml": "application/xv+xml", "xlf": "application/xliff+xml", "xm": "audio/xm", "xml": "text/xml", "xns": "application/xcap-ns+xml", "xop": "application/xop+xml", "xpl": "application/xproc+xml", "xsd": "application/xml", "xsf": "application/prs.xsf+xml", "xsl": "application/xml", "xslt": "application/xml", "xspf": "application/xspf+xml", "xvm": "application/xv+xml", "xvml": "application/xv+xml", "yaml": "text/yaml", "yang": "application/yang", "yin": "application/yin+xml", "yml": "text/yaml", "zip": "application/zip" }; function lookup(extn) { let tmp = ('' + extn).trim().toLowerCase(); let idx = tmp.lastIndexOf('.'); return mimes[!~idx ? tmp : tmp.substring(++idx)]; } const prettyBytes = (bytes) => { let units = ["B", "KB", "MB", "GB", "PB"]; let i = 0; while (bytes > 1024) { bytes /= 1024; i++; } let unit = units[i]; return bytes.toFixed(1) + " " + unit; }; const playable = () => { return true; }; function loaded(node, { autoplay }) { async function handle_playback() { if (!autoplay) return; await node.play(); } node.addEventListener("loadeddata", handle_playback); return { destroy() { node.removeEventListener("loadeddata", handle_playback); } }; } async function loadFfmpeg() { const ffmpeg = new FFmpeg(); const baseURL = "https://unpkg.com/@ffmpeg/core@0.12.4/dist/esm"; await ffmpeg.load({ coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, "text/javascript"), wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, "application/wasm") }); return ffmpeg; } async function trimVideo(ffmpeg, startTime, endTime, videoElement) { const videoUrl = videoElement.src; const mimeType = lookup(videoElement.src) || "video/mp4"; const blobUrl = await toBlobURL(videoUrl, mimeType); const response = await fetch(blobUrl); const vidBlob = await response.blob(); const type = getVideoExtensionFromMimeType(mimeType) || "mp4"; const inputName = `input.${type}`; const outputName = `output.${type}`; try { if (startTime === 0 && endTime === 0) { return vidBlob; } await ffmpeg.writeFile( inputName, new Uint8Array(await vidBlob.arrayBuffer()) ); let command = [ "-i", inputName, ...startTime !== 0 ? ["-ss", startTime.toString()] : [], ...endTime !== 0 ? ["-to", endTime.toString()] : [], "-c:a", "copy", outputName ]; await ffmpeg.exec(command); const outputData = await ffmpeg.readFile(outputName); const outputBlob = new Blob([outputData], { type: `video/${type}` }); return outputBlob; } catch (error) { console.error("Error initializing FFmpeg:", error); return vidBlob; } } const getVideoExtensionFromMimeType = (mimeType) => { const videoMimeToExtensionMap = { "video/mp4": "mp4", "video/webm": "webm", "video/ogg": "ogv", "video/quicktime": "mov", "video/x-msvideo": "avi", "video/x-matroska": "mkv", "video/mpeg": "mpeg", "video/3gpp": "3gp", "video/3gpp2": "3g2", "video/h261": "h261", "video/h263": "h263", "video/h264": "h264", "video/jpeg": "jpgv", "video/jpm": "jpm", "video/mj2": "mj2", "video/mpv": "mpv", "video/vnd.ms-playready.media.pyv": "pyv", "video/vnd.uvvu.mp4": "uvu", "video/vnd.vivo": "viv", "video/x-f4v": "f4v", "video/x-fli": "fli", "video/x-flv": "flv", "video/x-m4v": "m4v", "video/x-ms-asf": "asf", "video/x-ms-wm": "wm", "video/x-ms-wmv": "wmv", "video/x-ms-wmx": "wmx", "video/x-ms-wvx": "wvx", "video/x-sgi-movie": "movie", "video/x-smv": "smv" }; return videoMimeToExtensionMap[mimeType] || null; }; const Video_svelte_svelte_type_style_lang = ''; /* home/runner/work/gradio/gradio/js/video/shared/Video.svelte generated by Svelte v4.2.2 */ const { SvelteComponent: SvelteComponent$1, action_destroyer, add_render_callback, assign, attr: attr$1, binding_callbacks: binding_callbacks$1, create_slot, detach: detach$1, element: element$1, exclude_internal_props, get_all_dirty_from_scope, get_slot_changes, init, insert: insert$1, is_function: is_function$1, listen, raf, run_all, safe_not_equal: safe_not_equal$1, space, src_url_equal, toggle_class: toggle_class$1, transition_in: transition_in$1, transition_out: transition_out$1, update_slot_base } = window.__gradio__svelte__internal; const { createEventDispatcher } = window.__gradio__svelte__internal; function create_fragment$1(ctx) { let div; let t; let video; let video_src_value; let video_data_testid_value; let video_updating = false; let video_animationframe; let video_is_paused = true; let loaded_action; let current; let mounted; let dispose; const default_slot_template = /*#slots*/ ctx[16].default; const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[15], null); function video_timeupdate_handler() { cancelAnimationFrame(video_animationframe); if (!video.paused) { video_animationframe = raf(video_timeupdate_handler); video_updating = true; } /*video_timeupdate_handler*/ ctx[17].call(video); } return { c() { div = element$1("div"); div.innerHTML = ``; t = space(); video = element$1("video"); if (default_slot) default_slot.c(); attr$1(div, "class", "overlay svelte-1y0s5gv"); toggle_class$1(div, "hidden", !/*processingVideo*/ ctx[9]); if (!src_url_equal(video.src, video_src_value = /*resolved_src*/ ctx[10])) attr$1(video, "src", video_src_value); video.muted = /*muted*/ ctx[4]; video.playsInline = /*playsinline*/ ctx[5]; attr$1(video, "preload", /*preload*/ ctx[6]); video.autoplay = /*autoplay*/ ctx[7]; video.controls = /*controls*/ ctx[8]; attr$1(video, "data-testid", video_data_testid_value = /*$$props*/ ctx[12]["data-testid"]); attr$1(video, "crossorigin", "anonymous"); if (/*duration*/ ctx[1] === void 0) add_render_callback(() => /*video_durationchange_handler*/ ctx[18].call(video)); }, m(target, anchor) { insert$1(target, div, anchor); insert$1(target, t, anchor); insert$1(target, video, anchor); if (default_slot) { default_slot.m(video, null); } /*video_binding*/ ctx[20](video); current = true; if (!mounted) { dispose = [ listen(video, "loadeddata", /*dispatch*/ ctx[11].bind(null, "loadeddata")), listen(video, "click", /*dispatch*/ ctx[11].bind(null, "click")), listen(video, "play", /*dispatch*/ ctx[11].bind(null, "play")), listen(video, "pause", /*dispatch*/ ctx[11].bind(null, "pause")), listen(video, "ended", /*dispatch*/ ctx[11].bind(null, "ended")), listen(video, "mouseover", /*dispatch*/ ctx[11].bind(null, "mouseover")), listen(video, "mouseout", /*dispatch*/ ctx[11].bind(null, "mouseout")), listen(video, "focus", /*dispatch*/ ctx[11].bind(null, "focus")), listen(video, "blur", /*dispatch*/ ctx[11].bind(null, "blur")), listen(video, "timeupdate", video_timeupdate_handler), listen(video, "durationchange", /*video_durationchange_handler*/ ctx[18]), listen(video, "play", /*video_play_pause_handler*/ ctx[19]), listen(video, "pause", /*video_play_pause_handler*/ ctx[19]), action_destroyer(loaded_action = loaded.call(null, video, { autoplay: /*autoplay*/ ctx[7] ?? false })) ]; mounted = true; } }, p(ctx, [dirty]) { if (!current || dirty & /*processingVideo*/ 512) { toggle_class$1(div, "hidden", !/*processingVideo*/ ctx[9]); } if (default_slot) { if (default_slot.p && (!current || dirty & /*$$scope*/ 32768)) { update_slot_base( default_slot, default_slot_template, ctx, /*$$scope*/ ctx[15], !current ? get_all_dirty_from_scope(/*$$scope*/ ctx[15]) : get_slot_changes(default_slot_template, /*$$scope*/ ctx[15], dirty, null), null ); } } if (!current || dirty & /*resolved_src*/ 1024 && !src_url_equal(video.src, video_src_value = /*resolved_src*/ ctx[10])) { attr$1(video, "src", video_src_value); } if (!current || dirty & /*muted*/ 16) { video.muted = /*muted*/ ctx[4]; } if (!current || dirty & /*playsinline*/ 32) { video.playsInline = /*playsinline*/ ctx[5]; } if (!current || dirty & /*preload*/ 64) { attr$1(video, "preload", /*preload*/ ctx[6]); } if (!current || dirty & /*autoplay*/ 128) { video.autoplay = /*autoplay*/ ctx[7]; } if (!current || dirty & /*controls*/ 256) { video.controls = /*controls*/ ctx[8]; } if (!current || dirty & /*$$props*/ 4096 && video_data_testid_value !== (video_data_testid_value = /*$$props*/ ctx[12]["data-testid"])) { attr$1(video, "data-testid", video_data_testid_value); } if (!video_updating && dirty & /*currentTime*/ 1 && !isNaN(/*currentTime*/ ctx[0])) { video.currentTime = /*currentTime*/ ctx[0]; } video_updating = false; if (dirty & /*paused*/ 4 && video_is_paused !== (video_is_paused = /*paused*/ ctx[2])) { video[video_is_paused ? "pause" : "play"](); } if (loaded_action && is_function$1(loaded_action.update) && dirty & /*autoplay*/ 128) loaded_action.update.call(null, { autoplay: /*autoplay*/ ctx[7] ?? false }); }, i(local) { if (current) return; transition_in$1(default_slot, local); current = true; }, o(local) { transition_out$1(default_slot, local); current = false; }, d(detaching) { if (detaching) { detach$1(div); detach$1(t); detach$1(video); } if (default_slot) default_slot.d(detaching); /*video_binding*/ ctx[20](null); mounted = false; run_all(dispose); } }; } function instance$1($$self, $$props, $$invalidate) { let { $$slots: slots = {}, $$scope } = $$props; let { src = undefined } = $$props; let { muted = undefined } = $$props; let { playsinline = undefined } = $$props; let { preload = undefined } = $$props; let { autoplay = undefined } = $$props; let { controls = undefined } = $$props; let { currentTime = undefined } = $$props; let { duration = undefined } = $$props; let { paused = undefined } = $$props; let { node = undefined } = $$props; let { processingVideo = false } = $$props; const dispatch = createEventDispatcher(); let resolved_src; // The `src` prop can be updated before the Promise from `resolve_wasm_src` is resolved. // In such a case, the resolved value for the old `src` has to be discarded, // This variable `latest_src` is used to pick up only the value resolved for the latest `src` prop. let latest_src; function video_timeupdate_handler() { currentTime = this.currentTime; $$invalidate(0, currentTime); } function video_durationchange_handler() { duration = this.duration; $$invalidate(1, duration); } function video_play_pause_handler() { paused = this.paused; $$invalidate(2, paused); } function video_binding($$value) { binding_callbacks$1[$$value ? 'unshift' : 'push'](() => { node = $$value; $$invalidate(3, node); }); } $$self.$$set = $$new_props => { $$invalidate(12, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props))); if ('src' in $$new_props) $$invalidate(13, src = $$new_props.src); if ('muted' in $$new_props) $$invalidate(4, muted = $$new_props.muted); if ('playsinline' in $$new_props) $$invalidate(5, playsinline = $$new_props.playsinline); if ('preload' in $$new_props) $$invalidate(6, preload = $$new_props.preload); if ('autoplay' in $$new_props) $$invalidate(7, autoplay = $$new_props.autoplay); if ('controls' in $$new_props) $$invalidate(8, controls = $$new_props.controls); if ('currentTime' in $$new_props) $$invalidate(0, currentTime = $$new_props.currentTime); if ('duration' in $$new_props) $$invalidate(1, duration = $$new_props.duration); if ('paused' in $$new_props) $$invalidate(2, paused = $$new_props.paused); if ('node' in $$new_props) $$invalidate(3, node = $$new_props.node); if ('processingVideo' in $$new_props) $$invalidate(9, processingVideo = $$new_props.processingVideo); if ('$$scope' in $$new_props) $$invalidate(15, $$scope = $$new_props.$$scope); }; $$self.$$.update = () => { if ($$self.$$.dirty & /*src, latest_src*/ 24576) { { // In normal (non-Wasm) Gradio, the `` element should be rendered with the passed `src` props immediately // without waiting for `resolve_wasm_src()` to resolve. // If it waits, a black image is displayed until the async task finishes // and it leads to undesirable flickering. // So set `src` to `resolved_src` here. $$invalidate(10, resolved_src = src); $$invalidate(14, latest_src = src); const resolving_src = src; resolve_wasm_src(resolving_src).then(s => { if (latest_src === resolving_src) { $$invalidate(10, resolved_src = s); } }); } } }; $$props = exclude_internal_props($$props); return [ currentTime, duration, paused, node, muted, playsinline, preload, autoplay, controls, processingVideo, resolved_src, dispatch, $$props, src, latest_src, $$scope, slots, video_timeupdate_handler, video_durationchange_handler, video_play_pause_handler, video_binding ]; } class Video extends SvelteComponent$1 { constructor(options) { super(); init(this, options, instance$1, create_fragment$1, safe_not_equal$1, { src: 13, muted: 4, playsinline: 5, preload: 6, autoplay: 7, controls: 8, currentTime: 0, duration: 1, paused: 2, node: 3, processingVideo: 9 }); } } const Example_svelte_svelte_type_style_lang = ''; /* home/runner/work/gradio/gradio/js/video/Example.svelte generated by Svelte v4.2.2 */ const { SvelteComponent, add_flush_callback, append, attr, bind, binding_callbacks, create_component, destroy_component, detach, element, empty, init: init_1, insert, is_function, mount_component, noop, safe_not_equal, set_data, text, toggle_class, transition_in, transition_out } = window.__gradio__svelte__internal; function create_else_block(ctx) { let div; let t; return { c() { div = element("div"); t = text(/*value*/ ctx[2]); }, m(target, anchor) { insert(target, div, anchor); append(div, t); }, p(ctx, dirty) { if (dirty & /*value*/ 4) set_data(t, /*value*/ ctx[2]); }, i: noop, o: noop, d(detaching) { if (detaching) { detach(div); } } }; } // (18:0) {#if playable()} function create_if_block(ctx) { let div; let video_1; let updating_node; let current; function video_1_node_binding(value) { /*video_1_node_binding*/ ctx[6](value); } let video_1_props = { muted: true, playsinline: true, src: /*samples_dir*/ ctx[3] + /*value*/ ctx[2] }; if (/*video*/ ctx[4] !== void 0) { video_1_props.node = /*video*/ ctx[4]; } video_1 = new Video({ props: video_1_props }); binding_callbacks.push(() => bind(video_1, 'node', video_1_node_binding)); video_1.$on("loadeddata", /*init*/ ctx[5]); video_1.$on("mouseover", function () { if (is_function(/*video*/ ctx[4].play.bind(/*video*/ ctx[4]))) /*video*/ ctx[4].play.bind(/*video*/ ctx[4]).apply(this, arguments); }); video_1.$on("mouseout", function () { if (is_function(/*video*/ ctx[4].pause.bind(/*video*/ ctx[4]))) /*video*/ ctx[4].pause.bind(/*video*/ ctx[4]).apply(this, arguments); }); return { c() { div = element("div"); create_component(video_1.$$.fragment); attr(div, "class", "container svelte-1de9zxs"); toggle_class(div, "table", /*type*/ ctx[0] === "table"); toggle_class(div, "gallery", /*type*/ ctx[0] === "gallery"); toggle_class(div, "selected", /*selected*/ ctx[1]); }, m(target, anchor) { insert(target, div, anchor); mount_component(video_1, div, null); current = true; }, p(new_ctx, dirty) { ctx = new_ctx; const video_1_changes = {}; if (dirty & /*samples_dir, value*/ 12) video_1_changes.src = /*samples_dir*/ ctx[3] + /*value*/ ctx[2]; if (!updating_node && dirty & /*video*/ 16) { updating_node = true; video_1_changes.node = /*video*/ ctx[4]; add_flush_callback(() => updating_node = false); } video_1.$set(video_1_changes); if (!current || dirty & /*type*/ 1) { toggle_class(div, "table", /*type*/ ctx[0] === "table"); } if (!current || dirty & /*type*/ 1) { toggle_class(div, "gallery", /*type*/ ctx[0] === "gallery"); } if (!current || dirty & /*selected*/ 2) { toggle_class(div, "selected", /*selected*/ ctx[1]); } }, i(local) { if (current) return; transition_in(video_1.$$.fragment, local); current = true; }, o(local) { transition_out(video_1.$$.fragment, local); current = false; }, d(detaching) { if (detaching) { detach(div); } destroy_component(video_1); } }; } function create_fragment(ctx) { let current_block_type_index; let if_block; let if_block_anchor; let current; const if_block_creators = [create_if_block, create_else_block]; const if_blocks = []; function select_block_type(ctx, dirty) { return 0; } current_block_type_index = select_block_type(); if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); return { c() { if_block.c(); if_block_anchor = empty(); }, m(target, anchor) { if_blocks[current_block_type_index].m(target, anchor); insert(target, if_block_anchor, anchor); current = true; }, p(ctx, [dirty]) { if_block.p(ctx, dirty); }, i(local) { if (current) return; transition_in(if_block); current = true; }, o(local) { transition_out(if_block); current = false; }, d(detaching) { if (detaching) { detach(if_block_anchor); } if_blocks[current_block_type_index].d(detaching); } }; } function instance($$self, $$props, $$invalidate) { let { type } = $$props; let { selected = false } = $$props; let { value } = $$props; let { samples_dir } = $$props; let video; async function init() { $$invalidate(4, video.muted = true, video); $$invalidate(4, video.playsInline = true, video); $$invalidate(4, video.controls = false, video); video.setAttribute("muted", ""); await video.play(); video.pause(); } function video_1_node_binding(value) { video = value; $$invalidate(4, video); } $$self.$$set = $$props => { if ('type' in $$props) $$invalidate(0, type = $$props.type); if ('selected' in $$props) $$invalidate(1, selected = $$props.selected); if ('value' in $$props) $$invalidate(2, value = $$props.value); if ('samples_dir' in $$props) $$invalidate(3, samples_dir = $$props.samples_dir); }; return [type, selected, value, samples_dir, video, init, video_1_node_binding]; } class Example extends SvelteComponent { constructor(options) { super(); init_1(this, options, instance, create_fragment, safe_not_equal, { type: 0, selected: 1, value: 2, samples_dir: 3 }); } } const Example$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ __proto__: null, default: Example }, Symbol.toStringTag, { value: 'Module' })); export { Example as E, Video as V, playable as a, loaded as b, Example$1 as c, loadFfmpeg as l, prettyBytes as p, trimVideo as t }; //# sourceMappingURL=Example-40880a3c.js.map