feat(config): hot-reload safe config updates and document behavior

This commit is contained in:
2026-02-18 01:04:56 -08:00
parent fd49e73762
commit 4703b995da
18 changed files with 850 additions and 85 deletions

View File

@@ -5,6 +5,7 @@
* Copy to $XDG_CONFIG_HOME/SubMiner/config.jsonc (or ~/.config/SubMiner/config.jsonc) and edit as needed.
*/
{
// ==========================================
// Overlay Auto-Start
// When overlay connects to mpv, automatically show overlay and hide mpv subtitles.
@@ -23,7 +24,7 @@
// Control whether browser opens automatically for texthooker.
// ==========================================
"texthooker": {
"openBrowser": true,
"openBrowser": true
},
// ==========================================
@@ -33,7 +34,7 @@
// ==========================================
"websocket": {
"enabled": "auto",
"port": 6677,
"port": 6677
},
// ==========================================
@@ -42,12 +43,14 @@
// Set to debug for full runtime diagnostics.
// ==========================================
"logging": {
"level": "info",
"level": "info"
},
// ==========================================
// AnkiConnect Integration
// Automatic Anki updates and media generation options.
// Hot-reload: AI translation settings update live while SubMiner is running.
// Most other AnkiConnect settings still require restart.
// ==========================================
"ankiConnect": {
"enabled": false,
@@ -58,7 +61,7 @@
"image": "Picture",
"sentence": "Sentence",
"miscInfo": "MiscInfo",
"translation": "SelectionText",
"translation": "SelectionText"
},
"ai": {
"enabled": false,
@@ -67,7 +70,7 @@
"model": "openai/gpt-4o-mini",
"baseUrl": "https://openrouter.ai/api",
"targetLanguage": "English",
"systemPrompt": "You are a translation engine. Return only the translated text with no explanations.",
"systemPrompt": "You are a translation engine. Return only the translated text with no explanations."
},
"media": {
"generateAudio": true,
@@ -80,7 +83,7 @@
"animatedCrf": 35,
"audioPadding": 0.5,
"fallbackDuration": 3,
"maxMediaDuration": 30,
"maxMediaDuration": 30
},
"behavior": {
"overwriteAudio": true,
@@ -88,7 +91,7 @@
"mediaInsertMode": "append",
"highlightWord": true,
"notificationType": "osd",
"autoUpdateNewCards": true,
"autoUpdateNewCards": true
},
"nPlusOne": {
"highlightEnabled": false,
@@ -97,22 +100,22 @@
"decks": [],
"minSentenceWords": 3,
"nPlusOne": "#c6a0f6",
"knownWord": "#a6da95",
"knownWord": "#a6da95"
},
"metadata": {
"pattern": "[SubMiner] %f (%t)",
"pattern": "[SubMiner] %f (%t)"
},
"isLapis": {
"enabled": false,
"sentenceCardModel": "Japanese sentences",
"sentenceCardSentenceField": "Sentence",
"sentenceCardAudioField": "SentenceAudio",
"sentenceCardAudioField": "SentenceAudio"
},
"isKiku": {
"enabled": false,
"fieldGrouping": "disabled",
"deleteDuplicateInAuto": true,
},
"deleteDuplicateInAuto": true
}
},
// ==========================================
@@ -120,6 +123,7 @@
// Overlay keyboard shortcuts. Set a shortcut to null to disable.
// Fixed (non-configurable) overlay shortcuts:
// - Ctrl/Cmd+A: append clipboard video path to MPV playlist
// Hot-reload: shortcut changes apply live and update the session help modal on reopen.
// ==========================================
"shortcuts": {
"toggleVisibleOverlayGlobal": "Alt+Shift+O",
@@ -135,7 +139,7 @@
"toggleSecondarySub": "CommandOrControl+Shift+V",
"markAudioCard": "CommandOrControl+Shift+A",
"openRuntimeOptions": "CommandOrControl+Shift+O",
"openJimaku": "Ctrl+Shift+J",
"openJimaku": "Ctrl+Shift+J"
},
// ==========================================
@@ -145,19 +149,21 @@
// This edit-mode shortcut is fixed and is not currently configurable.
// ==========================================
"invisibleOverlay": {
"startupVisibility": "platform-default",
"startupVisibility": "platform-default"
},
// ==========================================
// Keybindings (MPV Commands)
// Extra keybindings that are merged with built-in defaults.
// Set command to null to disable a default keybinding.
// Hot-reload: keybinding changes apply live and update the session help modal on reopen.
// ==========================================
"keybindings": [],
// ==========================================
// Subtitle Appearance
// Primary and secondary subtitle styling.
// Hot-reload: subtitle style changes apply live without restarting SubMiner.
// ==========================================
"subtitleStyle": {
"enableJlpt": false,
@@ -174,7 +180,7 @@
"N2": "#f5a97f",
"N3": "#f9e2af",
"N4": "#a6e3a1",
"N5": "#8aadf4",
"N5": "#8aadf4"
},
"frequencyDictionary": {
"enabled": false,
@@ -182,7 +188,13 @@
"topX": 1000,
"mode": "single",
"singleColor": "#f5a97f",
"bandedColors": ["#ed8796", "#f5a97f", "#f9e2af", "#a6e3a1", "#8aadf4"],
"bandedColors": [
"#ed8796",
"#f5a97f",
"#f9e2af",
"#a6e3a1",
"#8aadf4"
]
},
"secondary": {
"fontSize": 24,
@@ -190,19 +202,20 @@
"backgroundColor": "transparent",
"fontWeight": "normal",
"fontStyle": "normal",
"fontFamily": "Noto Sans CJK JP Regular, Noto Sans CJK JP, Arial Unicode MS, Arial, sans-serif",
},
"fontFamily": "Noto Sans CJK JP Regular, Noto Sans CJK JP, Arial Unicode MS, Arial, sans-serif"
}
},
// ==========================================
// Secondary Subtitles
// Dual subtitle track options.
// Used by subminer YouTube subtitle generation as secondary language preferences.
// Hot-reload: defaultMode updates live while SubMiner is running.
// ==========================================
"secondarySub": {
"secondarySubLanguages": [],
"autoLoadSecondarySub": false,
"defaultMode": "hover",
"defaultMode": "hover"
},
// ==========================================
@@ -213,7 +226,7 @@
"defaultMode": "auto",
"alass_path": "",
"ffsubsync_path": "",
"ffmpeg_path": "",
"ffmpeg_path": ""
},
// ==========================================
@@ -221,7 +234,7 @@
// Initial vertical subtitle position from the bottom.
// ==========================================
"subtitlePosition": {
"yPercent": 10,
"yPercent": 10
},
// ==========================================
@@ -231,7 +244,7 @@
"jimaku": {
"apiBaseUrl": "https://jimaku.cc",
"languagePreference": "ja",
"maxEntryResults": 10,
"maxEntryResults": 10
},
// ==========================================
@@ -242,7 +255,10 @@
"mode": "automatic",
"whisperBin": "",
"whisperModel": "",
"primarySubLanguages": ["ja", "jpn"],
"primarySubLanguages": [
"ja",
"jpn"
]
},
// ==========================================
@@ -251,7 +267,7 @@
// ==========================================
"anilist": {
"enabled": false,
"accessToken": "",
"accessToken": ""
},
// ==========================================
@@ -276,8 +292,16 @@
"pullPictures": false,
"iconCacheDir": "/tmp/subminer-jellyfin-icons",
"directPlayPreferred": true,
"directPlayContainers": ["mkv", "mp4", "webm", "mov", "flac", "mp3", "aac"],
"transcodeVideoCodec": "h264",
"directPlayContainers": [
"mkv",
"mp4",
"webm",
"mov",
"flac",
"mp3",
"aac"
],
"transcodeVideoCodec": "h264"
},
// ==========================================
@@ -299,7 +323,7 @@
"telemetryDays": 30,
"dailyRollupsDays": 365,
"monthlyRollupsDays": 1825,
"vacuumIntervalDays": 7,
},
},
"vacuumIntervalDays": 7
}
}
}