feat: ConvertGUI v2.0 (Wails + preview/trim + NSIS + Gitea CI)
Build Windows Installer / build (push) Successful in 4m11s

This commit is contained in:
m4xx1m committed 2026-11-12 17:30:44 +03:00
1 parent 02fd1dc817
commit 65387c5dcd
40 files changed
+6084 -266

No files matched your search

+84
View File
@@ -0,0 +1,84 @@
package config
import (
"encoding/json"
"os"
"path/filepath"
)
type AppConfig struct {
Language string `json:"language"` // "ru" or "en"
FFmpegPath string `json:"ffmpegPath"`
FFprobePath string `json:"ffprobePath"`
DefaultEncoder string `json:"defaultEncoder"` // libx264, h264_nvenc, libx265, hevc_nvenc
DefaultHwDecode string `json:"defaultHwDecode"`
DefaultPreset string `json:"defaultPreset"`
DefaultCRF int `json:"defaultCrf"`
DefaultFPS int `json:"defaultFps"` // 0 = original, 60 = 60fps
DefaultTune string `json:"defaultTune"`
DefaultMergeAudio bool `json:"defaultMergeAudio"`
OutputSuffix string `json:"outputSuffix"`
}
func Default() AppConfig {
return AppConfig{
Language: "ru",
DefaultEncoder: "libx264",
DefaultHwDecode: "none",
DefaultPreset: "slow",
DefaultCRF: 20,
DefaultFPS: 60,
DefaultTune: "film",
DefaultMergeAudio: true,
OutputSuffix: "_converted",
}
}
func ConfigPath() (string, error) {
dir, err := os.UserConfigDir()
if err != nil {
return "", err
}
return filepath.Join(dir, "ConvertGUI", "config.json"), nil
}
func Load() AppConfig {
cfg := Default()
path, err := ConfigPath()
if err != nil {
return cfg
}
data, err := os.ReadFile(path)
if err != nil {
return cfg
}
_ = json.Unmarshal(data, &cfg)
if cfg.Language == "" {
cfg.Language = "ru"
}
if cfg.DefaultEncoder == "" {
cfg.DefaultEncoder = "libx264"
}
if cfg.DefaultPreset == "" {
cfg.DefaultPreset = "slow"
}
if cfg.DefaultCRF < 0 || cfg.DefaultCRF > 51 {
cfg.DefaultCRF = 20
}
return cfg
}
func Save(cfg AppConfig) error {
path, err := ConfigPath()
if err != nil {
return err
}
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return err
}
data, err := json.MarshalIndent(cfg, "", " ")
if err != nil {
return err
}
return os.WriteFile(path, data, 0o644)
}
+42
View File
@@ -0,0 +1,42 @@
package config
import (
"os"
"path/filepath"
"testing"
)
func TestLoadDefaultsAndCRFClamp(t *testing.T) {
tmp := t.TempDir()
t.Setenv("APPDATA", tmp)
t.Setenv("XDG_CONFIG_HOME", tmp)
cfg := Default()
if cfg.DefaultCRF != 20 || cfg.DefaultPreset != "slow" || cfg.Language != "ru" {
t.Fatalf("unexpected defaults: %+v", cfg)
}
cfg.DefaultCRF = 99
if err := Save(cfg); err != nil {
t.Fatalf("save failed: %v", err)
}
loaded := Load()
if loaded.DefaultCRF != 20 {
t.Fatalf("expected invalid CRF 99 to reset to 20, got %d", loaded.DefaultCRF)
}
// CRF 0 (lossless) must be preserved
cfg.DefaultCRF = 0
if err := Save(cfg); err != nil {
t.Fatalf("save CRF 0 failed: %v", err)
}
loadedZero := Load()
if loadedZero.DefaultCRF != 0 {
t.Fatalf("expected CRF 0 to be preserved, got %d", loadedZero.DefaultCRF)
}
path, _ := ConfigPath()
if _, err := os.Stat(filepath.Clean(path)); err != nil {
t.Fatalf("config file missing: %v", err)
}
}