# TRANSFORMER — Documentation > Versión en español: [README.md](README.md) ## General ### What TRANSFORMER does TRANSFORMER is a multi-purpose file transformation tool: **image conversion** (between WEBP, AVIF, JPG and PNG, and to ICO and TIFF), **video conversion** (between MP4, WebM, animated GIF and animated WebP, and joining several into one), **audio conversion** (between MP3, AAC, Opus, WebM/Opus, OGG, FLAC and WAV, and concatenating or mixing several), **data transformation** (HTML<->MD, HTML->text, JSON<->CSV, JSON<->YAML, XML<->JSON, XLSX/ODS spreadsheets<->CSV/JSON, DOCX, beautify, minify and text from images via OCR), **PDF operations** (a page editor to rotate, delete and duplicate; merge, split/extract, convert to images and compress) and **batch renaming** with masks and variables. All the functions work on the same file queue: you load once and pick the corresponding tab in the right-hand column (**Image**, **Video**, **Audio**, **Data**, **PDF** or **Rename**). ### Privacy All processing (loading, conversion, scaling, renaming, ZIP/PDF generation and metadata editing) happens **entirely on your device**, inside the browser. **No file or private data is uploaded, shared or stored** on external servers: the files never leave your device. All the libraries (WASM codecs, FFmpeg engine, data utilities) are served from the site itself; only if a local file failed would it be downloaded from its official CDN with an integrity check (SRI). After the first load everything stays cached and the work is completely local. On your device, TRANSFORMER stores in the browser's **local storage** the **session** (the list of loaded files, to restore it when you come back), the **conversion history** (original and output file names), the **user presets**, the **recipes**, the **tab settings** for conversion, the **preferences** and, if you use them, the Real-ESRGAN **upscale models**, the **background removal models** and the **OCR engine** with its languages. The [Settings](#settings) window shows how much each one takes up and lets you clear it separately or reset it all. None of it leaves your device. ### Installation and offline use TRANSFORMER is an installable app (PWA). When the browser allows it, a banner appears with the **Install** button and the **Install** link in the footer; once installed, it opens in its own window, without the browser bars. After the first visit, the app and its engines (WASM codecs and FFmpeg) are stored in the cache, so you can keep working **without an internet connection**. Next to the Convert button, the _offline_ indicator appears when there is no network. If a new version is published while the app is open, a banner is shown to refresh and update. ### Remembered settings The control values of each tab (Image, Video, Audio, Data and PDF) are remembered between sessions in this browser. The first control of Data and PDF is **Operation**; the second (**Settings** in Data, **Type** in PDF) picks the variant of that operation. The **Operation** selector filters its options by the formats present in the queue: only the operations that apply to what is loaded appear. The last entry, **Show all**, reveals the full catalogue (and becomes **Show only applicable** to go back); if the queue does not match any operation, the full catalogue is shown directly. If the queue changes and the active operation no longer applies, the selector adjusts itself to the first one that does apply. Click its label to **reset** the tab's default values. If you edit a control with a variant applied, the selector switches to "Custom", as always. ### Settings The **gear** icon in the header, next to My presets, My recipes and Conversion history, opens the **Settings** window. Changes are saved immediately in this browser. **Remember between visits.** Three switches, enabled by default: **Remember the session** (the loaded files), **Save the conversion history** and **Remember the tab settings**. Switching one off offers to delete what has already been saved of that type; once off, the app stops saving it (with the history off, the History modal still shows the current session's conversions, with a notice). **Session.** TRANSFORMER remembers the list of loaded files so it can be restored if you close the tab or the browser. - **When opening with a saved session**: **Ask** (by default; a notice appears at the bottom with Restore and Discard, which hides on its own after 10 seconds), **Restore it** without asking or **Discard it** without asking. - **Space to save files**: 50 MB, 200 MB (by default), 500 MB or 1 GB. This is the cap on the content of the saved files; those that do not fit are remembered by name only and come back as a placeholder, without content. Lowering the cap does not delete what is already saved: it only leaves out new files that do not fit. **History.** **Maximum entries**: 100, 500 (by default) or 2000. Once the maximum is reached, the oldest ones are discarded. If you lower it below the number already there, confirmation is asked before deleting the excess. **Output.** **ZIP name**: optional mask with `%date%` (date), `%time%` (time) and `%n%` (counter); empty uses the classic name `transformer_YYMMDD`. **After converting**: do nothing (by default) or download automatically (with one output, the file; with several, the ZIP; in a guided flow, only on the last step). **Pause between downloads** (0, 250 by default, 500 ms or 1 s) and **Suggest ZIP from** (5, 10, 20 or 50 files). **Output metadata**: **Clean** (by default; the output does not keep the original's EXIF), **Copy from the original without GPS** or **Copy all**. It only applies to JPEG, PNG and WebP, the same in the individual download, the ZIPs and Sharing; the manual per-file metadata editing (including “Delete metadata”) always takes precedence. **Interaction.** **Preview on hover** (mouse; the keyboard and clicking still open the panel), **Panel speed** (fast, normal or slow), **When loading files** (select them —by default—, do not select them or select only the new ones), **Ask for confirmation when deleting** and **Step-by-step guided flows** (disabled, each flow runs all the steps in sequence with the current settings). **Performance.** **Warn if more than** a given memory usage is expected (automatic based on the device —by default—, 1, 2 or 4 GB, or do not warn; it also applies to large PDFs), **Files at a time when loading** (automatic, 2, 4 or 8) and **Estimate the output size** (enabled by default). **Data in this browser.** How much space the site uses in total (including the copy of the app for offline use) and, separately, the saved session, the history, the user presets, the recipes, the tab settings, this window's preferences, the downloaded upscale and background removal models and the OCR engine with its languages. Each row has its **Clear** or **Reset** button, with confirmation. Clearing the models means they must be downloaded again (about 105 MB) the next time you use Real-ESRGAN (the background removal ones, 4.6 MB the fast one and 178 MB the quality one); clearing the OCR engine means downloading it again (up to about 9 MB) the next time you recognise text. **Export and import configuration.** The footer of the window lets you download a JSON file with the tab settings, the user presets, the recipes and the preferences, and apply it again in another browser or device. When importing, it shows which blocks the file contains and lets you choose which to apply; the history and the session are not included. **Reset everything** clears all of the above at once and reloads the page, with the app as freshly installed. The list of files loaded at that moment is also emptied; your original files are not touched. The copy of the app for offline use is kept. ### Loading files - **Drag and drop** files onto the left area. - **Click** the upload area to open the file picker. - **Ctrl+V** at any time to paste an image from the clipboard (screenshots, images copied from other apps). - **URL** -- click the URL link under the upload area, paste the address of a file (http/https) and click Load: it is downloaded in the browser and enters the queue. It only works with servers that allow downloading from other websites (CORS); if the server blocks it, a warning is shown (the browser extension, if you use it, can get around that limitation). Supported image formats: `PNG JPG WEBP AVIF HEIC GIF BMP SVG ICO` Supported video formats: `MP4 WebM MOV MKV` Supported audio formats: `MP3 WAV AAC M4A OGG Opus FLAC` Supported data formats: `HTML HTM MD JSON CSV TSV YAML YML XML DOCX XLSX XLS ODS CSS JS` Supported document format: `PDF` (page operations, not conversion) You can mix images, videos, audio and data files in the same queue: each file is processed with the active tab at the moment you click **Convert**, according to its type (image, video, audio or data). ### Preview, Properties and Metadata panel The left panel (the upload area) also acts as an **ephemeral window** for preview, properties and metadata. When the cursor passes over the **eye**, **information** or **tag** icon of any file -- whether from the input list or the output list -- the panel becomes that view and a second tab, in italics, appears next to “Input”. When the cursor moves away it closes on its own after a moment. While something is being viewed, the **source icon and its file name are highlighted** in the list, so you always know which row what you are looking at comes from. A **click** on those same icons makes the view **fixed**: the tab becomes round and the panel accepts the mouse, so you can scroll the properties or metadata list, click “Analyse” or use the video and audio playback controls. A **second click** on that same icon takes the next step: it opens the large window -- the full-screen viewer, the Properties modal or the Metadata editor -- and removes the panel. The fixed view is closed with **Escape**, the cross, clicking outside the panel or dragging files over it (the upload area always has priority). Once fixed, the panel header offers: - **Previous / Next** (up and down arrows) -- moves through the files without leaving the view: if you are viewing the metadata, you keep seeing the next file's metadata. It only stops on the rows that have that icon, and the arrows grey out at the ends of the list. - **Input / Output** (left or right arrow) -- jumps to the equivalent file in the other column, also without changing the view. It greys out when that file has not been converted yet. - **Expand** -- opens the file in the usual full-screen viewer; in the Metadata view, the same button opens the **editor**. It does the same as the second click on the list icon. The panel occupies exactly the box it already had, so the page never jumps: if the content does not fit, it scrolls inside the panel itself. On narrow screens (less than 700 px) and on devices without a mouse there is no hover: there the icons still open, with a tap, the full-screen viewer, the Properties modal and the Metadata editor. ### Global action buttons - **Convert** -- starts or cancels the conversion of all the loaded files according to the active tab (Image, Video, Audio or Data). Each file is processed with the engine suited to its type. The button only lights up (with a highlighted border) when it is going to do something: there are files to work with in the active tab and the combination of operation, settings, selected files and their edits (crop, rotation, trim, PDF editing) is not the one that was just converted. If there is nothing to work with, it greys out and, when the mouse hovers over it, a notice says why. After a complete conversion it becomes **Rename** (see [Convert and rename](#convert-and-rename)) until something changes. Deleting a converted file or cancelling halfway leaves it lit. In a [guided flow](#guided-flows) the button is the one for the step: **Next** with the `1/2` indicator, or **Convert** with its own on the last step, with a blue background and border. - **Rename** -- (Visible in the Rename tab) applies the bulk naming changes to all the files. It only changes names: it never converts. - **ZIP** -- downloads all the converted files in a single ZIP. - **Download all** -- starts the sequential individual download of all the generated files. - **PDF** -- opens the PDF tab with the **Images → PDF** operation set, which is the one that assembles the document. It no longer generates anything on its own: there is a single path to make a PDF from images, and it is described in [Images → PDF](#images--pdf). With the images already converted it goes straight into the last step of the guided flow, with **Convert 2/2**. - **Share all** -- (mobiles and tablets with the Web Share API) sends the converted files to other apps on the device. Maximum 10 files per send; with more, the ZIP is suggested. Only visible if the browser supports it. ### Guided flows Some tasks require going through two tabs: converting some images in **Image** and assembling them in **PDF**, or a DOCX in **Data** before laying it out. Instead of warning about what is missing and leaving you to go back on your own, TRANSFORMER takes you from one tab to another with the **Next** button: - The button shows the step you are on (`1/2`, `2/3`…) and changes its look: blue background and border, different from the normal lit state. When the mouse hovers over it, the notice says what it is going to do (“Convert 3 images and return to PDF”). - Above the controls a **banner** appears with the flow name and the step (“Preparing images for a PDF · Step 1 of 2”), and a blue dot marks the tab you are going to next. - Each step leaves the tab ready: the chosen operation and the files it concerns, selected. You can change the settings before clicking **Next**; what you cannot do is miss the next step. - The last step is the usual button, **Convert**, with its indicator; clicking it ends the flow. - Where the flow starts, a note explains the steps and offers a shortcut, **Use current settings and …**, which runs all the steps in sequence with the settings the tabs already have. The flow is abandoned when you **switch tabs by hand**, when you **add files** or with **Escape** (if there is no dialog, inspector or menu open, which are closed first). Cancelling a conversion, or nothing coming out of it, leaves you on the same step to try again; if only some files fail, the flow continues with the ones that came out and the note says how many are skipped. Available flows: - **Images → PDF** -- with images not yet converted, in PDF: Image (convert) → PDF (assemble). See [Images → PDF](#images--pdf). - **DOCX → PDF** -- with DOCX not yet converted and the Text and images → PDF operation: Data (DOCX → HTML) → PDF (lay out). See [Text and images → PDF](#text-and-images--pdf). - **Merge images and PDFs** -- with images not yet converted, PDFs loaded and the Merge operation: Image → PDF (assemble the images into a PDF) → PDF (merge). See [Merge](#merge). ### Recipes A **recipe** is a named sequence of steps that is applied all at once to the selected files: for example, “images to 1920 px WEBP → lowercase names → download the ZIP”. Unlike [guided flows](#guided-flows), which are fixed and driven step by step with the Next button, a recipe is composed by you, is saved and runs on its own from start to finish. And unlike **My presets**, which only put settings into the tabs, a recipe also runs them. **My recipes.** The list-with-a-triangle icon in the header, next to My presets, opens the window. Each recipe shows its route (`Image → Rename · ZIP when done`; on hover, the detail of each step) and the buttons **Apply**, **Duplicate**, **Edit** and **Delete**. Below, **examples** grouped by type that can be applied as they are or copied to your recipes to change them: - **Image**: **Lightweight web** (WEBP no wider than 1920 px, lowercase names) and **Photos for email** (JPG no wider than 1280 px and 500 KB). - **PDF**: **Scans to PDF** (to JPG and assembled into an A4 PDF), **Merge PDF** (the selected ones, in list order) and **PDF to images** (each page as a JPG at 150 dpi). - **Audio and video**: **Audio to MP3** (VBR V0, normalised volume) and **Extract audio from videos** (MP3). - **Data**: **Text from screenshots (OCR)** (one .txt per image, Spanish and English). - **Mixed types**: **Everything for web** (images to WEBP, videos to WebM 720p and audio to Opus, all at once). The footer has **New recipe**, **Import** and **Export** (a JSON file with only the recipes; they also travel in Export configuration). **Composing a recipe.** A step is **a tab with its settings**: Image, Video, Audio, Data, PDF or Rename. The settings are not written in the window: set up the tab as usual, choose that tab in **Add step** (the one you have open is preselected) and the recipe copies its settings from that moment. Each step is summarised in one line, for example `WEBP · quality 80 · 1920 px wide (max.) · brightness +10`. - **Change a step**: the pencil takes you to its tab with the step's settings applied and a banner “Editing step 1 of “Lightweight web”” with **Update step** and **Cancel**. In both cases the tab then goes back to the settings it had. - **Order**: by dragging the ⋮⋮ handle or with the arrows of each step (useful with the keyboard and on mobile). **Remove** with the bin. Up to 12 steps. - **When finished**: do nothing, **download the ZIP** or **download one by one** what the recipe has produced. With **Download ZIP**, if only one file comes out that file is downloaded, without a ZIP. Only what the recipe has produced is downloaded: a previous output of a selected file that no step touched does not count. - **Warnings**: a step marked in amber warns of something that would not come out as expected: two Image steps (the second converts again from the original and replaces the first) or Images → PDF without an Image step before it. - **Try with 1 file** applies the recipe, as it is in the editor and without saving it, only to the first selected file and without downloading anything. When it finishes, the banner offers **Back to the recipe** to keep fine-tuning it. **Applying a recipe.** With **Apply** in My recipes, or with a right-click on the input list → **Apply recipe**. It acts on the **selected files**; each step only touches the ones of its type. While it runs, a banner says which step it is on (`Recipe “Lightweight web” · Step 1 of 2 · Image`) with a **Cancel** button, the app visibly goes through each tab and each file shows its usual progress. - Names only change in the **Rename** steps: the mask you have in that tab is not applied during the recipe. - If the recipe has a Video step, its Audio step does not extract the audio from the videos (it would replace their conversion): it only processes the audio files. - **Images → PDF** assembles only the images that come out of the recipe, not others converted before. - A step with no files to apply to is skipped, and a warning is given at the end. - **When finished**, the tabs go back to the settings you had, the selection to the previous one and the active tab to yours; the closing action is performed and a notice summarises the result (“Recipe “Lightweight web”: 12 output files, 1 error. Nothing to do: 3. Video.”). The automatic download of **After converting** does not act on the intermediate steps: the recipe's closing action takes precedence. ### Per-file buttons -- left column (originals) - **Preview** -- hover over the eye icon and the image appears in the left panel; for videos, moving the mouse over the icon scrolls the storyboard; for **PDFs** its first page appears. A click fixes the view (with playback controls for video and audio) and a second click takes it full screen. - **Properties** -- the file's sheet (name, MIME type, dimensions, duration, date) in the same panel, with the on-demand “Analyse” rows for the EXIF and the codec/bitrate. - **Metadata** -- (images only) the original's EXIF in that same panel on hover; the click fixes the view and opens the way to the editor from its header. - **Delete** -- deletes that file from the queue. - A file **generated** by an operation (a merged PDF, a page extracted to an image...) also appears in the left column as a “Generated” placeholder: it can be selected to chain another operation, but it does not have the actions of an imported one. ### Per-file buttons -- right column (converted) - **Rename inline** -- manually edits the name of an individual file (pencil icon). - **Metadata** -- hover over the icon to read the file's metadata in the left panel (the original's EXIF on the left, what the output will carry on the right); the click fixes that view and the editor opens from the button in its header. The editor: for images it edits the EXIF fields (Artist, Copyright, Description, etc.); the metadata is _not_ copied from the original automatically: the output is clean by default. For video and audio it edits Title, Artist and Comment (plus Album in MP3, FLAC, OGG, Opus and WAV), written by FFmpeg on export through a remux without re-encoding. The edited metadata travels in all the output routes (download, ZIP, copy, share, PDF); if the target format does not support writing (AVIF, GIF, BMP, SVG) editing is blocked in the modal and on export a warning says it will not be included. “Delete metadata” empties the edited fields and also removes the pre-existing ones from the original file (including the EXIF of origins renamed without converting and the video/audio tags). In WebP without a VP8X header the XMP is inserted anyway without synthesising it (the decoders tolerate it and so the file is not corrupted). - A green dot next to the name indicates that the output carries edited metadata (the tooltip lists the filled fields), and hovering over the button shows in the left panel the values the downloaded file will carry. - GPS accepts decimal (`40.7128`, `-74.0060`) and degrees-minutes-seconds (`40° 42' 51" N`, `40,42,51N`); it is normalised to decimal when saving, and an unrecognised value marks the field in red and a warning is given when saving. Date/Time expects the EXIF format `2026:09:04 15:30:12`. - The copy icon of each row dumps the original value into the output field (only in individual editing). **Verify** re-reads the resulting file in memory and shows what was written per field, without touching the real file. - **Preview** -- the converted result in the left panel (hover) and fixed with a click; the converted videos play right there. - **Properties** -- the generated file's sheet in that same panel: size, compression versus the original, dimensions and, on demand, codec and bitrate. - **Open** -- opens the converted file in a new browser tab. - **Copy** -- copies the image to the clipboard. For formats not directly supported by the browser (AVIF, etc.) it is automatically converted to PNG as a fallback. Not available for videos. - **Download** -- downloads the individual file. - **Share** -- sends the converted file to another app on the device (Web Share). If the device does not support sharing files, it shares the name as text. - **Delete** -- deletes only the converted result, keeping the original in the queue. For a generated file there is no original: it deletes the whole file. ### Selection and batch operations Conversion and the other bulk operations act only on the **selected** files (highlighted in the left list). Files come in selected by default when they are loaded. - **Click / Ctrl+Click on the name** -- selects or deselects that file. - **Shift+Click** -- selects the range from the last file clicked to this one, file-explorer style. - **Ctrl+A** -- selects all the eligible files in the active tab. - **All / None / Invert buttons** -- in the “Files” bar; they act only on the eligible files according to the active tab (Image, Video, Audio, Data or Rename). - **Right-click** -- on any file in the list opens a context menu with its row's actions (same icon and order) and, separately, the global actions: Convert (input), Download all (output) and Delete all (both lists). With a partial selection, the counter in the “Files” bar shows _N sel / N total_. Under the “Files” bar the **batch operations bar** appears when there is an active selection in the Image or Video tabs: - **Image** -- rotate 90° left/right and flip horizontal/vertical all the selected images at once (the transformations are applied on conversion, just as in the individual preview), and **Metadata**: edit the fields once and they are applied to all the selected images. - **Video** -- rotate and flip the selected videos (applied on conversion via FFmpeg) and **trim by percentage**: enter the start and end in % and click _Apply_; each video calculates its absolute trim from its current effective duration. _Remove_ deletes the trim from the selected ones. If the selection mixes orientations (horizontal/vertical) a warning is shown. ### Engine indicators The right panel summarises the loading state of the active tab in a **pilot light** anchored at the bottom left: a coloured dot -- grey on standby, blue while loading, green when ready and red if it fails --. The label with the detail appears when the mouse hovers over it; with nothing to report, the pilot light is hidden. The pilot light covers the image WASM codecs (`libwebp`, `libavif`, `MozJPEG`, `OxiPNG`), the video and audio engine (FFmpeg.wasm, which is downloaded the first time a video or audio is processed and stays cached) and the Data and PDF libraries. The active tab of the right panel is drawn as a tab, with the panel's background. ### Very large files and memory Before converting a video or audio that might exhaust the tab's memory (an estimate based on size and the device's memory), a confirmation appears with the option to continue, or to trim the clip or lower the resolution before retrying. The estimate always counts the whole input file (FFmpeg receives it complete even if there is a trim), but the output and working part is reduced with the trim and, for video, with an output resolution lower than the source's. If a conversion fails for lack of memory, a warning is shown with those same suggestions. ### Keyboard shortcuts - `Ctrl+Enter` -- Convert - `Ctrl+A` -- Select all the eligible files in the active tab - `Del` -- Delete the focused file - `Ctrl+Z` -- Undo the last list operation (see “Undo and redo”) - `Ctrl+Shift+Z` or `Ctrl+Y` -- Redo - `Space` -- Select/deselect file (left side) - `Ctrl+Space` -- Preview of the focused file in the left panel (floating thumbnail on narrow screens) - Up/down arrow -- Move focus between files in the same column - Left/right arrow -- Move focus to the opposite column - `0` -- Rename tab - `1` `2` `3` `4` -- Image / Video / Audio / Data tabs - `Ctrl+Down arrow` -- Download all individually - `Shift+Down arrow` -- Download ZIP - `Ctrl+Shift+Down arrow` -- Download ZIP + Viewer ### Undo and redo The **deletion of a file** can be undone (Del or the row's bin, in either column) and the **renames** (the pencil of a row or the tab's **Rename** button, which counts as a single step for the whole batch). After each of these operations a notice appears with the **Undo** button; after undoing, the notice offers **Redo**. The same with the keyboard: `Ctrl+Z` undoes and `Ctrl+Shift+Z` or `Ctrl+Y` redoes. - The last 20 steps of the open session are saved; a new operation discards what could be redone. - Bulk deletions are not undone (deleting all the loaded files, all the generated ones or the selection's outputs), which still ask for confirmation, nor conversions. **Delete all the loaded files** is final and empties the undo history. - During a conversion you cannot undo or redo. - With the viewer open, `Ctrl+Z` belongs to the image or PDF editor, and inside a text field it undoes what has been typed. ### Batch renaming Switch to the **Rename** tab (at the top of the right column) to change the output names in bulk. Renaming works the same on image and video files: - **Name mask:** Type a base text; hovering over or focusing the **Name** field reveals the variable chips and the `%n%` counter, and focusing **Replace** reveals its wildcards (click a chip to insert it, e.g. `img_%date%_%n%`). If you leave it empty, the original name is kept. - **Supported variables:** `%name%` (original name), `%n%` (numeric counter), `%ext%` (original extension), `%date%` (current date), `%time%` (current time), `%width%` (output width) and `%height%` (output height). - **Extension:** Lets you force a specific output extension regardless of the conversion format. - **Counter:** Configures the _Start_ number, the _Step_ (increment per file) and the _Digits_ (leading zeros, e.g. 3 digits = 001). - **Preview and Apply:** The projected names are shown in italics in the right list. Click the **Rename** button to apply and fix the names on the files. While the mask is not `%name%` and has not been applied yet, the **Rename** tab is shown in italics. Duplicate names are marked in the right list with an amber warning as soon as two already-converted files would produce the same output name (a comparison that ignores case and leading/trailing spaces; including the mask preview for the selected ones). When exporting as ZIP, ZIP with viewer, Download all or sharing, the duplicates are also warned about before continuing. #### Convert and rename The `%width%` and `%height%` variables and the new extension come from the conversion, so renaming makes more sense after converting. After a complete conversion, the **Convert** button of the tab (Image, Video, Audio, Data or PDF) becomes **Rename** and takes you to this tab with the files you just converted selected: converting and renaming are two clicks plus the mask. If you change a setting, the selection or the edits, or add files (they come in selected), it becomes **Convert** again. In this tab, **Rename** only changes names: with unconverted files, it names the originals, without converting them. #### Replace (find and replace) The **Replace** block lets you find a pattern inside the base name (after applying the mask) and replace it with another text. It is applied to all the files. - **_pattern_ field:** Literal text or _glob_-type pattern to find. If left empty, no substitution is applied. - **_replacement_ field:** Text with which each match is replaced. It can be empty (equivalent to deleting the found pattern). - **Wildcards in the pattern:** - `*` or `%any%` -- any number of characters (including none). - `?` or `%chr%` -- a single character of any kind. - `#` or `%num%` -- a digit (0-9). - `@` or `%txt%` -- a letter (accents included). - `%Nstart%` (e.g. `%3start%`) at the start -- the first _N_ characters of the name. - `%Nend%` (e.g. `%3end%`) at the end -- the last _N_ characters of the name. - **Variable in the replacement:** `%N%` inserts a simple counter (1, 2, 3...) based on the file's position in the list. - **Case sensitivity (_Aa_):** By default the search ignores upper/lower case. Enable the **Aa** checkbox to require an exact match. - **Order of application:** First the mask variables are resolved (`%name%`, `%n%`, etc.), then the replacement is run, and lastly the _Case_ transformation. #### Case (upper/lower-case transformation) The **Case** selector applies a final transformation to the base name (it does not affect the extension). Available options: - **--** (by default): no transformation, it is kept as is. - **lowercase:** converts the whole name to lowercase. E.g. _Mi_Foto_01_ -> _mi_foto_01_. - **Capitalised:** uppercases only the first letter of the name and lowercases the rest. E.g. _mi_FOTO_01_ -> _Mi_foto_01_. - **Title case:** uppercases the first letter of each word (style _Title Case_). E.g. _mi_foto_de_viaje_ -> _Mi_Foto_De_Viaje_. - **UPPERCASE:** converts the whole name to uppercase. E.g. _mi_foto_01_ -> _MI_FOTO_01_. ### Languages The interface is available in **Spanish** and **English**. The language is chosen in the **Language** section of Settings or deduced from the browser (**Automatic** option); the Help has an English version and there is a dedicated English page at [/en/](https://edpanfleto.com/kdgdkd/transformer/en/), meant for search engines. When the app opens embedded in Commander, it inherits the host's language and the selector stops being shown. The system details are in [docs/transformer_i18n.md](docs/transformer_i18n.md) and the Spanish version of this document in [README.md](README.md). ### Task pages and links with the operation already chosen The most searched tasks have a page of their own (for example [/convertir-heic-a-jpg/](https://edpanfleto.com/kdgdkd/transformer/convertir-heic-a-jpg/), [/comprimir-pdf/](https://edpanfleto.com/kdgdkd/transformer/comprimir-pdf/) or [/unir-pdf/](https://edpanfleto.com/kdgdkd/transformer/unir-pdf/)): it is the same app, with a title and text that explain the task and the tab and operation already set. They are in Spanish only for now. The footer of the main page links to all of them. With `?preset=` any link opens the app the same way, with the operation chosen: `?preset=heic-to-jpg`, `compress-images`, `remove-background`, `video-to-gif`, `compress-video`, `video-to-mp3`, `compress-pdf`, `merge-pdf`, `pdf-to-jpg` and `excel-to-csv`. The parameter is consumed on start-up, like the tabs' `#image`, and the settings can be changed afterwards as usual. --- ## Image ### Image conversion flow 1. Select the **Image** tab at the top of the right column. 2. Choose **Preset**, output **Format** (WEBP, AVIF, JPG, PNG or ICO) and **Scale**. 3. Adjust the format-specific advanced controls if you need to (the details of each one are in the _Formats_ section). 4. Click **Convert**. You can cancel during the process. 5. The generated files appear in the right column. ### Supported input formats You can load image files in the following formats: `JPG PNG GIF WebP BMP TIFF HEIC HEIF AVIF SVG ICO`. HEIC/HEIF files are decoded with `heic2any`, and TIFF files with `UTIF.js` (which only Safari renders), before going to the selected encoder. From a multi-page TIFF the first page is used, and a warning is given. A CMYK TIFF is converted to RGB with a simple formula, without an ICC profile (the colours may vary compared to a layout program), and CMYK with JPEG compression, uncommon, can come out wrong. SVGs are rasterised to the requested size. ### Editing the image in the viewer The full-screen viewer of an image is also its editor. What you do in it does not touch the file: it is saved with the image and applied on conversion (and to the row's thumbnail). The **✓** button closes and saves (also whatever is half-done in the open mode) and the **✕** (or `Esc`) closes, undoing everything done since it was opened. A click outside the image does not close the viewer. The bar has four **modes**, which are mutually exclusive. Crop, Straighten and Erase work the same way: what is done in them is a **draft** that is saved with **Apply** (or `Enter`) and thrown away with **Cancel** (`Esc`). While one is open, rotate, flip and reset are disabled, and Undo and Redo walk through the draft's steps. - **Move** (with no mode active): dragging pans the image, the wheel zooms it around the cursor and the double click toggles between **fitted** and **actual size** (also with the **1:1** button). If a crop is applied, only the cropped area is seen, which is what will come out. - **Crop** (`C`): the whole image is seen with the frame on top. Dragging the handles adjusts it, dragging inside moves it and dragging outside draws a new one. The sub-bar sets the **aspect ratio** (Free, Original, 1:1, 4:3, 3:2, 16:9, 4:5; the ⇄ button sets it to portrait or landscape) and the exact **width and height** in pixels. The crop is only saved with **Apply** (or `Enter`), which does not close the viewer; **Cancel** (`Esc`) keeps the previous one and **Remove crop** sets the frame to the whole image (the crop is removed when applying). If you switch to another mode (or press Crop again) without applying, the frame is not saved, but it is kept as a draft and reappears when you return to Crop; closing the viewer discards it. - **Straighten** (`S`): rotates the image by a free angle, from −45° to 45° in tenths, with the slider or the number field; the `←` `→` arrows fine-tune it in tenths (with `Shift`, in degrees). While it rotates, a **fixed grid** on screen serves as a guide to get the horizon or a wall straight. When it rotates, four corners are left exposed, and the sub-bar decides what they carry: - a **colour** of your choice; the first time it is the one **Auto** gives, the colour of the image's edge (the median of its contour); - **Transparent**: transparent corners in PNG, WEBP and AVIF; in JPG, which does not support transparency, they come out white; - **No corners**: crops to the largest rectangle with the original's proportions that does not touch any corner, and replaces any previous crop. While you adjust the angle, that crop is seen as a fixed frame. The crop is measured on the already straightened image: if you change the angle afterwards, the crop shifts to stay over the same part of the photo. The erased areas rotate with the content, and an area drawn with the image straightened comes out straight on screen and in the result. At an angle of 0 nothing changes. - **Erase areas** (`E`): dragging over the image marks an area that is filled on release with the **Fill** colour; the areas are saved with **Apply** (or `Enter`) and **Cancel** (`Esc`) keeps the previous ones. As in Crop, switching to another mode without applying keeps them as a draft. With **Auto**, each new area takes the surrounding colour (the median of its edge), which covers a text or a logo over a plain background without it showing. A click on an area selects it (the one just drawn comes selected) and **Remove the selected area** (or `Del`) removes it; **Remove all** does what it says. To redo a removed area, Undo. Rotate and flip act on what is seen (straightening comes first: you rotate and flip the already straightened image): with the image rotated 90°, flipping horizontally still flips from left to right. The crop and the areas are glued to the content, so rotating or flipping afterwards does not move them. **Undo** and **Redo** (`Ctrl+Z` and `Ctrl+Shift+Z`) walk through everything saved while the viewer is open (inside a mode, its draft's steps), and **Reset** leaves the image as it came (it also removes the straightening). Viewer shortcuts: `R` / `Shift+R` rotate, `F` / `Shift+F` flip horizontally or vertically, `C` crop, `S` straighten, `E` erase, `0` fit, `1` actual size, hold `Space` to move the image from any mode, `Enter` applies and `Esc` cancels the active mode (with no mode, `Esc` closes the viewer discarding the changes). While the viewer is open, the file list shortcuts (Del, the tabs, Ctrl+Enter...) do not act. ### Scale and dimensions The **Scale slider** adjusts the size as a percentage of the original. Click the _Scale_ label to open the advanced modal with the following options: - **Numeric percentage:** Enter the exact value or use the **/2** (half) and **x2** (double) buttons for quick adjustments. - **px mode:** Defines how the target width and height are interpreted. There are five modes, split into two families. **Single-factor modes** (they use a single field: percentage, width or height): - **Maximum:** it will not exceed the given dimension; images already smaller are left untouched. - **Minimum:** it will cover the given dimension; images already larger are left untouched. - **Force:** applies the dimension strictly, in both directions. In these three modes the **active field priority** applies: the last field you edit (percentage, width or height) becomes the active scaling rule, and the inactive fields are shown struck through. The other side is always deduced from the original proportions, so **the image is never distorted**, but you also cannot set width and height at the same time. **Fit modes** (they use width **and** height simultaneously, to reach an exact dimension without distorting): - **Centre crop:** scales until it *covers* the requested width and height and crops from the centre whatever is left over on the axis that exceeds. Output always of the exact size, without bands and without distortion; the price is that part of the image is lost. It is the mode for square thumbnails, covers and grid galleries. - **Letterbox:** scales until the whole image *fits* inside the requested width and height, and fills the remaining gap with bands. Output of the exact size, without distortion and without losing anything; the price is the bands. It is the mode for fitting material of mixed proportions into a common canvas. With Letterbox the **Bars** control appears, with a colour picker (black by default) and a **Transparent** checkbox. Transparent bars require a format with an alpha channel (PNG, WEBP, AVIF): in JPG, which does not have one, they are filled white. In the fit modes the percentage stops applying and its slider is disabled, since the factor is determined by the width and height. If you fill in only one of the two fields, both modes behave like **Force** on that dimension. The width and height always refer to the **final image**: if you have rotated the image 90 or 270 degrees, the crop and the bars are calculated on the already rotated result, not on the original. Under the modal a help line appears with the effect of the chosen mode and a preview of the result on the reference image (for example `1600x900 -> 500x500 - crops 44% of the area`). ### Interpolation The **Interpolation** drop-down of the scale modal decides how the new pixels are calculated when resizing: - **Smooth (photography)** -- averages the neighbouring pixels. It is the default behaviour and the right one for photographs and any image with gradients: the edges are left clean and without jaggies. - **Nearest neighbor (pixel art)** -- copies the nearest pixel without blending colours. The edges stay absolutely hard and no new colour is introduced. It is what is needed for **pixel art**, **screenshots**, graphics with small text, one-pixel lines or diagrams: with smooth interpolation, enlarging pixel art blurs it and reducing a screenshot smudges the text. Note: when _enlarging_, Nearest neighbor produces the classic square-pixel effect. If what you want is to enlarge a photograph without it looking blurry, the right tool is not the interpolation but the **Upscale** described next. ### Upscale (enlargement) The **Upscale** checkbox enlarges the image before fitting it to the target dimensions. It only acts **when the target is larger than the source**: if you are reducing, it is ignored without warning. The factor (**2x** or **4x**) and the engine are chosen: - **Lanczos3 (fast):** Lanczos resampling of radius 3, separable and with premultiplied alpha, run in its own worker. It downloads nothing, works offline and takes on the order of seconds. It gives noticeably cleaner edges than canvas scaling, but it does not invent detail that was not already in the image. It is the default engine. - **Real-ESRGAN (AI):** super-resolution neural network run with `onnxruntime-web`, in 128 px tiles with overlap to avoid seams. It does reconstruct texture and edges. In exchange: it **downloads about 105 MB the first time** (`onnxruntime-web` from jsDelivr and the ONNX model from Hugging Face), which stay in the browser cache for later uses, and needs **WebGPU** to be practical. Without WebGPU it falls back to single-threaded WASM, on the order of tens of minutes per megapixel, and TRANSFORMER warns about it. As the network works in RGB, the alpha channel is enlarged separately with Lanczos3 and reinjected, so transparency is preserved. The modal shows at all times a notice with the expected cost of the selected engine and factor. During the conversion, the file's progress bar reflects the phases (model download, initialisation and inference), and the **Cancel** button aborts the process instantly. The upscale is applied on the area actually needed (already cropped), not on the whole image, so as not to waste time on pixels that are going to be discarded. > Real-ESRGAN and [Remove background](#remove-background) are the only TRANSFORMER features that download something on demand from a third party, and only if you enable them explicitly. Even so, **your images do not leave the device**: what travels is the model download, in the opposite direction. All the processing stays local. ### Remove background The **Background** cell opens the modal that removes the background from each image with a segmentation neural network run with `onnxruntime-web` in a worker, and leaves the subject transparent. Two engines, both on CPU: - **Fast (U²-Netp):** downloads 4.6 MB the first time and takes a couple of seconds per image. The mask is calculated at 320 px and rescaled, so on hair or fine detail the edge is a bit soft. - **Quality (ISNet general-use):** downloads 178 MB the first time and takes on the order of 10–20 s per image. Mask at 1024 px, with much more precise edges, hair included. Settings: **Edge** contracts (to eat into the background halo) or expands the mask, and **Feather** blurs it; both in image pixels. **Fill** puts the subject over a colour instead of leaving transparency; JPG, which does not support it, comes out with a white background if you do not choose a colour. **Crop to the subject** fits the framing to the subject before scaling, so the **Scale** dimensions already refer to the subject. To keep the transparency, convert to PNG, WebP, AVIF or TIFF. It is applied after each image's edits (erased areas, straightening, crop) and before scaling and upscale. The network only runs the first time for each image and engine: changing the edge, the fill or the format reuses the mask. **Cancel** aborts instantly. The models are downloaded from Hugging Face pinned to a commit and their SHA-256 is checked before use; they stay in a dedicated cache that [Settings](#settings) measures and lets you clear. As with Real-ESRGAN, **your images do not leave the device**: the only thing that travels is the model download. ### Image adjustments (filters) The **Adjustments** cell of the Image tab summarises the active filters (for example “Brightness +20 · Saturation −100 · Sharpness +60”, or “None”). Clicking the label or the summary opens the **Image adjustments** modal, with five sliders: - **Brightness**, **Contrast** and **Saturation**, from −100 to 100 with 0 as neutral. Contrast −100 leaves a flat grey; Saturation −100 converts to grayscale and +100 doubles the colour intensity. - **Gamma**, from 0.20 to 3.00 with 1 as neutral: above 1 it lightens the midtones without moving black or white (useful in underexposed photos); below, it darkens them. - **Sharpness**, from −100 to 100: positive values enhance the edges (unsharp mask) and negative ones blur. The filters are **global**: they are applied to all the images on conversion, after the viewer edits and resizing, and at the final size. They do not touch the letterbox bars or the JPG's white background. With everything neutral there is no cost. The modal has a live **preview** of the reference image (the one open in the viewer, or the first selected, or the first in the queue), already edited and resized; holding it pressed shows the original. **Double-clicking** a slider returns it to its neutral value and **Reset** returns them all. The filters do not switch the preset to Custom, are remembered between sessions, travel in the user presets and are reset, like the rest of the tab, with the click on **Preset**. On very large images (about 12 MP) sharpness takes around a second per image and blur about two; the rest of the filters are almost instantaneous. ### Estimated size In the output list, the reference image's row (the one you see in the viewer, or the first selected, or the first) shows the **estimated size** instead of the “-”: `≈ 184 KB (−62 %)` and, below, `Estimated size · 1600×1067`. While it recalculates, the previous figure is shown dimmed. On mobile, and when that image is already converted or in the queue, the data appears on a line at the end of the Image tab's grid. It recalculates when any quality, scale or filter control is moved, without needing to convert. To do so, a sample of the already edited, resized and filtered reference image (64 tiles of 64 px spread across the whole image) is encoded with the real codec and extrapolated to the final size. Measured on photos, screenshots and textures, the average error is around 7 % and does not usually exceed 16 %; the tooltip reminds you of the margin. If the image fits entirely in the sample (512×512 or less) it is encoded in full and the size is exact, without “≈”. The estimate takes less than a second on JPG, WEBP and PNG and about two on AVIF. It is not calculated while a conversion is running. With an active [max size](#max-size) and an estimate that exceeds it, the figure indicates it (`≈ 1.2 MB → ≤ 500 KB`): it is the starting point, and the conversion will lower it to the cap. ### Max size The **Max size** cell of the Image tab sets a size cap for each converted image, such as “≤ 500 KB” for a website. It shows `No limit` or the active cap; a click on the label or the value opens its window: - **Limit the size of each image** -- enables the cap (disabled by default). - **Maximum** -- the value and its unit: **KB**, **MB** (base 1024, like the rest of the app) or **% of the original**, which is calculated on the size of each input file. - **Reduce the dimensions if the quality is not enough** -- enabled by default. On conversion, each image is encoded several times with the real codec looking for the highest quality that fits: never above the one the format has set, and at most down to 40 (down to 5 if reducing the dimensions is not allowed). The search starts from an estimate on the same tile sample as the estimated size, so two or three full encodings are usually enough; it accepts a result that is within 5 % of the cap. If even the minimum quality does not fit and it is allowed, the dimensions are reduced just enough (in proportion to the root of the excess) and the quality is searched again. Lossless PNG and WebP have no quality to lower: only their dimensions can be reduced. The output row says how it came out: `≤ 500 KB, quality 62`, or `downscaled` in the lossless formats; if the scale was also reduced, the percentage appears next to the dimensions. If the cap was not reached (dimensions not allowed, or an image that does not fit even at 16 px), the lightest possible version is delivered, the row marks it in amber (`⚠ > 500 KB`) and a warning is given. The cap is one more tab setting: it is remembered between sessions and goes into the user presets and the exported configuration. ### Compare before and after In the viewer of a **converted** image, the **Compare** button (or the `C` key) overlays the before and after with a vertical **divider**: - **Before** is the original with the conversion's edits and resizing, but without encoding and without filters; **after** is the converted file. Both are drawn at the same scale. - The divider is dragged, or moved with `←` `→` (with `Shift`, in fine steps), `Home` and `End`. - The wheel zooms around the cursor, `1` sets the actual size, `0` fits to the window, `+` and `−` zoom in and out, and the double click toggles. When zoomed in, each pixel is seen sharply, to judge the compression artifacts. Both sides pan together. - The labels give each side's size and the reduction: “Before · 2.1 MB” and “After · 184 KB · −91 %”. - **Compute SSIM** measures the structural similarity between the two sides on 512 px copies and grades it: indistinguishable (≥ 0.995), good (≥ 0.98), acceptable (≥ 0.95) or visible loss. The bands are demanding because the SSIM only looks at luminance: a WEBP at quality 10 still gives around 0.98. With active filters it is compared against the already filtered image, so that the index reflects only the compression, and the label indicates it. The comparison persists when moving between files with `Page Up` and `Page Down` and is closed with the viewer. ### Controls by format Each format shows its own panel of advanced controls when selected. The exhaustive detail of each parameter is in the **Formats** section. Quick summary: - **WEBP:** Quality, Method, Near-LL, Alpha, Filter and Lossless mode. Encoder `libwebp`. - **AVIF:** Quality, Speed, Denoise, Sharpness, Subsample and Alpha. Encoder `libavif`. - **JPG:** Quality, Chroma subsampling, Smoothing, Quantisation table, Trellis and Grayscale. Encoder `MozJPEG`. - **PNG:** Optimisation (1-6), Colours and Interlaced. Encoder `OxiPNG`; lossless unless the colours are reduced. - **ICO / Favicon:** No codec controls. It generates a multi-size `.ico` (16, 32, 48, 64, 128 and 256) or, with **Favicon pack**, a ZIP with `favicon.ico`, `apple-touch-icon.png`, `icon-192.png`, `icon-512.png` and `site.webmanifest`. - **TIFF:** Compression (LZW, Deflate or uncompressed) and annotated Resolution. Own encoder, always lossless. ### Image presets #### Optimised Quality/size balance intended for general web use. The recommended starting point for most images. #### Max Quality It prioritises visual fidelity over file size. Suitable for images that will be viewed at high resolution or that require minimum degradation. #### Min Size It maximises size reduction with aggressive compression. Ideal for thumbnails, background images or contexts with limited bandwidth where size is critical. #### Lossless Lossless encoding: reproduces the original pixels exactly. In WEBP and PNG it guarantees perfect quality; in AVIF and JPG it gets as close as possible with their encoders. #### — Custom — It switches on automatically when any control is edited manually. Selecting a preset again restores its default values for the active format. --- ## Video ### Video conversion flow 1. Select the **Video** tab at the top of the right column. 2. Choose **Preset**, output **Format** (MP4, WebM, animated GIF or animated WebP) and the global controls (**Resolution**, **FPS**, **Audio**). 3. Adjust the format-specific advanced controls if you need to (the details of each one are in the _Formats_ section). 4. Click **Convert**. You can cancel during the process. 5. The FFmpeg.wasm engine (~25 MB) is served from the site itself; the first video conversion downloads it and the following ones are immediate. 6. After converting, the **Metadata** button of each output file (MP4, WebM) lets you tag Title, Artist and Comment; the tag is applied on download or share, without re-encoding. ### Supported input formats You can load video files in the following formats: `MP4 WebM MOV MKV AVI OGV`. In general FFmpeg.wasm can demultiplex most common containers; the ones listed are those filtered explicitly from the picker and recognised on drag. ### Global video controls - **Resolution:** maximum output height in pixels. It keeps the original aspect ratio and acts as a ceiling: a clip that is already smaller is not upscaled. _Original_ keeps the input resolution; preset options: 1080p, 720p, 480p. - **FPS:** frames per second of the output video. Lowering the FPS noticeably reduces the size. _Original_ keeps the source frame rate; preset options: 60, 30, 24, 15, 12. In GIF and animated WebP _Original_ is not a direct pass-through: both formats store a per-frame delay (hundredths of a second in GIF), so the clip's real frame rate is measured with `requestVideoFrameCallback` and fixed in the filtergraph. That way a variable-frame-rate clip --screen recordings, phone cameras-- does not end up with frozen frames of more than a second at the end of the loop. If the measurement fails, the GIF falls back to 15 fps and the WebP keeps the source frame rate. - **Audio:** handling of the audio track. Four modes: - _Encode 128k_ (by default): re-encodes the track to 128 kbps (AAC in MP4, Opus in WebM). - _Encode 320k_: the same but at 320 kbps, higher quality and size. - _Remove_: discards the track. It reduces size and avoids incompatibilities. - _Keep_: copies the original track without re-encoding (`-c:a copy`). It saves time and preserves quality, but fails if the source codec is not compatible with the container (MP4 accepts AAC; WebM accepts Opus/Vorbis). For GIF and animated WebP the control is disabled: the audio is always discarded (GIF does not support audio). When re-encoding (128k or 320k), the track also receives the [audio adjustments](#audio-adjustments) of the Audio tab: high and low pass, gain and fades. Normalisation is not applied to the audio of videos. - **Filters:** summary of the active video filters; clicking the label or the summary opens its modal (see [Video filters](#video-filters)). ### Video filters The **Video filters** modal gathers global settings, which are applied to all the videos on conversion, also in GIF and animated WebP: - **Brightness**, **Contrast**, **Saturation** and **Gamma**, with the same scale as the [image adjustments](#image-adjustments-filters), so the same value gives a similar result in both tabs. They are applied with FFmpeg's `eq` filter. - **Noise**: noise reduction (`hqdn3d`) in three levels, Light, Medium and Strong. It smooths the grain of low-light recordings and usually lowers the size; with the high levels fine detail is lost. - **Deinterlace** (`yadif`): removes the horizontal lines from interlaced videos (DTT, old camcorders). _Automatic_ only processes the frames the file marks as interlaced; _Always_ processes all of them, for mislabelled files. - **Stabilise** (`deshake`): compensates hand-held camera shake. It is a basic stabiliser and makes the conversion considerably slower. The edges left exposed are filled with the mirrored image. The order in the chain is: deinterlace → FPS → rotation and flip → stabilise → noise → colour → scale. In the GIF, the palette is calculated with the colours already filtered. The modal's **preview** shows a frame of the reference video (the one open in the viewer, or the first selected, or the first in the queue), taken from the centre of the trimmed section, with the colour settings applied. It is approximate, because `eq` works on the luminance; the noise, the deinterlacing and the stabilisation are not previewed. Holding it pressed shows the original. As in image, double-clicking a slider returns it to neutral, **Reset** returns them all and the click on **Preset** also resets them. ### Controls by format Each format shows its own panel of advanced controls when selected. The exhaustive detail of each parameter is in the **Formats** section. Quick summary: - **MP4 (H.264):** Quality (mapped to CRF 18-28), Encoder speed (ultrafast -> slow) and Profile (Baseline / Main / High). Encoding with x264 via FFmpeg. - **WebM (VP9):** Quality (mapped to CRF 15-35), CPU used (encoder effort) and Lossless mode. Encoding with libvpx-vp9 via FFmpeg. - **Animated GIF:** Colours (palette max. 256) and Dithering (Bayer / Floyd-Steinberg / None). The audio is always discarded. - **Animated WebP:** Quality, Method (encoder effort) and Lossless mode. ### Join videos (+) The **+** button next to **Convert** joins the selected videos into one, in queue order (drag the rows to change it). The result is added as a new row under Generated, unselected, and the originals are left untouched. **Convert** still converts each video separately. - **Without re-encoding** when possible: if all the clips share codec, size, frame rate and pixel format (and audio, if it is kept), the codec is valid for the output format (H.264 in MP4 and MKV; VP9 or VP8 in WebM), there are no trims, rotations or [filters](#video-filters), and **Resolution** and **FPS** are on _Original_, they are joined with FFmpeg's concat demuxer: it is fast and loses no quality. The final notice says so. - **Re-encoding** in any other case: each clip is fitted into the size of the first one (already rotated, and with **Resolution** as a ceiling), letterboxed if its aspect differs, at the chosen FPS or the first one's, and encoded with the tab's settings. Each clip's trim, rotation and flip are respected; the video filters and the [audio adjustments](#audio-adjustments) apply to the whole. A clip without an audio track contributes silence of its length; with _Remove_ the output has no audio and with _Keep_ the audio is re-encoded (several different tracks can't be copied). - Formats: MP4, WebM and MKV. Animated GIF and WebP can't be joined (the button is disabled and its tooltip explains why). - The button needs at least two selected videos. Before starting there is a warning if the clips together may exhaust memory, and **Cancel** stops the join. ### Video presets #### Optimised Quality/size balance intended for general web use. In MP4 and WebM it keeps the original resolution and FPS with medium-high quality; in GIF it drops to 480p/15 fps and in animated WebP to 720p, which is what makes those two formats usable. The recommended starting point for most videos. #### Max Quality It prioritises visual fidelity over file size. In MP4 and WebM it keeps the original resolution and FPS, raises the encoder quality to the maximum (slower encoder, larger files) and keeps the original audio without re-encoding (`-c:a copy`). Suitable for masters, archiving or large-screen playback. In GIF and animated WebP no preset keeps the original resolution, because they are delivery formats and not archive ones: the ceiling is 720p in GIF and 1080p in WebP. An 8 s GIF at 1080p goes over 50 MB and exhausts the engine's memory; at 720p it stays at a few. The audio does not apply in either of them. #### Min Size It maximises size reduction with aggressive compression. It reduces to 720p and 30 FPS to minimise the size. Ideal for quick previews, messaging or contexts with limited bandwidth. #### No Audio (Social) Configuration optimised for social networks: it removes the audio, reduces to 720p and 30 FPS, and applies balanced compression. Suitable for clips intended for Instagram, TikTok, X and similar, where the audio is replaced or played muted. #### Lossless (WebM only) Available through the **Lossless** checkbox in WebM (VP9) and in animated WebP: lossless encoding that reproduces the pixels exactly. It produces much larger files than lossy mode. MP4 and GIF do not offer a dedicated lossless mode (GIF always quantises to a palette). #### — Custom — It switches on automatically when any control is edited manually. Selecting a preset again restores its default values for the active format. --- ## Audio ### Audio conversion flow 1. Select the **Audio** tab at the top of the right column. 2. Choose **Preset**, output **Format** (MP3, AAC/M4A, Opus, WebM/Opus, OGG Vorbis, FLAC or WAV) and the global controls (**Sample rate**, **Channels**, **Normalise volume**). 3. Adjust the format-specific advanced controls if you need to (the details of each one are in the _Formats_ section). 4. Click **Convert**. You can cancel during the process. 5. The conversion is done with FFmpeg.wasm: if it has not been loaded yet, it is downloaded the first time (~30 MB) and stays cached for later uses. 6. After converting, the **Metadata** button of each output file lets you tag Title, Artist and Comment (and Album in MP3, FLAC, OGG, Opus and WAV); the tag is applied on download or share, without re-encoding. ### Supported input formats You can load audio files in the following formats: `MP3 WAV AAC M4A OGG Opus FLAC`. Extracting audio from video files loaded in the queue is also accepted, by selecting the Audio tab before converting. ### Global audio controls - **S. rate:** output sample rate in Hz. _Original_ keeps the input file's. For voice, 16 000-22 050 Hz is usually enough; for music, 44 100 or 48 000 Hz. - **Channels:** _Original_ keeps those of the file, _Stereo_ forces two channels and _Mono_ reduces to one (roughly half the size in lossy formats). - **Normalise volume:** applies the `loudnorm` filter (EBU R128, target `I=-16 LUFS, TP=-1.5, LRA=11`). Useful for matching levels between files; it increases the encoding time. - **Adjustments:** summary of the active audio adjustments; clicking the label or the summary opens its modal (see [Audio adjustments](#audio-adjustments)). ### Audio adjustments The **Audio adjustments** modal gathers global settings that are applied to all the audio on conversion: - **High-pass**: removes whatever is below the chosen frequency (40, 80, 120 or 200 Hz). It removes hum, microphone thumps and wind noise; 80 Hz is the usual value for voice. - **Low-pass**: removes whatever is above (16, 12, 8 or 4 kHz). It smooths hiss and harsh treble; 4 kHz gives a telephone sound. - **Gain**: from −20 to +20 dB in half decibels. +6 dB is roughly double the amplitude; raising it a lot can clip. Double-clicking returns it to 0. - **Fade in** and **Fade out**: duration in seconds (up to 30) of the fade from silence at the start and to silence at the end. They are counted over the [trimmed](#trim) section, and never exceed the clip's duration. The order in the chain is: high-pass → low-pass → gain → fades → normalisation. With **Normalise volume** active the gain barely changes the result, because normalisation brings the volume to the standard level; the modal warns about it. The adjustments are also applied to the track of **videos** when it is re-encoded (_Encode 128k/320k_ mode of the Video tab). With _Keep_ the track is copied as is and with _Remove_ there is no track, so in those cases they are not applied. Changing the audio adjustments lights **Convert** up again also in the Video tab. ### Trim When the cursor passes over an audio file in the left column, a playback bar appears with two handles to set the **start** and the **end** of the trim. The conversion will generate only the selected fragment. The time fields accept the `mm:ss.ms` format; the reset button removes the trim and returns to the full clip. In the viewer, `Space` plays or pauses, ✓ closes and saves the trim and ✕ (or `Esc`) leaves it as it was when opened. ### Join and mix audios (+) The **+** button next to **Convert** combines the selected audios into one, in queue order, with the tab's format and settings. The result is added as a new row under Generated, unselected. It also works with the audio of videos in the queue; a video without an audio track is left out with a notice. What it does depends on **Join (+)**: - **In sequence:** one after another, respecting each one's trim. If they all have the same encoding as the output (same codec, sample rate and channels), with no trims, adjustments or normalisation, they are joined without re-encoding. - **Mix:** all at once in a single track (`amix` filter). **Length** chooses whether the mix lasts as long as the longest, the shortest or the first in the queue; **Levels** sets each audio's weight in queue order, separated by spaces (`1 0.5` halves the second one; empty, all equal; missing ones count as 1). Since `amix` splits the volume among the tracks, **Normalise volume** helps bring the level back up. The output's sample rate and channels are those of **S. rate** and **Channels**, or the first audio's with _Original_. The [audio adjustments](#audio-adjustments) and normalisation apply to the result (the fade-out, at the end of the whole). ### Audio presets #### Optimised Quality/size balance intended for general use. The recommended starting point for most files. It keeps the current format and applies intermediate values (e.g. MP3 VBR V4, AAC 128 kbps, Opus 96 kbps, OGG q5, FLAC level 5, WAV 16-bit). #### Max Quality It prioritises fidelity over size. It keeps the current format and raises the parameters to the maximum reasonable (MP3 VBR V0 ~245 kbps, AAC 256 kbps, Opus 192 kbps, OGG q8, FLAC compression 12, WAV 24-bit). #### Min Size It maximises size reduction with aggressive compression. If the current format is `MP3`, `AAC` or `OGG` it keeps the format but lowers the bitrate; in any other lossy format it keeps the choice, and from lossless formats (FLAC/WAV) it **automatically switches to Opus 48 kbps** for its superior efficiency at low bitrates. #### Lossless Lossless encoding. If the current format is not already FLAC or WAV, it **automatically switches to FLAC** (compression 8). It reproduces the input samples losslessly, at the cost of significantly larger files than any lossy format. #### Roland SP-404 MK2 Configuration for the Roland SP-404 MK2 sampler: it forces **WAV 48 kHz, 16-bit PCM** output and keeps the original channels. Hardware limit: 16 minutes per sample (not enforced on encoding; it remains a warning). #### Roland TR-8S Configuration for the Roland TR-8S drum machine: it forces **WAV 44.1 kHz, 16-bit PCM, mono** output. Hardware limit: 600 ms per sample and 256 MB in total (not enforced on encoding; it remains a warning). #### Polyend Play Configuration for the Polyend Play groovebox: it forces **WAV 44.1 kHz, 16-bit PCM, mono** output. Hardware limit: 32 MB per sample (not enforced on encoding; it remains a warning). #### — Custom — It switches on automatically when any control is edited manually. Selecting a preset again restores its default values for the active format. --- ## Data ### Data transformation flow 1. Select the **Data** tab at the top of the right column. 2. Choose the desired **Operation**. The drop-down groups the operations by intent: **Text** (HTML<->MD, HTML->text), **Documents** (DOCX and image OCR), **Structured** (JSON<->CSV, JSON<->YAML, XML<->JSON, spreadsheets<->CSV/JSON) and **Code** (Beautify, Minify). 3. Adjust the operation-specific controls if you need to. 4. Click **Convert**. The result is generated instantly in the browser. ### Supported input formats - **HTML / Markdown:** `.html .htm .md .markdown` - **JSON / CSV:** `.json .csv .tsv` - **YAML:** `.yaml .yml` - **XML:** `.xml` - **Spreadsheets:** `.xlsx .xls .ods` (processed with SheetJS) - **DOCX:** `.docx` (processed with Mammoth.js) - **Beautify / Minify:** `.html .htm .css .js .mjs .json` - **Image → Text (OCR):** the images in the queue (`.png .jpg .webp .avif .gif .bmp .heic`) ### Available operations #### HTML -> Markdown Converts HTML documents to Markdown using **Turndown** (v7.2.0) + GFM plugin. The available controls are: - **Headings:** ATX (#) or Setext (===) style. - **List:** marker for unordered lists (-, *, +). - **Code:** fenced (```) or indented. - **Italic:** emphasis delimiter (_ or *). - **GFM:** enables GitHub Flavored Markdown (tables, strikethrough, task lists). #### Markdown -> HTML Converts Markdown to HTML using **Marked** (v12.0.2). The available controls are: - **GFM:** enables GitHub Flavored Markdown. - **Line breaks:** converts single line breaks into `
`. - **Sanitize:** sanitises the HTML with DOMPurify to prevent script injection. - **Full doc.:** wraps the output in a complete HTML document with basic embedded CSS. #### HTML -> Text Extracts the plain text of an HTML file (with the browser's `DOMParser`, which doesn't run scripts or load resources). The output is a `.txt` with paragraphs and headings separated by a blank line; `