Presets allow you to save conversion configurations as reusable profiles. Frame includes built-in presets for common use cases and supports custom user-defined presets.
Preset Structure
A preset contains a complete conversion configuration:
interface PresetDefinition {
id : string ; // Unique identifier (UUID for custom presets)
name : string ; // Display name
config : ConversionConfig ; // Complete conversion settings
builtIn ?: boolean ; // True for built-in presets (read-only)
}
Type definition (types.ts:131-136):
export interface PresetDefinition {
id : string ;
name : string ;
config : ConversionConfig ;
builtIn ?: boolean ;
}
Built-in Presets
Frame includes 15 built-in presets covering common conversion scenarios (presets.ts:9-633).
General Purpose
ID: balanced-mp4General-purpose H.264 encoding with balanced quality and file size. {
container : 'mp4' ,
videoCodec : 'libx264' ,
videoBitrateMode : 'crf' ,
crf : 23 ,
preset : 'medium' ,
audioCodec : 'aac' ,
audioBitrate : '128'
}
ID: archive-hqHigh-quality H.265 encoding for long-term storage with excellent compression. {
container : 'mkv' ,
videoCodec : 'libx265' ,
videoBitrateMode : 'crf' ,
crf : 18 ,
preset : 'slow' ,
audioCodec : 'ac3' ,
audioBitrate : '192' ,
scalingAlgorithm : 'lanczos'
}
ID: web-shareWebM format with VP9 and Opus for web compatibility. {
container : 'webm' ,
videoCodec : 'vp9' ,
videoBitrateMode : 'crf' ,
crf : 30 ,
resolution : '720p' ,
audioCodec : 'libopus' ,
audioBitrate : '96' ,
audioChannels : 'stereo'
}
GIF Presets
ID: gif-web-smallOptimized for web use with reduced dimensions and color palette. {
container : 'gif' ,
resolution : 'custom' ,
customWidth : '640' ,
customHeight : '360' ,
fps : '12' ,
gifColors : 128 ,
gifDither : 'sierra2_4a'
}
ID: gif-qualityHigher quality with full color palette and better dithering. {
container : 'gif' ,
resolution : '720p' ,
fps : '15' ,
gifColors : 256 ,
gifDither : 'floyd_steinberg'
}
Audio-Only Presets
ID: audio-onlyStandard MP3 audio extraction. {
container : 'mp3' ,
audioCodec : 'mp3' ,
audioBitrate : '128' ,
audioChannels : 'stereo'
}
ID: audio-flacLossless audio compression. {
container : 'flac' ,
audioCodec : 'flac' ,
audioChannels : 'original'
}
ID: audio-alacApple Lossless for iTunes/Apple ecosystem. {
container : 'm4a' ,
audioCodec : 'alac' ,
audioChannels : 'original'
}
ID: audio-wavUncompressed PCM audio. {
container : 'wav' ,
audioCodec : 'pcm_s16le' ,
audioChannels : 'original'
}
Social Media Presets
ID: social-tiktokVertical video format optimized for TikTok, Instagram Reels, YouTube Shorts. {
container : 'mp4' ,
videoCodec : 'libx264' ,
videoBitrateMode : 'bitrate' ,
videoBitrate : '6000' ,
resolution : 'custom' ,
customWidth : '1080' ,
customHeight : '1920' ,
fps : '30' ,
audioNormalize : true ,
scalingAlgorithm : 'lanczos' ,
preset : 'slow'
}
ID: yt-1080pOptimized for YouTube 1080p uploads. {
container : 'mp4' ,
videoCodec : 'libx264' ,
videoBitrateMode : 'bitrate' ,
videoBitrate : '10000' ,
resolution : '1080p' ,
audioCodec : 'aac' ,
audioBitrate : '320' ,
audioNormalize : true ,
preset : 'slow'
}
ID: yt-4kHigh bitrate 4K for YouTube. {
container : 'mp4' ,
videoCodec : 'libx264' ,
videoBitrateMode : 'bitrate' ,
videoBitrate : '40000' ,
resolution : 'custom' ,
customWidth : '3840' ,
customHeight : '2160' ,
audioCodec : 'aac' ,
audioBitrate : '320' ,
audioNormalize : true ,
preset : 'slow'
}
ID: x-landscapeOptimized for Twitter/X landscape videos. {
container : 'mp4' ,
videoCodec : 'libx264' ,
videoBitrateMode : 'bitrate' ,
videoBitrate : '2500' ,
resolution : '720p' ,
fps : '30' ,
audioNormalize : true
}
ID: x-portraitVertical format for Twitter/X mobile. {
container : 'mp4' ,
videoCodec : 'libx264' ,
videoBitrateMode : 'bitrate' ,
videoBitrate : '2000' ,
resolution : 'custom' ,
customWidth : '720' ,
customHeight : '1280' ,
fps : '30' ,
audioNormalize : true
}
ID: discordOptimized for Discord’s 8MB free tier upload limit. {
container : 'mp4' ,
videoCodec : 'libx264' ,
videoBitrateMode : 'bitrate' ,
videoBitrate : '1000' ,
resolution : '720p' ,
fps : '30' ,
audioCodec : 'aac' ,
audioBitrate : '64' ,
audioNormalize : true ,
preset : 'veryfast'
}
Default Preset Configuration
The default configuration is based on the “Balanced MP4” preset:
Implementation (presets.ts:678-680):
export function getDefaultConfig () : ConversionConfig {
return cloneConfig ( DEFAULT_PRESETS [ 0 ]. config );
}
Custom Presets
Creating Custom Presets
Create a custom preset from the current configuration:
import { createCustomPreset } from '$lib/services/presets' ;
const preset = createCustomPreset ( 'My Custom Preset' , currentConfig );
// Returns:
// {
// id: 'uuid-v4',
// name: 'My Custom Preset',
// config: { ...currentConfig }
// }
Implementation (presets.ts:666-672):
export function createCustomPreset ( name : string , config : ConversionConfig ) : PresetDefinition {
return {
id: uuidv4 (),
name: name . trim () || 'Untitled Preset' ,
config: cloneConfig ( config )
};
}
Saving Custom Presets
Custom presets are persisted to disk using Tauri’s plugin-store:
import { saveCustomPresets } from '$lib/services/presets' ;
await saveCustomPresets ([ preset1 , preset2 , preset3 ]);
Implementation (presets.ts:660-664):
export async function saveCustomPresets ( presets : PresetDefinition []) : Promise < void > {
const store = await getStore ();
await store . set ( PRESETS_KEY , presets );
await store . save ();
}
Storage location:
Path: presets.dat in the app data directory
Format: JSON serialized preset definitions
Key: presets (constant: PRESETS_KEY)
Loading Custom Presets
import { loadCustomPresets } from '$lib/services/presets' ;
const customPresets = await loadCustomPresets ();
// Returns: PresetDefinition[]
Implementation (presets.ts:649-658):
export async function loadCustomPresets () : Promise < PresetDefinition []> {
try {
const store = await getStore ();
const presets = await store . get < PresetDefinition []>( PRESETS_KEY );
return presets ?? [];
} catch ( error ) {
console . error ( 'Failed to load presets from store' , error );
return [];
}
}
Store Initialization
The preset store is lazily initialized with defaults:
Implementation (presets.ts:635-647):
const STORE_PATH = 'presets.dat' ;
const PRESETS_KEY = 'presets' ;
let storePromise : Promise < Store > | null = null ;
async function getStore () : Promise < Store > {
if ( ! storePromise ) {
storePromise = Store . load ( STORE_PATH , {
defaults: {
[ PRESETS_KEY ]: []
}
});
}
return storePromise ;
}
Configuration Cloning
Presets use deep cloning to prevent mutations:
Implementation (presets.ts:674-676):
export function cloneConfig ( config : ConversionConfig ) : ConversionConfig {
return JSON . parse ( JSON . stringify ( config ));
}
Cloning ensures that modifying a preset doesn’t affect the original configuration or other presets.
Usage in Application
Presets are typically used through the usePresets feature hook:
import { usePresets } from '$lib/features/conversion/usePresets.svelte' ;
const presets = usePresets ();
// Access all presets (built-in + custom)
const allPresets = presets . all ; // PresetDefinition[]
// Access only custom presets
const customPresets = presets . custom ; // PresetDefinition[]
// Apply a preset to current configuration
presets . apply ( presetId );
// Save current config as preset
presets . saveAs ( 'My Preset Name' );
// Delete a custom preset
presets . delete ( presetId );
Example: Creating a Preset Programmatically
import { createCustomPreset , saveCustomPresets , loadCustomPresets } from '$lib/services/presets' ;
import { getDefaultConfig } from '$lib/services/presets' ;
// Start with default config
const config = getDefaultConfig ();
// Customize settings
config . container = 'mp4' ;
config . videoCodec = 'libx265' ;
config . videoBitrateMode = 'crf' ;
config . crf = 20 ;
config . resolution = '1080p' ;
config . audioCodec = 'aac' ;
config . audioBitrate = '192' ;
config . audioNormalize = true ;
// Create preset
const preset = createCustomPreset ( 'My H.265 Profile' , config );
// Load existing custom presets
const existing = await loadCustomPresets ();
// Add new preset and save
await saveCustomPresets ([ ... existing , preset ]);
Preset Best Practices
Descriptive Names Use clear, descriptive names that indicate the preset’s purpose (e.g., “YouTube 1080p” instead of “Preset 1”).
Version Control For team workflows, export presets to JSON and version control them.
Platform-Specific Create separate presets for each target platform (YouTube, TikTok, etc.).
Quality Tiers Maintain presets for different quality levels (low, medium, high, archive).
Importing/Exporting Presets
While Frame doesn’t provide built-in import/export UI, presets can be shared by:
Accessing the store file directly:
Location: App data directory presets.dat
Format: JSON
Programmatic export:
const presets = await loadCustomPresets ();
const json = JSON . stringify ( presets , null , 2 );
// Write to file or clipboard
Programmatic import:
const importedPresets = JSON . parse ( jsonString );
const existing = await loadCustomPresets ();
await saveCustomPresets ([ ... existing , ... importedPresets ]);
Related Features
Video Conversion Configure video encoding settings
Audio Conversion Configure audio encoding settings
Batch Processing Apply presets to multiple files
social-tiktokVertical video format optimized for TikTok, Instagram Reels, YouTube Shorts.