package disk import ( "encoding/json" "os" "path/filepath" ) type DiskProfile struct { DestFolder string `json:"dest_folder"` OverwriteMode string `json:"overwrite_mode"` FileSelectMode string `json:"file_select_mode"` ReserveFreeGB float64 `json:"reserve_free_gb"` AutoCopy bool `json:"auto_copy"` // ShuffleDepth: -1=выкл, 0=файлы вразнобой, 1+=папки на глубине N от корня /media ShuffleDepth int `json:"shuffle_depth"` // nil = не транскодировать видео Transcode *TranscodeProfile `json:"transcode,omitempty"` } type TranscodeProfile struct { VideoCodec string `json:"video_codec"` // "h264" | "h265" | "mpeg4" MaxResolution string `json:"max_resolution"` // "480p" | "720p" | "1080p" MaxVideoBitrate string `json:"max_video_bitrate"` // "1000k" | "2000k" | "" (без лимита) MaxFPS int `json:"max_fps"` // 0=без лимита | 24 | 25 | 30 AudioCodec string `json:"audio_codec"` // "aac" | "mp3" MaxAudioBitrate string `json:"max_audio_bitrate"` // "128k" | "192k" | "" MaxAudioChannels int `json:"max_audio_channels"` // 2=стерео | 6=5.1 OutputFormat string `json:"output_format"` // "mp4" | "mkv" | "avi" } const profileFile = "profile.json" func profilePath(mountPath string) string { return filepath.Join(mountPath, MarkerDir, profileFile) } func LoadProfile(mountPath string) (*DiskProfile, error) { data, err := os.ReadFile(profilePath(mountPath)) if err != nil { return nil, err } var p DiskProfile if err := json.Unmarshal(data, &p); err != nil { return nil, err } return &p, nil } func SaveProfile(mountPath string, p *DiskProfile) error { data, err := json.MarshalIndent(p, "", " ") if err != nil { return err } path := profilePath(mountPath) tmp := path + ".tmp" if err := os.WriteFile(tmp, data, 0o644); err != nil { return err } return os.Rename(tmp, path) } func DefaultProfile() *DiskProfile { return &DiskProfile{ DestFolder: "media", OverwriteMode: "skip", FileSelectMode: "new", ReserveFreeGB: 2.0, AutoCopy: false, ShuffleDepth: -1, } }