-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmedia-processing.html
More file actions
28 lines (26 loc) · 26.1 KB
/
media-processing.html
File metadata and controls
28 lines (26 loc) · 26.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Media Processing | Foldergram</title>
<meta name="description" content="Supported formats, derivative generation rules, and video playback strategy in Foldergram.">
<meta name="generator" content="VitePress v1.6.4">
<link rel="preload stylesheet" href="/assets/style.D0ri7LhZ.css" as="style">
<link rel="preload stylesheet" href="/vp-icons.css" as="style">
<script type="module" src="/assets/app.Ctsaibyu.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/assets/chunks/theme.DJE1TC2M.js">
<link rel="modulepreload" href="/assets/chunks/framework.ePeAWSvT.js">
<link rel="modulepreload" href="/assets/media-processing.md.BZnAue5X.lean.js">
<link rel="icon" type="image/svg+xml" href="/logo.svg">
<link rel="apple-touch-icon" href="/logo.svg">
<meta name="theme-color" content="#6366f1">
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
</head>
<body>
<div id="app"><div class="Layout" data-v-b831c05f><!--[--><!--]--><!--[--><span tabindex="-1" data-v-9178e81a></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-9178e81a>Skip to content</a><!--]--><!----><header class="VPNav" data-v-b831c05f data-v-2222ab16><div class="VPNavBar" data-v-2222ab16 data-v-3a1adb31><div class="wrapper" data-v-3a1adb31><div class="container" data-v-3a1adb31><div class="title" data-v-3a1adb31><div class="VPNavBarTitle has-sidebar" data-v-3a1adb31 data-v-7c1b0e18><a class="title" href="/" data-v-7c1b0e18><!--[--><!--]--><!--[--><img class="VPImage logo" src="/logo.svg" alt data-v-84be65fe><!--]--><span data-v-7c1b0e18>Foldergram</span><!--[--><!--]--></a></div></div><div class="content" data-v-3a1adb31><div class="content-body" data-v-3a1adb31><!--[--><!--]--><div class="VPNavBarSearch search" data-v-3a1adb31><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-3a1adb31 data-v-b187e594><span id="main-nav-aria-label" class="visually-hidden" data-v-b187e594> Main Navigation </span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/quick-start" tabindex="0" data-v-b187e594 data-v-4599aa41><!--[--><span data-v-4599aa41>Quick Start</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/installation" tabindex="0" data-v-b187e594 data-v-4599aa41><!--[--><span data-v-4599aa41>Installation</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/configuration" tabindex="0" data-v-b187e594 data-v-4599aa41><!--[--><span data-v-4599aa41>Configuration</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/how-it-works" tabindex="0" data-v-b187e594 data-v-4599aa41><!--[--><span data-v-4599aa41>How It Works</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/api" tabindex="0" data-v-b187e594 data-v-4599aa41><!--[--><span data-v-4599aa41>API</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/security" tabindex="0" data-v-b187e594 data-v-4599aa41><!--[--><span data-v-4599aa41>Security</span><!--]--></a><!--]--><!--[--><a class="VPLink link vp-external-link-icon VPNavBarMenuLink" href="https://foldergram.intentdeep.com/" target="_blank" rel="noreferrer" tabindex="0" data-v-b187e594 data-v-4599aa41><!--[--><span data-v-4599aa41>Demo</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-3a1adb31 data-v-df187b99><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-df187b99 data-v-8e7bc7a0 data-v-dc0f6ec6><span class="check" data-v-dc0f6ec6><span class="icon" data-v-dc0f6ec6><!--[--><span class="vpi-sun sun" data-v-8e7bc7a0></span><span class="vpi-moon moon" data-v-8e7bc7a0></span><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-3a1adb31 data-v-ed584c66 data-v-2b546b40><!--[--><a class="VPSocialLink no-icon" href="https://github.com/foldergram/foldergram" aria-label="github" target="_blank" rel="noopener" data-v-2b546b40 data-v-9ca19b6a><span class="vpi-social-github"></span></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-3a1adb31 data-v-7fd1485d data-v-5d90fd5a><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-5d90fd5a><span class="vpi-more-horizontal icon" data-v-5d90fd5a></span></button><div class="menu" data-v-5d90fd5a><div class="VPMenu" data-v-5d90fd5a data-v-565e72ed><!----><!--[--><!--[--><!----><div class="group" data-v-7fd1485d><div class="item appearance" data-v-7fd1485d><p class="label" data-v-7fd1485d>Appearance</p><div class="appearance-action" data-v-7fd1485d><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-7fd1485d data-v-8e7bc7a0 data-v-dc0f6ec6><span class="check" data-v-dc0f6ec6><span class="icon" data-v-dc0f6ec6><!--[--><span class="vpi-sun sun" data-v-8e7bc7a0></span><span class="vpi-moon moon" data-v-8e7bc7a0></span><!--]--></span></span></button></div></div></div><div class="group" data-v-7fd1485d><div class="item social-links" data-v-7fd1485d><div class="VPSocialLinks social-links-list" data-v-7fd1485d data-v-2b546b40><!--[--><a class="VPSocialLink no-icon" href="https://github.com/foldergram/foldergram" aria-label="github" target="_blank" rel="noopener" data-v-2b546b40 data-v-9ca19b6a><span class="vpi-social-github"></span></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-3a1adb31 data-v-7b1e48c5><span class="container" data-v-7b1e48c5><span class="top" data-v-7b1e48c5></span><span class="middle" data-v-7b1e48c5></span><span class="bottom" data-v-7b1e48c5></span></span></button></div></div></div></div><div class="divider" data-v-3a1adb31><div class="divider-line" data-v-3a1adb31></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-b831c05f data-v-a3b82d7b><div class="container" data-v-a3b82d7b><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-a3b82d7b><span class="vpi-align-left menu-icon" data-v-a3b82d7b></span><span class="menu-text" data-v-a3b82d7b>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-a3b82d7b data-v-84597ab5><button data-v-84597ab5>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-b831c05f data-v-e0bd508c><div class="curtain" data-v-e0bd508c></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-e0bd508c><span class="visually-hidden" id="sidebar-aria-label" data-v-e0bd508c> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-aef8ce5e><section class="VPSidebarItem level-0" data-v-aef8ce5e data-v-44dbf5ab><div class="item" role="button" tabindex="0" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><h2 class="text" data-v-44dbf5ab>Guide</h2><!----></div><div class="items" data-v-44dbf5ab><!--[--><div class="VPSidebarItem level-1 is-link" data-v-44dbf5ab data-v-44dbf5ab><div class="item" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><a class="VPLink link link" href="/quick-start" data-v-44dbf5ab><!--[--><p class="text" data-v-44dbf5ab>Quick Start</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-44dbf5ab data-v-44dbf5ab><div class="item" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><a class="VPLink link link" href="/installation" data-v-44dbf5ab><!--[--><p class="text" data-v-44dbf5ab>Installation</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-44dbf5ab data-v-44dbf5ab><div class="item" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><a class="VPLink link link" href="/configuration" data-v-44dbf5ab><!--[--><p class="text" data-v-44dbf5ab>Configuration</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-aef8ce5e><section class="VPSidebarItem level-0 has-active" data-v-aef8ce5e data-v-44dbf5ab><div class="item" role="button" tabindex="0" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><h2 class="text" data-v-44dbf5ab>Product</h2><!----></div><div class="items" data-v-44dbf5ab><!--[--><div class="VPSidebarItem level-1 is-link" data-v-44dbf5ab data-v-44dbf5ab><div class="item" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><a class="VPLink link link" href="/how-it-works" data-v-44dbf5ab><!--[--><p class="text" data-v-44dbf5ab>How It Works</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-44dbf5ab data-v-44dbf5ab><div class="item" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><a class="VPLink link link" href="/features" data-v-44dbf5ab><!--[--><p class="text" data-v-44dbf5ab>Features</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-44dbf5ab data-v-44dbf5ab><div class="item" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><a class="VPLink link link" href="/media-processing" data-v-44dbf5ab><!--[--><p class="text" data-v-44dbf5ab>Media Processing</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-44dbf5ab data-v-44dbf5ab><div class="item" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><a class="VPLink link link" href="/security" data-v-44dbf5ab><!--[--><p class="text" data-v-44dbf5ab>Security</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-aef8ce5e><section class="VPSidebarItem level-0" data-v-aef8ce5e data-v-44dbf5ab><div class="item" role="button" tabindex="0" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><h2 class="text" data-v-44dbf5ab>Reference</h2><!----></div><div class="items" data-v-44dbf5ab><!--[--><div class="VPSidebarItem level-1 is-link" data-v-44dbf5ab data-v-44dbf5ab><div class="item" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><a class="VPLink link link" href="/api" data-v-44dbf5ab><!--[--><p class="text" data-v-44dbf5ab>API</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-44dbf5ab data-v-44dbf5ab><div class="item" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><a class="VPLink link link" href="/development" data-v-44dbf5ab><!--[--><p class="text" data-v-44dbf5ab>Development</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-44dbf5ab data-v-44dbf5ab><div class="item" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><a class="VPLink link link" href="/troubleshooting" data-v-44dbf5ab><!--[--><p class="text" data-v-44dbf5ab>Troubleshooting</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-44dbf5ab data-v-44dbf5ab><div class="item" data-v-44dbf5ab><div class="indicator" data-v-44dbf5ab></div><a class="VPLink link link" href="/faq" data-v-44dbf5ab><!--[--><p class="text" data-v-44dbf5ab>FAQ</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-b831c05f data-v-bf3f1372><div class="VPDoc has-sidebar has-aside" data-v-bf3f1372 data-v-7c2da6bf><!--[--><!--]--><div class="container" data-v-7c2da6bf><div class="aside" data-v-7c2da6bf><div class="aside-curtain" data-v-7c2da6bf></div><div class="aside-container" data-v-7c2da6bf><div class="aside-content" data-v-7c2da6bf><div class="VPDocAside" data-v-7c2da6bf data-v-c3c6bcbc><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-c3c6bcbc data-v-16b74dc6><div class="content" data-v-16b74dc6><div class="outline-marker" data-v-16b74dc6></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-16b74dc6>On this page</div><ul class="VPDocOutlineItem root" data-v-16b74dc6 data-v-8c1c05d6><!--[--><!--]--></ul></div></nav><!--[--><!--]--><div class="spacer" data-v-c3c6bcbc></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-7c2da6bf><div class="content-container" data-v-7c2da6bf><!--[--><!--]--><main class="main" data-v-7c2da6bf><div style="position:relative;" class="vp-doc _media-processing" data-v-7c2da6bf><div><h1 id="media-processing" tabindex="-1">Media Processing <a class="header-anchor" href="#media-processing" aria-label="Permalink to "Media Processing""></a></h1><p>Foldergram generates derivatives so feed and detail views can stay fast without touching original files on every request. Depending on configuration, those derivatives are either created during scans or lazily on first request and then cached on disk.</p><h2 id="supported-formats" tabindex="-1">Supported formats <a class="header-anchor" href="#supported-formats" aria-label="Permalink to "Supported formats""></a></h2><h3 id="images" tabindex="-1">Images <a class="header-anchor" href="#images" aria-label="Permalink to "Images""></a></h3><ul><li><code>.jpg</code></li><li><code>.jpeg</code></li><li><code>.png</code></li><li><code>.webp</code></li><li><code>.gif</code></li></ul><h3 id="videos" tabindex="-1">Videos <a class="header-anchor" href="#videos" aria-label="Permalink to "Videos""></a></h3><ul><li><code>.mp4</code></li><li><code>.mov</code></li><li><code>.m4v</code></li><li><code>.webm</code></li><li><code>.mkv</code></li></ul><h2 id="output-sizes" tabindex="-1">Output sizes <a class="header-anchor" href="#output-sizes" aria-label="Permalink to "Output sizes""></a></h2><p>These values are defined in <code>server/src/utils/image-utils.ts</code>.</p><table tabindex="0"><thead><tr><th>Constant</th><th>Value</th><th>Used for</th></tr></thead><tbody><tr><td><code>THUMBNAIL_SIZE</code></td><td><code>640</code></td><td>Feed cards, folder grids, avatars, and video posters</td></tr><tr><td><code>PREVIEW_MAX_WIDTH</code></td><td><code>1500</code></td><td>Detail-view previews and transcodes</td></tr></tbody></table><h2 id="derivative-timing" tabindex="-1">Derivative timing <a class="header-anchor" href="#derivative-timing" aria-label="Permalink to "Derivative timing""></a></h2><p><code>DERIVATIVE_MODE</code> controls when missing derivatives are created:</p><table tabindex="0"><thead><tr><th>Mode</th><th>Behavior</th></tr></thead><tbody><tr><td><code>eager</code></td><td>Scans queue derivative generation during indexing.</td></tr><tr><td><code>lazy</code></td><td>Scans index metadata only. Missing thumbnails and previews are generated when <code>/thumbnails/...</code> or <code>/previews/...</code> is first requested.</td></tr></tbody></table><p>Lazy mode still writes the generated files to the configured derivative directories, so subsequent requests use the cached file on disk.</p><h2 id="derivative-mapping" tabindex="-1">Derivative mapping <a class="header-anchor" href="#derivative-mapping" aria-label="Permalink to "Derivative mapping""></a></h2><p>Foldergram mirrors relative source paths into the derivative roots.</p><table tabindex="0"><thead><tr><th>Source media</th><th>Thumbnail output</th><th>Preview output</th></tr></thead><tbody><tr><td>Image</td><td><code>.webp</code></td><td><code>.webp</code></td></tr><tr><td>Video</td><td><code>.webp</code></td><td><code>.mp4</code> or direct original playback</td></tr></tbody></table><p>Examples:</p><table tabindex="0"><thead><tr><th>Source</th><th>Thumbnail</th><th>Preview</th></tr></thead><tbody><tr><td><code>trips/oslo/IMG_0001.jpg</code></td><td><code>trips/oslo/IMG_0001.webp</code></td><td><code>trips/oslo/IMG_0001.webp</code></td></tr><tr><td><code>trips/oslo/clip-01.mov</code></td><td><code>trips/oslo/clip-01.webp</code></td><td><code>trips/oslo/clip-01.mp4</code></td></tr></tbody></table><h2 id="image-derivatives" tabindex="-1">Image derivatives <a class="header-anchor" href="#image-derivatives" aria-label="Permalink to "Image derivatives""></a></h2><p>Images are processed with Sharp.</p><h3 id="thumbnail" tabindex="-1">Thumbnail <a class="header-anchor" href="#thumbnail" aria-label="Permalink to "Thumbnail""></a></h3><ul><li>auto-rotated</li><li>resized to width <code>640</code> without enlargement</li><li>encoded as WebP with <code>quality: 82</code></li></ul><h3 id="preview" tabindex="-1">Preview <a class="header-anchor" href="#preview" aria-label="Permalink to "Preview""></a></h3><ul><li>auto-rotated</li><li>resized to width <code>1500</code> without enlargement</li><li>encoded as WebP with <code>quality: 86</code></li></ul><h2 id="image-detail-source" tabindex="-1">Image detail source <a class="header-anchor" href="#image-detail-source" aria-label="Permalink to "Image detail source""></a></h2><p><code>IMAGE_DETAIL_SOURCE</code> affects image detail pages only:</p><table tabindex="0"><thead><tr><th>Value</th><th>Behavior</th></tr></thead><tbody><tr><td><code>preview</code></td><td><code>/image/:id</code> uses the generated preview asset.</td></tr><tr><td><code>original</code></td><td><code>/image/:id</code> uses <code>/api/originals/:id</code> for images.</td></tr></tbody></table><p>This setting does not change feed cards, folder grids, avatars, or any video playback behavior.</p><h2 id="video-metadata" tabindex="-1">Video metadata <a class="header-anchor" href="#video-metadata" aria-label="Permalink to "Video metadata""></a></h2><p>Videos are probed with <code>ffprobe</code>.</p><p>Foldergram reads:</p><ul><li>width and height</li><li>duration</li><li>creation timestamps when present</li><li>container and codec details used to decide playback strategy</li></ul><h2 id="video-thumbnail-generation" tabindex="-1">Video thumbnail generation <a class="header-anchor" href="#video-thumbnail-generation" aria-label="Permalink to "Video thumbnail generation""></a></h2><p>Video thumbnails are generated with <code>ffmpeg</code>:</p><ul><li><code>thumbnail</code> filter picks a representative frame</li><li>the frame is resized to width <code>640</code></li><li>output is encoded as WebP</li></ul><h2 id="video-preview-generation" tabindex="-1">Video preview generation <a class="header-anchor" href="#video-preview-generation" aria-label="Permalink to "Video preview generation""></a></h2><p>When a video needs a derived preview, Foldergram transcodes it with <code>ffmpeg</code> to:</p><ul><li>H.264 video</li><li>AAC audio when audio is present</li><li><code>yuv420p</code></li><li><code>+faststart</code></li><li>landscape-equivalent output up to <code>1280x720</code></li><li>portrait and square output that keeps the short edge at or below <code>720</code></li><li>even-numbered output dimensions for encoder compatibility</li></ul><h2 id="direct-original-video-playback" tabindex="-1">Direct-original video playback <a class="header-anchor" href="#direct-original-video-playback" aria-label="Permalink to "Direct-original video playback""></a></h2><p>Foldergram can mark the original video as eligible for direct playback in the detail player when all of these are true:</p><ul><li>the file extension is <code>.mp4</code></li><li>the container is compatible with MP4</li><li>the video codec is H.264</li><li>the pixel format is <code>yuv420p</code></li><li>the audio codec is AAC, or there is no audio track</li></ul><p>When that happens:</p><ul><li><code>playbackStrategy</code> is set to <code>original</code></li><li>generated previews still remain the default playback source</li><li>the detail player can expose an <code>HD</code> switch when the original is compatible and higher resolution than the generated preview</li><li>feed cards and other list surfaces continue to use generated preview media</li></ul><h2 id="gif-handling" tabindex="-1">GIF handling <a class="header-anchor" href="#gif-handling" aria-label="Permalink to "GIF handling""></a></h2><p>GIF files are accepted as supported images, but derivatives are generated with <code>animated: false</code>. In practice that means Foldergram treats GIF derivatives as static image outputs, not animated preview pipelines.</p><h2 id="timestamp-sources" tabindex="-1">Timestamp sources <a class="header-anchor" href="#timestamp-sources" aria-label="Permalink to "Timestamp sources""></a></h2><p>Foldergram resolves <code>taken_at</code> from the best available source:</p><ul><li>EXIF or embedded media metadata when available</li><li>file modification time or first-seen timing when richer metadata is absent</li></ul><p>Those timestamps influence:</p><ul><li>Recent feed ordering</li><li>Moments eligibility</li><li>Highlights fallback behavior</li></ul><h2 id="thumbnail-only-rebuild" tabindex="-1">Thumbnail-only rebuild <a class="header-anchor" href="#thumbnail-only-rebuild" aria-label="Permalink to "Thumbnail-only rebuild""></a></h2><p>The thumbnail rebuild action:</p><ul><li>removes the thumbnail cache directory</li><li>recreates it</li><li>rebuilds thumbnails and video poster images for currently indexed media</li></ul><p>It does not regenerate previews. In lazy mode it acts as a thumbnail and poster prewarm only; preview generation still happens on demand.</p><h2 id="why-derivatives-are-mirrored-by-relative-path" tabindex="-1">Why derivatives are mirrored by relative path <a class="header-anchor" href="#why-derivatives-are-mirrored-by-relative-path" aria-label="Permalink to "Why derivatives are mirrored by relative path""></a></h2><p>Mirroring keeps the derivative tree predictable and lets Foldergram:</p><ul><li>resolve public asset URLs without exposing arbitrary filesystem paths</li><li>reuse derivatives across scans when the relative source path still matches</li><li>remove per-folder derivative trees safely during folder deletion</li></ul></div></div></main><footer class="VPDocFooter" data-v-7c2da6bf data-v-fea9e177><!--[--><!--]--><div class="edit-info" data-v-fea9e177><!----><div class="last-updated" data-v-fea9e177><p class="VPLastUpdated" data-v-fea9e177 data-v-61bce6e2>Last updated: <time datetime="2026-03-28T17:40:54.000Z" data-v-61bce6e2></time></p></div></div><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-fea9e177><span class="visually-hidden" id="doc-footer-aria-label" data-v-fea9e177>Pager</span><div class="pager" data-v-fea9e177><a class="VPLink link pager-link prev" href="/features" data-v-fea9e177><!--[--><span class="desc" data-v-fea9e177>Previous page</span><span class="title" data-v-fea9e177>Features</span><!--]--></a></div><div class="pager" data-v-fea9e177><a class="VPLink link pager-link next" href="/security" data-v-fea9e177><!--[--><span class="desc" data-v-fea9e177>Next page</span><span class="title" data-v-fea9e177>Security</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><footer class="VPFooter has-sidebar" data-v-b831c05f data-v-9f6e1f5c><div class="container" data-v-9f6e1f5c><p class="message" data-v-9f6e1f5c>Released under the AGPL-3.0 License.</p><p class="copyright" data-v-9f6e1f5c>Copyright © 2026 Sajjad Ali</p></div></footer><!--[--><!--]--></div></div>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"api.md\":\"Dq0npsCa\",\"configuration.md\":\"BsBeukw7\",\"development.md\":\"C4QAiDqM\",\"faq.md\":\"BhPUjBTn\",\"features.md\":\"C4hW69V4\",\"how-it-works.md\":\"CLbxPRcv\",\"index.md\":\"CCJ_uVDf\",\"installation.md\":\"BJPcu2wc\",\"media-processing.md\":\"BZnAue5X\",\"quick-start.md\":\"Bi2ZqhxJ\",\"security.md\":\"BwkL2X-x\",\"troubleshooting.md\":\"c84mph4l\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Foldergram\",\"description\":\"Documentation for Foldergram, the local-first photo and video gallery.\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"logo\":\"/logo.svg\",\"siteTitle\":\"Foldergram\",\"search\":{\"provider\":\"local\"},\"nav\":[{\"text\":\"Quick Start\",\"link\":\"/quick-start\"},{\"text\":\"Installation\",\"link\":\"/installation\"},{\"text\":\"Configuration\",\"link\":\"/configuration\"},{\"text\":\"How It Works\",\"link\":\"/how-it-works\"},{\"text\":\"API\",\"link\":\"/api\"},{\"text\":\"Security\",\"link\":\"/security\"},{\"text\":\"Demo\",\"link\":\"https://foldergram.intentdeep.com/\"}],\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/foldergram/foldergram\"}],\"sidebar\":[{\"text\":\"Guide\",\"items\":[{\"text\":\"Quick Start\",\"link\":\"/quick-start\"},{\"text\":\"Installation\",\"link\":\"/installation\"},{\"text\":\"Configuration\",\"link\":\"/configuration\"}]},{\"text\":\"Product\",\"items\":[{\"text\":\"How It Works\",\"link\":\"/how-it-works\"},{\"text\":\"Features\",\"link\":\"/features\"},{\"text\":\"Media Processing\",\"link\":\"/media-processing\"},{\"text\":\"Security\",\"link\":\"/security\"}]},{\"text\":\"Reference\",\"items\":[{\"text\":\"API\",\"link\":\"/api\"},{\"text\":\"Development\",\"link\":\"/development\"},{\"text\":\"Troubleshooting\",\"link\":\"/troubleshooting\"},{\"text\":\"FAQ\",\"link\":\"/faq\"}]}],\"outline\":{\"level\":[2,3],\"label\":\"On this page\"},\"footer\":{\"message\":\"Released under the AGPL-3.0 License.\",\"copyright\":\"Copyright © 2026 Sajjad Ali\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":true}");</script>
</body>
</html>