From b24155caf6c3f76ee63679ee86bf3f799c949237 Mon Sep 17 00:00:00 2001 From: Leonid Nikitin Date: Fri, 6 Jun 2025 14:50:16 +0500 Subject: [PATCH] Refactor application structure and initialize core components I decided to rewrite the program taking into account the experience gained. --- internal/application/app.go | 51 +++++++ internal/application/progressbar.go | 63 ++++++++ internal/application/setting/ffmpeg.go | 25 +++ internal/application/setting/lang.go | 66 ++++++++ internal/application/setting/setting.go | 65 ++++++++ internal/controller/convertor.go | 8 + internal/controller/error.go | 16 ++ internal/controller/main.go | 64 ++++++++ internal/ffmpeg/ffmpeg.go | 19 +++ internal/ffmpeg/ffplay.go | 19 +++ internal/ffmpeg/ffprobe.go | 19 +++ internal/ffmpeg/utilities.go | 48 ++++++ internal/gui/view/convertor.go | 33 ++++ internal/gui/view/error.go | 39 +++++ .../gui/view/start_without_support_lang.go | 28 ++++ internal/gui/window/main.go | 140 +++++++++++++++++ internal/resources/translation.go | 12 ++ internal/resources/translations/app.en.json | 143 ++++++++++++++++++ internal/resources/translations/app.kk.json | 143 ++++++++++++++++++ internal/resources/translations/app.ru.json | 143 ++++++++++++++++++ internal/resources/translations/base.en.json | 45 ++++++ internal/resources/translations/base.kk.json | 45 ++++++ internal/resources/translations/base.ru.json | 45 ++++++ main.go | 79 ++-------- 24 files changed, 1295 insertions(+), 63 deletions(-) create mode 100644 internal/application/app.go create mode 100644 internal/application/progressbar.go create mode 100644 internal/application/setting/ffmpeg.go create mode 100644 internal/application/setting/lang.go create mode 100644 internal/application/setting/setting.go create mode 100644 internal/controller/convertor.go create mode 100644 internal/controller/error.go create mode 100644 internal/controller/main.go create mode 100644 internal/ffmpeg/ffmpeg.go create mode 100644 internal/ffmpeg/ffplay.go create mode 100644 internal/ffmpeg/ffprobe.go create mode 100644 internal/ffmpeg/utilities.go create mode 100644 internal/gui/view/convertor.go create mode 100644 internal/gui/view/error.go create mode 100644 internal/gui/view/start_without_support_lang.go create mode 100644 internal/gui/window/main.go create mode 100644 internal/resources/translation.go create mode 100644 internal/resources/translations/app.en.json create mode 100644 internal/resources/translations/app.kk.json create mode 100644 internal/resources/translations/app.ru.json create mode 100644 internal/resources/translations/base.en.json create mode 100644 internal/resources/translations/base.kk.json create mode 100644 internal/resources/translations/base.ru.json diff --git a/internal/application/app.go b/internal/application/app.go new file mode 100644 index 0000000..128c088 --- /dev/null +++ b/internal/application/app.go @@ -0,0 +1,51 @@ +package application + +import ( + "fyne.io/fyne/v2" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/setting" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg" +) + +type AppContract interface { + FyneApp() fyne.App + GetSetting() setting.SettingContract + GetProgressBarService() ProgressBarContract + GetFFmpegService() ffmpeg.UtilitiesContract + Run() +} + +type application struct { + fyneApp fyne.App + setting setting.SettingContract + progressBarService ProgressBarContract + ffmpegService ffmpeg.UtilitiesContract +} + +func NewApp(fyneApp fyne.App, setting setting.SettingContract, progressBarService ProgressBarContract, ffmpegService ffmpeg.UtilitiesContract) AppContract { + return &application{ + fyneApp: fyneApp, + setting: setting, + progressBarService: progressBarService, + ffmpegService: ffmpegService, + } +} + +func (a *application) FyneApp() fyne.App { + return a.fyneApp +} + +func (a *application) GetSetting() setting.SettingContract { + return a.setting +} + +func (a *application) GetProgressBarService() ProgressBarContract { + return a.progressBarService +} + +func (a *application) GetFFmpegService() ffmpeg.UtilitiesContract { + return a.ffmpegService +} + +func (a *application) Run() { + a.fyneApp.Run() +} diff --git a/internal/application/progressbar.go b/internal/application/progressbar.go new file mode 100644 index 0000000..8890088 --- /dev/null +++ b/internal/application/progressbar.go @@ -0,0 +1,63 @@ +package application + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/canvas" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/theme" + "fyne.io/fyne/v2/widget" +) + +type ProgressBarContract interface { + GetContainer() *fyne.Container +} + +type progressBar struct { + container *fyne.Container + label *widget.Label + progressbar *widget.ProgressBar + errorBlock *container.Scroll + messageError *canvas.Text + statusMessage *canvas.Text + buttonPlay *widget.Button +} + +func NewProgressBar() ProgressBarContract { + label := widget.NewLabel("") + progressbar := widget.NewProgressBar() + + statusMessage := canvas.NewText("", theme.Color(theme.ColorNamePrimary)) + messageError := canvas.NewText("", theme.Color(theme.ColorNameError)) + buttonPlay := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() { + + }) + buttonPlay.Hide() + + errorBlock := container.NewHScroll(messageError) + errorBlock.Hide() + + content := container.NewVBox( + container.NewHScroll(label), + progressbar, + container.NewHScroll(container.NewHBox( + buttonPlay, + statusMessage, + )), + errorBlock, + ) + content.Hide() + + return &progressBar{ + container: content, + label: label, + progressbar: progressbar, + errorBlock: errorBlock, + messageError: messageError, + statusMessage: statusMessage, + buttonPlay: buttonPlay, + } +} + +func (p *progressBar) GetContainer() *fyne.Container { + return p.container +} diff --git a/internal/application/setting/ffmpeg.go b/internal/application/setting/ffmpeg.go new file mode 100644 index 0000000..84f0789 --- /dev/null +++ b/internal/application/setting/ffmpeg.go @@ -0,0 +1,25 @@ +package setting + +func (s *setting) GetFFmpegPath() string { + return s.fyneApp.Preferences().String("ffmpegPath") +} + +func (s *setting) SetFFmpegPath(path string) { + s.fyneApp.Preferences().SetString("ffmpegPath", path) +} + +func (s *setting) GetFFprobePath() string { + return s.fyneApp.Preferences().String("ffprobePath") +} + +func (s *setting) SetFFprobePath(path string) { + s.fyneApp.Preferences().SetString("ffprobePath", path) +} + +func (s *setting) GetFFplayPath() string { + return s.fyneApp.Preferences().String("ffplayPath") +} + +func (s *setting) SetFFplayPath(path string) { + s.fyneApp.Preferences().SetString("ffplayPath", path) +} diff --git a/internal/application/setting/lang.go b/internal/application/setting/lang.go new file mode 100644 index 0000000..f7bf953 --- /dev/null +++ b/internal/application/setting/lang.go @@ -0,0 +1,66 @@ +package setting + +import ( + "encoding/json" + "fyne.io/fyne/v2" + fyneLang "fyne.io/fyne/v2/lang" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/resources" +) + +var supportedLanguages = map[string]Lang{ + "ru": {Code: "ru", Title: "Русский"}, + "kk": {Code: "kk", Title: "Қазақ Тілі"}, + "en": {Code: "en", Title: "English"}, +} + +type Lang struct { + Code string + Title string +} + +func ChangeLang(lang Lang) error { + translationsData, err := getTranslations(lang) + if err != nil { + return err + } + + name := fyneLang.SystemLocale().LanguageString() + return fyneLang.AddTranslations(fyne.NewStaticResource(name+".json", translationsData)) +} + +func defaultLang() Lang { + return supportedLanguages["ru"] +} + +func getTranslations(language Lang) ([]byte, error) { + translations := resources.GetTranslations() + + baseJson, err := translations.ReadFile("translations/base." + language.Code + ".json") + if err != nil { + return nil, err + } + appJson, err := translations.ReadFile("translations/app." + language.Code + ".json") + if err != nil { + return nil, err + } + + return mergeTranslations(baseJson, appJson) +} + +func mergeTranslations(baseJson []byte, appJson []byte) ([]byte, error) { + base := map[string]interface{}{} + custom := map[string]interface{}{} + err := json.Unmarshal(baseJson, &base) + if err != nil { + return nil, err + } + err = json.Unmarshal(appJson, &custom) + if err != nil { + return nil, err + } + + for k, v := range custom { + base[k] = v + } + return json.Marshal(base) +} diff --git a/internal/application/setting/setting.go b/internal/application/setting/setting.go new file mode 100644 index 0000000..d10d324 --- /dev/null +++ b/internal/application/setting/setting.go @@ -0,0 +1,65 @@ +package setting + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/lang" + "golang.org/x/text/language" +) + +type SettingContract interface { + GetLanguages() []Lang + GetCurrentLangOrDefaultLang() (currentLang Lang, isDefault bool) + SetLang(language Lang) error + GetFFmpegPath() string + SetFFmpegPath(path string) + GetFFprobePath() string + SetFFprobePath(path string) + GetFFplayPath() string + SetFFplayPath(path string) +} + +type setting struct { + fyneApp fyne.App +} + +func NewSetting(fyneApp fyne.App) SettingContract { + return &setting{ + fyneApp: fyneApp, + } +} + +func (s *setting) GetLanguages() []Lang { + items := []Lang{} + for _, item := range supportedLanguages { + items = append(items, item) + } + return items +} + +func (s *setting) GetCurrentLangOrDefaultLang() (currentLang Lang, isDefault bool) { + languageCode := s.fyneApp.Preferences().String("language") + + if languageCode == "" { + languageTag, err := language.Parse(lang.SystemLocale().LanguageString()) + if err != nil { + return currentLang, true + } + base, _ := languageTag.Base() + languageCode = base.String() + } + + if currentLang, ok := supportedLanguages[languageCode]; ok { + return currentLang, false + } + + return defaultLang(), true +} + +func (s *setting) SetLang(language Lang) error { + err := ChangeLang(language) + if err != nil { + return err + } + s.fyneApp.Preferences().SetString("language", language.Code) + return nil +} diff --git a/internal/controller/convertor.go b/internal/controller/convertor.go new file mode 100644 index 0000000..1b6ccdc --- /dev/null +++ b/internal/controller/convertor.go @@ -0,0 +1,8 @@ +package controller + +import "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view" + +func (c *controller) convertor() { + content := view.Convertor() + c.window.SetContent(content) +} diff --git a/internal/controller/error.go b/internal/controller/error.go new file mode 100644 index 0000000..0f66887 --- /dev/null +++ b/internal/controller/error.go @@ -0,0 +1,16 @@ +package controller + +import ( + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/setting" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view" +) + +func (c *controller) startWithError(err error) { + languages := c.app.GetSetting().GetLanguages() + + content := view.StartWithError(err, languages, func(lang setting.Lang) { + _ = setting.ChangeLang(lang) + c.startWithError(err) + }) + c.window.SetContent(content) +} diff --git a/internal/controller/main.go b/internal/controller/main.go new file mode 100644 index 0000000..2e5832a --- /dev/null +++ b/internal/controller/main.go @@ -0,0 +1,64 @@ +package controller + +import ( + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/setting" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/window" +) + +type ControllerContract interface { + Start() +} + +type controller struct { + app application.AppContract + window window.MainWindowContract +} + +func NewController(app application.AppContract) ControllerContract { + fyneWindow := app.FyneApp().NewWindow(app.FyneApp().Metadata().Name) + + return &controller{ + app: app, + window: window.NewMainWindow(fyneWindow, app.GetProgressBarService()), + } +} + +func (c *controller) Start() { + c.window.Show() + + isDefault, err := c.initLanguage() + if err != nil { + c.startWithError(err) + return + } + + if isDefault { + languages := c.app.GetSetting().GetLanguages() + content := view.StartWithoutSupportLang(languages, func(lang setting.Lang) { + err = c.app.GetSetting().SetLang(lang) + if err != nil { + c.startWithError(err) + return + } + c.window.InitLayout() + c.verificareaFFmpeg() + }) + c.window.SetContent(content) + return + } + + c.window.InitLayout() + c.verificareaFFmpeg() +} + +func (c *controller) verificareaFFmpeg() { + c.convertor() +} + +func (c *controller) initLanguage() (isDefault bool, err error) { + lang, isDefault := c.app.GetSetting().GetCurrentLangOrDefaultLang() + err = setting.ChangeLang(lang) + return isDefault, err +} diff --git a/internal/ffmpeg/ffmpeg.go b/internal/ffmpeg/ffmpeg.go new file mode 100644 index 0000000..c7e3019 --- /dev/null +++ b/internal/ffmpeg/ffmpeg.go @@ -0,0 +1,19 @@ +package ffmpeg + +type FFmpegContract interface { + SetPath(path string) +} + +type ffmpeg struct { + path string +} + +func newFFmpeg(path string) FFmpegContract { + return &ffmpeg{ + path: path, + } +} + +func (f *ffmpeg) SetPath(path string) { + f.path = path +} diff --git a/internal/ffmpeg/ffplay.go b/internal/ffmpeg/ffplay.go new file mode 100644 index 0000000..105359f --- /dev/null +++ b/internal/ffmpeg/ffplay.go @@ -0,0 +1,19 @@ +package ffmpeg + +type FFplayContract interface { + SetPath(path string) +} + +type ffplay struct { + path string +} + +func newFFplay(path string) FFplayContract { + return &ffplay{ + path: path, + } +} + +func (f *ffplay) SetPath(path string) { + f.path = path +} diff --git a/internal/ffmpeg/ffprobe.go b/internal/ffmpeg/ffprobe.go new file mode 100644 index 0000000..ee8d9c8 --- /dev/null +++ b/internal/ffmpeg/ffprobe.go @@ -0,0 +1,19 @@ +package ffmpeg + +type FFprobeContract interface { + SetPath(path string) +} + +type ffprobe struct { + path string +} + +func newFFprobe(path string) FFprobeContract { + return &ffprobe{ + path: path, + } +} + +func (f *ffprobe) SetPath(path string) { + f.path = path +} diff --git a/internal/ffmpeg/utilities.go b/internal/ffmpeg/utilities.go new file mode 100644 index 0000000..309019d --- /dev/null +++ b/internal/ffmpeg/utilities.go @@ -0,0 +1,48 @@ +package ffmpeg + +import ( + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/setting" +) + +type UtilitiesContract interface { + GetFFmpeg() FFmpegContract + GetFFprobe() FFprobeContract + GetFFplay() FFplayContract +} + +type utilities struct { + setting setting.SettingContract + ffmpeg FFmpegContract + ffprobe FFprobeContract + ffplay FFplayContract +} + +func NewUtilities(setting setting.SettingContract) UtilitiesContract { + return &utilities{ + setting: setting, + } +} + +func (u *utilities) GetFFmpeg() FFmpegContract { + if u.ffmpeg == nil { + u.ffmpeg = newFFmpeg(u.setting.GetFFmpegPath()) + } + + return u.ffmpeg +} + +func (u *utilities) GetFFprobe() FFprobeContract { + if u.ffprobe != nil { + u.ffprobe = newFFprobe(u.setting.GetFFprobePath()) + } + + return u.ffprobe +} + +func (u *utilities) GetFFplay() FFplayContract { + if u.ffplay == nil { + u.ffplay = newFFplay(u.setting.GetFFplayPath()) + } + + return u.ffplay +} diff --git a/internal/gui/view/convertor.go b/internal/gui/view/convertor.go new file mode 100644 index 0000000..db11d16 --- /dev/null +++ b/internal/gui/view/convertor.go @@ -0,0 +1,33 @@ +package view + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/lang" + "fyne.io/fyne/v2/widget" +) + +func Convertor() fyne.CanvasObject { + form := newFormConvertor() + + converterVideoFilesTitle := lang.L("converterVideoFilesTitle") + return widget.NewCard(converterVideoFilesTitle, "", container.NewVScroll(form.getForm())) +} + +type formConvertor struct { + form *widget.Form + items []*widget.FormItem +} + +func newFormConvertor() *formConvertor { + f := widget.NewForm() + f.SubmitText = lang.L("converterVideoFilesSubmitTitle") + + return &formConvertor{ + form: f, + } +} + +func (f *formConvertor) getForm() *widget.Form { + return f.form +} diff --git a/internal/gui/view/error.go b/internal/gui/view/error.go new file mode 100644 index 0000000..f1860e3 --- /dev/null +++ b/internal/gui/view/error.go @@ -0,0 +1,39 @@ +package view + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/lang" + "fyne.io/fyne/v2/widget" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/setting" +) + +func StartWithError(err error, languages []setting.Lang, funcSelected func(lang setting.Lang)) fyne.CanvasObject { + messageHead := lang.L("error") + + listView := widget.NewList( + func() int { + return len(languages) + }, + func() fyne.CanvasObject { + return widget.NewLabel("template") + }, + func(i widget.ListItemID, o fyne.CanvasObject) { + block := o.(*widget.Label) + block.SetText(languages[i].Title) + }) + listView.OnSelected = func(id widget.ListItemID) { + funcSelected(languages[id]) + } + + return container.NewBorder( + container.NewVBox( + widget.NewLabel(messageHead), + widget.NewLabel(err.Error()), + ), + nil, + nil, + nil, + listView, + ) +} diff --git a/internal/gui/view/start_without_support_lang.go b/internal/gui/view/start_without_support_lang.go new file mode 100644 index 0000000..6d9a3e3 --- /dev/null +++ b/internal/gui/view/start_without_support_lang.go @@ -0,0 +1,28 @@ +package view + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/lang" + "fyne.io/fyne/v2/widget" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/setting" +) + +func StartWithoutSupportLang(languages []setting.Lang, funcSelected func(lang setting.Lang)) fyne.CanvasObject { + listView := widget.NewList( + func() int { + return len(languages) + }, + func() fyne.CanvasObject { + return widget.NewLabel("template") + }, + func(i widget.ListItemID, o fyne.CanvasObject) { + block := o.(*widget.Label) + block.SetText(languages[i].Title) + }) + listView.OnSelected = func(id widget.ListItemID) { + funcSelected(languages[id]) + } + + messageHead := lang.L("languageSelectionHead") + return widget.NewCard(messageHead, "", listView) +} diff --git a/internal/gui/window/main.go b/internal/gui/window/main.go new file mode 100644 index 0000000..77f8e51 --- /dev/null +++ b/internal/gui/window/main.go @@ -0,0 +1,140 @@ +package window + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/lang" + "fyne.io/fyne/v2/widget" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application" +) + +type MainWindowContract interface { + SetContent(content fyne.CanvasObject) + Show() + InitLayout() +} + +type mainWindow struct { + fyneWindow fyne.Window + layout *fyne.Container + progressBarService application.ProgressBarContract +} + +func NewMainWindow(fyneWindow fyne.Window, progressBarService application.ProgressBarContract) MainWindowContract { + fyneWindow.Resize(fyne.Size{Width: 1039, Height: 599}) + fyneWindow.CenterOnScreen() + + return &mainWindow{ + fyneWindow: fyneWindow, + progressBarService: progressBarService, + } +} + +func (w *mainWindow) InitLayout() { + fyne.Do(func() { + rContainer := newRightContainer(w.progressBarService.GetContainer()) + layout := container.NewAdaptiveGrid(2, widget.NewLabel(""), rContainer.GetCanvasObject()) + w.fyneWindow.SetContent(layout) + + w.layout = layout + }) +} + +func (w *mainWindow) SetContent(content fyne.CanvasObject) { + fyne.Do(func() { + if w.layout == nil { + w.fyneWindow.SetContent(content) + return + } + + w.layout.Objects[0] = content + w.fyneWindow.SetContent(w.layout) + }) +} + +func (w *mainWindow) Show() { + w.fyneWindow.Show() +} + +type RightMainContainerContract interface { + GetCanvasObject() fyne.CanvasObject + GetTabs() *container.AppTabs + GetAddedFilesContainer() *fyne.Container + GetFileQueueContainer() *fyne.Container + SelectFileQueueTab() + SelectAddedFilesTab() +} + +type rightMainContainer struct { + container fyne.CanvasObject + + tabs *container.AppTabs + + addedFilesContainer *fyne.Container + addedFilesTab *container.TabItem + + fileQueueContainer *fyne.Container + fileQueueTab *container.TabItem +} + +func newRightContainer(blockProgressbar *fyne.Container) RightMainContainerContract { + + addedFilesContainer := container.NewVBox() + addedFilesTab := container.NewTabItem(lang.L("addedFilesTitle"), addedFilesContainer) + + fileQueueContainer := container.NewVBox() + fileQueueTab := container.NewTabItem(lang.L("fileQueueTitle"), fileQueueContainer) + + tabs := container.NewAppTabs( + addedFilesTab, + fileQueueTab, + ) + + rightContainer := container.NewBorder( + container.NewVBox( + blockProgressbar, + widget.NewSeparator(), + ), + nil, + nil, + nil, + tabs, + ) + + return &rightMainContainer{ + container: rightContainer, + tabs: tabs, + addedFilesContainer: addedFilesContainer, + addedFilesTab: addedFilesTab, + fileQueueContainer: fileQueueContainer, + fileQueueTab: fileQueueTab, + } +} + +func (r *rightMainContainer) GetCanvasObject() fyne.CanvasObject { + return r.container +} + +func (r *rightMainContainer) GetTabs() *container.AppTabs { + return r.tabs +} + +func (r *rightMainContainer) GetAddedFilesContainer() *fyne.Container { + return r.addedFilesContainer +} + +func (r *rightMainContainer) GetFileQueueContainer() *fyne.Container { + return r.fileQueueContainer +} + +func (r *rightMainContainer) SelectFileQueueTab() { + fyne.Do(func() { + r.tabs.Select(r.fileQueueTab) + }) +} + +func (r *rightMainContainer) SelectAddedFilesTab() { + fyne.Do(func() { + r.tabs.Select(r.addedFilesTab) + }) +} diff --git a/internal/resources/translation.go b/internal/resources/translation.go new file mode 100644 index 0000000..401a291 --- /dev/null +++ b/internal/resources/translation.go @@ -0,0 +1,12 @@ +package resources + +import ( + "embed" +) + +//go:embed translations +var translations embed.FS + +func GetTranslations() embed.FS { + return translations +} diff --git a/internal/resources/translations/app.en.json b/internal/resources/translations/app.en.json new file mode 100644 index 0000000..9919f8d --- /dev/null +++ b/internal/resources/translations/app.en.json @@ -0,0 +1,143 @@ +{ + "AlsoUsedProgram": "The program also uses:", + "about": "About", + "aboutText": "A simple interface for the FFmpeg console utility. \nBut I am not the author of the FFmpeg utility itself.", + "addedFilesTitle": "Added files", + "autoClearAfterAddingToQueue": "Auto-clear after adding to queue", + "buttonDownloadFFmpeg": "Download FFmpeg automatically", + "buttonForSelectedDirTitle": "Save to folder:", + "cancel": "Cancel", + "changeFFPath": "FFmpeg, FFprobe and FFplay", + "changeLanguage": "Change language", + "checkboxOverwriteOutputFilesTitle": "Allow file to be overwritten", + "choose": "choose", + "clearAll": "Clear List", + "completedQueue": "Completed", + "converterVideoFilesSubmitTitle": "Convert", + "converterVideoFilesTitle": "Video, audio and picture converter", + "download": "Download", + "downloadFFmpegFromSite": "Will be downloaded from the site:", + "downloadRun": "Downloading...", + "dragAndDropFiles": "drag and drop files", + "encoderGroupAudio": "Audio", + "encoderGroupImage": "Images", + "encoderGroupVideo": "Video", + "encoder_apng": "APNG image", + "encoder_bmp": "BMP image", + "encoder_flv": "FLV", + "encoder_gif": "GIF image", + "encoder_h264_nvenc": "H.264 with NVIDIA support", + "encoder_libmp3lame": "libmp3lame MP3 (MPEG audio layer 3)", + "encoder_libshine": "libshine MP3 (MPEG audio layer 3)", + "encoder_libtwolame": "libtwolame MP2 (MPEG audio layer 2)", + "encoder_libvpx": "libvpx VP8 (codec vp8)", + "encoder_libvpx-vp9": "libvpx VP9 (codec vp9)", + "encoder_libwebp": "libwebp WebP image", + "encoder_libwebp_anim": "libwebp_anim WebP image", + "encoder_libx264": "H.264 libx264", + "encoder_libx265": "H.265 libx265", + "encoder_libxvid": "libxvidcore MPEG-4 part 2", + "encoder_mjpeg": "MJPEG (Motion JPEG)", + "encoder_mp2": "MP2 (MPEG audio layer 2)", + "encoder_mp2fixed": "MP2 fixed point (MPEG audio layer 2)", + "encoder_mpeg1video": "MPEG-1", + "encoder_mpeg2video": "MPEG-2", + "encoder_mpeg4": "MPEG-4 part 2", + "encoder_msmpeg4": "MPEG-4 part 2 Microsoft variant version 3", + "encoder_msmpeg4v2": "MPEG-4 part 2 Microsoft variant version 2", + "encoder_msvideo1": "Microsoft Video-1", + "encoder_png": "PNG image", + "encoder_qtrle": "QuickTime Animation (RLE) video", + "encoder_sgi": "SGI image", + "encoder_tiff": "TIFF image", + "encoder_wmav1": "Windows Media Audio 1", + "encoder_wmav2": "Windows Media Audio 2", + "encoder_wmv1": "Windows Media Video 7", + "encoder_wmv2": "Windows Media Video 8", + "encoder_xbm": "XBM (X BitMap) image", + "error": "An error has occurred!", + "errorConverter": "Couldn't convert video", + "errorDragAndDropFile": "Not all files were added", + "errorFFmpeg": "this is not FFmpeg", + "errorFFmpegVersion": "Could not determine FFmpeg version", + "errorFFplay": "this is not FFplay", + "errorFFplayVersion": "Could not determine FFplay version", + "errorFFprobe": "this is not FFprobe", + "errorFFprobeVersion": "Failed to determine FFprobe version", + "errorNoFilesAddedForConversion": "There are no files to convert", + "errorQueue": "Error", + "errorSelectedEncoder": "Converter not selected", + "errorSelectedFolderSave": "No save folder selected!", + "errorSelectedFormat": "File extension not selected", + "exit": "Exit", + "ffmpegLGPL": "This software uses libraries from the **FFmpeg** project under the **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**.", + "ffmpegTrademark": "**FFmpeg** is a trademark of **[Fabrice Bellard](http://bellard.org/)**, originator of the **[FFmpeg](https://ffmpeg.org/about.html)** project.", + "fileForConversionTitle": "File:", + "fileQueueTitle": "Queue", + "formPreset": "Preset", + "gratitude": "Gratitude", + "gratitudeText": "I sincerely thank you for your invaluable\n\r and timely assistance:", + "help": "Help", + "helpFFplay": "FFplay Player Keys", + "helpFFplayActivateFrameStepMode": "Activate frame-by-frame mode.", + "helpFFplayCycleVideoFiltersOrShowModes": "A cycle of video filters or display modes.", + "helpFFplayDecreaseVolume": "Decrease the volume.", + "helpFFplayDescription": "Description", + "helpFFplayDoubleClickLeftMouseButton": "double click\nleft mouse button", + "helpFFplayIncreaseVolume": "Increase the volume.", + "helpFFplayKeyDown": "down", + "helpFFplayKeyHoldS": "hold S", + "helpFFplayKeyLeft": "left", + "helpFFplayKeyRight": "right", + "helpFFplayKeySpace": "SPACE", + "helpFFplayKeyUp": "up", + "helpFFplayKeys": "Keys", + "helpFFplayPause": "Pause or continue playing.", + "helpFFplayQuit": "Close the player.", + "helpFFplaySeekBForward10Minutes": "Fast forward 10 minutes.", + "helpFFplaySeekBForward1Minute": "Fast forward 1 minute.", + "helpFFplaySeekBackward10Minutes": "Rewind 10 minutes.", + "helpFFplaySeekBackward10Seconds": "Rewind 10 seconds.", + "helpFFplaySeekBackward1Minute": "Rewind 1 minute.", + "helpFFplaySeekForward10Seconds": "Fast forward 10 seconds.", + "helpFFplayToggleFullScreen": "Switch to full screen or exit full screen.", + "helpFFplayToggleMute": "Mute or unmute.", + "inProgressQueue": "In Progress", + "languageSelectionFormHead": "Switch language", + "languageSelectionHead": "Choose language", + "licenseLink": "License information", + "licenseLinkOther": "Licenses from other products used in the program", + "menuSettingsLanguage": "Language", + "menuSettingsTheme": "Theme", + "or": "or", + "parameterCheckbox": "Enable option", + "pathToFfmpeg": "Path to FFmpeg:", + "pathToFfplay": "Path to FFplay:", + "pathToFfprobe": "Path to FFprobe:", + "preset_fast": "fast (slower than \"faster\", but the file will weigh less)", + "preset_faster": "faster (slower than \"veryfast\", but the file will weigh less)", + "preset_medium": "medium (slower than \"fast\", but the file will weigh less)", + "preset_placebo": "placebo (not recommended)", + "preset_slow": "slow (slower than \"medium\", but the file will weigh less)", + "preset_slower": "slower (slower than \"slow\", but the file will weigh less)", + "preset_superfast": "superfast (slower than \"ultrafast\", but the file will weigh less)", + "preset_ultrafast": "ultrafast (fast, but the file will weigh a lot)", + "preset_veryfast": "veryfast (slower than \"superfast\", but the file will weigh less)", + "preset_veryslow": "veryslow (slower than \"slower\", but the file will weigh less)", + "programmLink": "Project website", + "programmVersion": "**Program version:** {{.Version}}", + "queue": "Queue", + "save": "Save", + "selectEncoder": "Encoder:", + "selectFFPathTitle": "Specify the path to FFmpeg and FFprobe", + "selectFormat": "File extension:", + "settings": "Settings", + "testFF": "Checking FFmpeg for serviceability...", + "themesNameDark": "Dark", + "themesNameDefault": "Default", + "themesNameLight": "Light", + "titleDownloadLink": "You can download it from here", + "total": "Total", + "unzipRun": "Unpacked...", + "waitingQueue": "Waiting" +} \ No newline at end of file diff --git a/internal/resources/translations/app.kk.json b/internal/resources/translations/app.kk.json new file mode 100644 index 0000000..6fb1b81 --- /dev/null +++ b/internal/resources/translations/app.kk.json @@ -0,0 +1,143 @@ +{ + "AlsoUsedProgram": "Бағдарлама сонымен қатар пайдаланады:", + "about": "Бағдарлама туралы", + "aboutText": "FFmpeg консоль утилитасы үшін қарапайым интерфейс. \nБірақ мен FFmpeg утилитасының авторы емеспін.", + "addedFilesTitle": "Қосылған файлдар", + "autoClearAfterAddingToQueue": "Кезекке қосқаннан кейін тазалаңыз", + "buttonDownloadFFmpeg": "FFmpeg автоматты түрде жүктеп алыңыз", + "buttonForSelectedDirTitle": "Қалтаға сақтаңыз:", + "cancel": "Болдырмау", + "changeFFPath": "FFmpeg, FFprobe және FFplay", + "changeLanguage": "Тілді өзгерту", + "checkboxOverwriteOutputFilesTitle": "Файлды қайта жазуға рұқсат беріңіз", + "choose": "таңдау", + "clearAll": "Тізімді өшіру", + "completedQueue": "Дайын", + "converterVideoFilesSubmitTitle": "Файлды түрлендіру", + "converterVideoFilesTitle": "Бейне, аудио және суретті түрлендіргіш", + "download": "Жүктеп алу", + "downloadFFmpegFromSite": "Сайттан жүктеледі:", + "downloadRun": "Жүктеп алынуда...", + "dragAndDropFiles": "файлдарды сүйреп апарыңыз", + "encoderGroupAudio": "Аудио", + "encoderGroupImage": "Суреттер", + "encoderGroupVideo": "Бейне", + "encoder_apng": "APNG image", + "encoder_bmp": "BMP image", + "encoder_flv": "FLV", + "encoder_gif": "GIF image", + "encoder_h264_nvenc": "NVIDIA қолдауымен H.264", + "encoder_libmp3lame": "libmp3lame MP3 (MPEG audio layer 3)", + "encoder_libshine": "libshine MP3 (MPEG audio layer 3)", + "encoder_libtwolame": "libtwolame MP2 (MPEG audio layer 2)", + "encoder_libvpx": "libvpx VP8 (codec vp8)", + "encoder_libvpx-vp9": "libvpx VP9 (codec vp9)", + "encoder_libwebp": "libwebp WebP image", + "encoder_libwebp_anim": "libwebp_anim WebP image", + "encoder_libx264": "H.264 libx264", + "encoder_libx265": "H.265 libx265", + "encoder_libxvid": "libxvidcore MPEG-4 part 2", + "encoder_mjpeg": "MJPEG (Motion JPEG)", + "encoder_mp2": "MP2 (MPEG audio layer 2)", + "encoder_mp2fixed": "MP2 fixed point (MPEG audio layer 2)", + "encoder_mpeg1video": "MPEG-1", + "encoder_mpeg2video": "MPEG-2", + "encoder_mpeg4": "MPEG-4 part 2", + "encoder_msmpeg4": "MPEG-4 part 2 Microsoft variant version 3", + "encoder_msmpeg4v2": "MPEG-4 part 2 Microsoft variant version 2", + "encoder_msvideo1": "Microsoft Video-1", + "encoder_png": "PNG image", + "encoder_qtrle": "QuickTime Animation (RLE) video", + "encoder_sgi": "SGI image", + "encoder_tiff": "TIFF image", + "encoder_wmav1": "Windows Media Audio 1", + "encoder_wmav2": "Windows Media Audio 2", + "encoder_wmv1": "Windows Media Video 7", + "encoder_wmv2": "Windows Media Video 8", + "encoder_xbm": "XBM (X BitMap) image", + "error": "Қате орын алды!", + "errorConverter": "Бейнені түрлендіру мүмкін болмады", + "errorDragAndDropFile": "Барлық файлдар қосылмаған", + "errorFFmpeg": "бұл FFmpeg емес", + "errorFFmpegVersion": "FFmpeg нұсқасын анықтау мүмкін болмады", + "errorFFplay": "бұл FFplay емес", + "errorFFplayVersion": "FFplay нұсқасын анықтау мүмкін болмады", + "errorFFprobe": "бұл FFprobe емес", + "errorFFprobeVersion": "FFprobe нұсқасын анықтау мүмкін болмады", + "errorNoFilesAddedForConversion": "Түрлендіруге арналған файлдар жоқ", + "errorQueue": "Қате", + "errorSelectedEncoder": "Түрлендіргіш таңдалмаған", + "errorSelectedFolderSave": "Сақтау қалтасы таңдалмаған!", + "errorSelectedFormat": "Файл кеңейтімі таңдалмаған", + "exit": "Шығу", + "ffmpegLGPL": "Бұл бағдарламалық құрал **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)** астында **FFmpeg** жобасының кітапханаларын пайдаланады.", + "ffmpegTrademark": "FFmpeg — **[FFmpeg](https://ffmpeg.org/about.html)** жобасын жасаушы **[Fabrice Bellard](http://bellard.org/)** сауда белгісі.", + "fileForConversionTitle": "Файл:", + "fileQueueTitle": "Кезек", + "formPreset": "Алдын ала орнатылған", + "gratitude": "Алғыс", + "gratitudeText": "Сізге баға жетпес және уақтылы көмектескеніңіз\n\r үшін шын жүректен алғыс айтамын:", + "help": "Анықтама", + "helpFFplay": "FFplay ойнатқышының пернелері", + "helpFFplayActivateFrameStepMode": "Уақыт аралығын іске қосыңыз.", + "helpFFplayCycleVideoFiltersOrShowModes": "Бейне сүзгілерінің немесе дисплей режимдерінің циклі.", + "helpFFplayDecreaseVolume": "Дыбыс деңгейін төмендетіңіз.", + "helpFFplayDescription": "Сипаттама", + "helpFFplayDoubleClickLeftMouseButton": "тінтуірдің сол жақ\nбатырмасын екі рет басу", + "helpFFplayIncreaseVolume": "Дыбыс деңгейін арттыру.", + "helpFFplayKeyDown": "төмен", + "helpFFplayKeyHoldS": "ұстау S", + "helpFFplayKeyLeft": "сол", + "helpFFplayKeyRight": "құқық", + "helpFFplayKeySpace": "SPACE (пробел)", + "helpFFplayKeyUp": "жоғары", + "helpFFplayKeys": "Кілттер", + "helpFFplayPause": "Кідіртіңіз немесе жоғалтуды жалғастырыңыз.", + "helpFFplayQuit": "Ойнатқышты жабыңыз.", + "helpFFplaySeekBForward10Minutes": "10 минутқа алға айналдырыңыз.", + "helpFFplaySeekBForward1Minute": "1 минутқа алға айналдырыңыз.", + "helpFFplaySeekBackward10Minutes": "10 минутқа артқа айналдырыңыз.", + "helpFFplaySeekBackward10Seconds": "10 секундқа артқа айналдырыңыз.", + "helpFFplaySeekBackward1Minute": "1 минутқа артқа айналдырыңыз.", + "helpFFplaySeekForward10Seconds": "10 секунд алға айналдырыңыз.", + "helpFFplayToggleFullScreen": "Толық экранға ауысу немесе толық экраннан шығу.", + "helpFFplayToggleMute": "Дыбысты өшіріңіз немесе дыбысты қосыңыз.", + "inProgressQueue": "Орындалуда", + "languageSelectionFormHead": "Тілді ауыстыру", + "languageSelectionHead": "Тілді таңдаңыз", + "licenseLink": "Лицензия туралы ақпарат", + "licenseLinkOther": "Бағдарламада пайдаланылатын басқа өнімдердің лицензиялары", + "menuSettingsLanguage": "Тіл", + "menuSettingsTheme": "Тақырып", + "or": "немесе", + "parameterCheckbox": "Опцияны қосу", + "pathToFfmpeg": "FFmpeg жол:", + "pathToFfplay": "FFplay жол:", + "pathToFfprobe": "FFprobe жол:", + "preset_fast": "fast («faster» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)", + "preset_faster": "faster («veryfast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)", + "preset_medium": "medium («fast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)", + "preset_placebo": "placebo (ұсынылмайды)", + "preset_slow": "slow («medium» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)", + "preset_slower": "slower («slow» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)", + "preset_superfast": "superfast («ultrafast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)", + "preset_ultrafast": "ultrafast (жылдам, бірақ файлдың салмағы көп болады)", + "preset_veryfast": "veryfast («superfast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)", + "preset_veryslow": "veryslow («slower» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)", + "programmLink": "Жобаның веб-сайты", + "programmVersion": "**Бағдарлама нұсқасы:** {{.Version}}", + "queue": "Кезек", + "save": "Сақтау", + "selectEncoder": "Кодировщик:", + "selectFFPathTitle": "FFmpeg және FFprobe жолын көрсетіңіз", + "selectFormat": "Файл кеңейтімі:", + "settings": "Параметрлер", + "testFF": "FFmpeg функционалдығы тексерілуде...", + "themesNameDark": "Қараңғы тақырып", + "themesNameDefault": "Әдепкі бойынша", + "themesNameLight": "Жеңіл тақырып", + "titleDownloadLink": "Сіз оны осы жерден жүктей аласыз", + "total": "Барлығы", + "unzipRun": "Орамнан шығарылуда...", + "waitingQueue": "Күту" +} \ No newline at end of file diff --git a/internal/resources/translations/app.ru.json b/internal/resources/translations/app.ru.json new file mode 100644 index 0000000..20a5da8 --- /dev/null +++ b/internal/resources/translations/app.ru.json @@ -0,0 +1,143 @@ +{ + "AlsoUsedProgram": "Также в программе используется:", + "about": "О программе", + "aboutText": "Простенький интерфейс для консольной утилиты FFmpeg. \nНо я не являюсь автором самой утилиты FFmpeg.", + "addedFilesTitle": "Добавленные файлы", + "autoClearAfterAddingToQueue": "Очищать после добавления в очередь", + "buttonDownloadFFmpeg": "Скачать автоматически FFmpeg", + "buttonForSelectedDirTitle": "Сохранить в папку:", + "cancel": "Отмена", + "changeFFPath": "FFmpeg, FFprobe и FFplay", + "changeLanguage": "Поменять язык", + "checkboxOverwriteOutputFilesTitle": "Разрешить перезаписать файл", + "choose": "выбрать", + "clearAll": "Очистить список", + "completedQueue": "Готово", + "converterVideoFilesSubmitTitle": "Конвертировать", + "converterVideoFilesTitle": "Конвертер видео, аудио и картинок", + "download": "Скачать", + "downloadFFmpegFromSite": "Будет скачано с сайта:", + "downloadRun": "Скачивается...", + "dragAndDropFiles": "перетащить файлы", + "encoderGroupAudio": "Аудио", + "encoderGroupImage": "Картинки", + "encoderGroupVideo": "Видео", + "encoder_apng": "APNG image", + "encoder_bmp": "BMP image", + "encoder_flv": "FLV", + "encoder_gif": "GIF image", + "encoder_h264_nvenc": "H.264 с поддержкой NVIDIA", + "encoder_libmp3lame": "libmp3lame MP3 (MPEG audio layer 3)", + "encoder_libshine": "libshine MP3 (MPEG audio layer 3)", + "encoder_libtwolame": "libtwolame MP2 (MPEG audio layer 2)", + "encoder_libvpx": "libvpx VP8 (codec vp8)", + "encoder_libvpx-vp9": "libvpx VP9 (codec vp9)", + "encoder_libwebp": "libwebp WebP image", + "encoder_libwebp_anim": "libwebp_anim WebP image", + "encoder_libx264": "H.264 libx264", + "encoder_libx265": "H.265 libx265", + "encoder_libxvid": "libxvidcore MPEG-4 part 2", + "encoder_mjpeg": "MJPEG (Motion JPEG)", + "encoder_mp2": "MP2 (MPEG audio layer 2)", + "encoder_mp2fixed": "MP2 fixed point (MPEG audio layer 2)", + "encoder_mpeg1video": "MPEG-1", + "encoder_mpeg2video": "MPEG-2", + "encoder_mpeg4": "MPEG-4 part 2", + "encoder_msmpeg4": "MPEG-4 part 2 Microsoft variant version 3", + "encoder_msmpeg4v2": "MPEG-4 part 2 Microsoft variant version 2", + "encoder_msvideo1": "Microsoft Video-1", + "encoder_png": "PNG image", + "encoder_qtrle": "QuickTime Animation (RLE) video", + "encoder_sgi": "SGI image", + "encoder_tiff": "TIFF image", + "encoder_wmav1": "Windows Media Audio 1", + "encoder_wmav2": "Windows Media Audio 2", + "encoder_wmv1": "Windows Media Video 7", + "encoder_wmv2": "Windows Media Video 8", + "encoder_xbm": "XBM (X BitMap) image", + "error": "Произошла ошибка!", + "errorConverter": "не смогли отконвертировать видео", + "errorDragAndDropFile": "Не все файлы добавились", + "errorFFmpeg": "это не FFmpeg", + "errorFFmpegVersion": "Не смогли определить версию FFmpeg", + "errorFFplay": "это не FFplay", + "errorFFplayVersion": "Не смогли определить версию FFplay", + "errorFFprobe": "это не FFprobe", + "errorFFprobeVersion": "Не смогли определить версию FFprobe", + "errorNoFilesAddedForConversion": "Нет файлов для конвертации", + "errorQueue": "Ошибка", + "errorSelectedEncoder": "Конвертер не выбран", + "errorSelectedFolderSave": "Папка для сохранения не выбрана!", + "errorSelectedFormat": "Расширение файла не выбрана", + "exit": "Выход", + "ffmpegLGPL": "Это программное обеспечение использует библиотеки из проекта **FFmpeg** под **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**.", + "ffmpegTrademark": "**FFmpeg** — торговая марка **[Fabrice Bellard](http://bellard.org/)** , создателя проекта **[FFmpeg](https://ffmpeg.org/about.html)**.", + "fileForConversionTitle": "Файл:", + "fileQueueTitle": "Очередь", + "formPreset": "Предустановка", + "gratitude": "Благодарность", + "gratitudeText": "Я искренне благодарю вас за неоценимую\n\rи своевременную помощь:", + "help": "Справка", + "helpFFplay": "Клавиши проигрывателя FFplay", + "helpFFplayActivateFrameStepMode": "Активировать покадровый режим.", + "helpFFplayCycleVideoFiltersOrShowModes": "Цикл видеофильтров или режимов показа.", + "helpFFplayDecreaseVolume": "Уменьшить громкость.", + "helpFFplayDescription": "Описание", + "helpFFplayDoubleClickLeftMouseButton": "двойной щелчок\nлевой кнопкой мыши", + "helpFFplayIncreaseVolume": "Увеличить громкость.", + "helpFFplayKeyDown": "вниз", + "helpFFplayKeyHoldS": "держать S", + "helpFFplayKeyLeft": "лево", + "helpFFplayKeyRight": "право", + "helpFFplayKeySpace": "SPACE (пробел)", + "helpFFplayKeyUp": "вверх", + "helpFFplayKeys": "Клавиши", + "helpFFplayPause": "Поставить на паузу или продолжить проигрывать.", + "helpFFplayQuit": "Закрыть проигрыватель.", + "helpFFplaySeekBForward10Minutes": "Перемотать вперёд на 10 минут.", + "helpFFplaySeekBForward1Minute": "Перемотать вперёд на 1 минуту.", + "helpFFplaySeekBackward10Minutes": "Перемотать назад на 10 минут.", + "helpFFplaySeekBackward10Seconds": "Перемотать назад на 10 секунд.", + "helpFFplaySeekBackward1Minute": "Перемотать назад на 1 минуту.", + "helpFFplaySeekForward10Seconds": "Перемотать вперёд на 10 секунд.", + "helpFFplayToggleFullScreen": "Переключиться на полный экран или выйти с полного экрана.", + "helpFFplayToggleMute": "Отключить звук или включить звук.", + "inProgressQueue": "Выполняется", + "languageSelectionFormHead": "Переключить язык", + "languageSelectionHead": "Выберите язык", + "licenseLink": "Сведения о лицензии", + "licenseLinkOther": "Лицензии от других продуктов, которые используются в программе", + "menuSettingsLanguage": "Язык", + "menuSettingsTheme": "Тема", + "or": "или", + "parameterCheckbox": "Включить параметр", + "pathToFfmpeg": "Путь к FFmpeg:", + "pathToFfplay": "Путь к FFplay:", + "pathToFfprobe": "Путь к FFprobe:", + "preset_fast": "fast (медленней чем faster, но будет файл и меньше весить)", + "preset_faster": "faster (медленней чем veryfast, но будет файл и меньше весить)", + "preset_medium": "medium (медленней чем fast, но будет файл и меньше весить)", + "preset_placebo": "placebo (не рекомендуется)", + "preset_slow": "slow (медленней чем medium, но будет файл и меньше весить)", + "preset_slower": "slower (медленней чем slow, но будет файл и меньше весить)", + "preset_superfast": "superfast (медленней чем ultrafast, но будет файл и меньше весить)", + "preset_ultrafast": "ultrafast (быстро, но файл будет много весить)", + "preset_veryfast": "veryfast (медленней чем superfast, но будет файл и меньше весить)", + "preset_veryslow": "veryslow (медленней чем slower, но будет файл и меньше весить)", + "programmLink": "Сайт проекта", + "programmVersion": "**Версия программы:** {{.Version}}", + "queue": "Очередь", + "save": "Сохранить", + "selectEncoder": "Кодировщик:", + "selectFFPathTitle": "Укажите путь к FFmpeg и к FFprobe", + "selectFormat": "Расширение файла:", + "settings": "Настройки", + "testFF": "Проверка FFmpeg на работоспособность...", + "themesNameDark": "Тёмная", + "themesNameDefault": "По умолчанию", + "themesNameLight": "Светлая", + "titleDownloadLink": "Скачать можно от сюда", + "total": "Всего", + "unzipRun": "Распаковывается...", + "waitingQueue": "В очереди" +} \ No newline at end of file diff --git a/internal/resources/translations/base.en.json b/internal/resources/translations/base.en.json new file mode 100644 index 0000000..3f5dd3d --- /dev/null +++ b/internal/resources/translations/base.en.json @@ -0,0 +1,45 @@ +{ + "Advanced": "Advanced", + "Cancel": "Cancel", + "Confirm": "Confirm", + "Copy": "Copy", + "Create Folder": "Create Folder", + "Cut": "Cut", + "Enter filename": "Enter filename", + "Error": "Error", + "Favourites": "Favourites", + "File": "File", + "Folder": "Folder", + "New Folder": "New Folder", + "No": "No", + "OK": "OK", + "Open": "Open", + "Paste": "Paste", + "Quit": "Quit", + "Redo": "Redo", + "Save": "Save", + "Select all": "Select all", + "Show Hidden Files": "Show Hidden Files", + "Undo": "Undo", + "Yes": "Yes", + "file.name": { + "other": "Name" + }, + "file.parent": { + "other": "Parent" + }, + "friday": "Friday", + "friday.short": "Fri", + "monday": "Monday", + "monday.short": "Mon", + "saturday": "Saturday", + "saturday.short": "Sat", + "sunday": "Sunday", + "sunday.short": "Sun", + "thursday": "Thursday", + "thursday.short": "Thu", + "tuesday": "Tuesday", + "tuesday.short": "Tue", + "wednesday": "Wednesday", + "wednesday.short": "Wed" +} \ No newline at end of file diff --git a/internal/resources/translations/base.kk.json b/internal/resources/translations/base.kk.json new file mode 100644 index 0000000..469566b --- /dev/null +++ b/internal/resources/translations/base.kk.json @@ -0,0 +1,45 @@ +{ + "Advanced": "Кеңейтілген", + "Cancel": "Бас тарту", + "Confirm": "Растау", + "Copy": "Көшіру", + "Create Folder": "Қалта жасау", + "Cut": "Кесу", + "Enter filename": "Файл атауын енгізіңіз", + "Error": "Қате", + "Favourites": "Таңдаулылар", + "File": "Файл", + "Folder": "Қалта", + "New Folder": "Жаңа қалта", + "No": "Жоқ", + "OK": "ОК", + "Open": "Ашу", + "Paste": "Кірістіру", + "Quit": "Шығу", + "Redo": "Қайталау", + "Save": "Сақтау", + "Select all": "Барлығын таңдаңыз", + "Show Hidden Files": "Жасырын файлдарды көрсету", + "Undo": "Бас тарту", + "Yes": "Иә", + "file.name": { + "other": "Аты" + }, + "file.parent": { + "other": "Жоғары" + }, + "friday": "Жұма", + "friday.short": "Жұ", + "monday": "Дүйсенбі", + "monday.short": "Дү", + "saturday": "Сенбі", + "saturday.short": "Сен", + "sunday": "Жексенбі", + "sunday.short": "Же", + "thursday": "Сейсенбі", + "thursday.short": "Се", + "tuesday": "Бейсенбі", + "tuesday.short": "Бе", + "wednesday": "Сәрсенбі", + "wednesday.short": "Сә" +} \ No newline at end of file diff --git a/internal/resources/translations/base.ru.json b/internal/resources/translations/base.ru.json new file mode 100644 index 0000000..ac22058 --- /dev/null +++ b/internal/resources/translations/base.ru.json @@ -0,0 +1,45 @@ +{ + "Advanced": "Расширенные", + "Cancel": "Отмена", + "Confirm": "Подтвердить", + "Copy": "Копировать", + "Create Folder": "Создать папку", + "Cut": "Вырезать", + "Enter filename": "Введите имя файла", + "Error": "Ошибка", + "Favourites": "Избранное", + "File": "Файл", + "Folder": "Папка", + "New Folder": "Новая папка", + "No": "Нет", + "OK": "ОК", + "Open": "Открыть", + "Paste": "Вставить", + "Quit": "Выйти", + "Redo": "Повторить", + "Save": "Сохранить", + "Select all": "Выбрать всё", + "Show Hidden Files": "Показать скрытые файлы", + "Undo": "Отменить", + "Yes": "Да", + "file.name": { + "other": "Имя" + }, + "file.parent": { + "other": "Вверх" + }, + "friday": "Пятница", + "friday.short": "Пт", + "monday": "Понедельник", + "monday.short": "Пн", + "saturday": "Суббота", + "saturday.short": "Сб", + "sunday": "Воскресенье", + "sunday.short": "Вс", + "thursday": "Вторник", + "thursday.short": "Вт", + "tuesday": "Четверг", + "tuesday.short": "Чт", + "wednesday": "Среда", + "wednesday.short": "Ср" +} \ No newline at end of file diff --git a/main.go b/main.go index e299536..30a9ae7 100644 --- a/main.go +++ b/main.go @@ -1,76 +1,29 @@ package main import ( - _ "embed" "fyne.io/fyne/v2" - "git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor" - error2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/error" - "git.kor-elf.net/kor-elf/gui-for-ffmpeg/handler" + "fyne.io/fyne/v2/app" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/setting" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/controller" + "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/resources" - "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel" - "git.kor-elf.net/kor-elf/gui-for-ffmpeg/localizer" - "git.kor-elf.net/kor-elf/gui-for-ffmpeg/menu" - "git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting" - "git.kor-elf.net/kor-elf/gui-for-ffmpeg/theme" ) -var application kernel.AppContract -var ffPathUtilities *kernel.FFPathUtilities - -func init() { - appMetadata := &fyne.AppMetadata{ +func main() { + appMetadata := fyne.AppMetadata{ ID: "net.kor-elf.projects.gui-for-ffmpeg", Name: "GUI for FFmpeg", Version: "0.9.0", Icon: resources.IconAppLogoResource(), } - - ffPathUtilities = &kernel.FFPathUtilities{FFmpeg: "", FFprobe: "", FFplay: ""} - convertorService := kernel.NewService(ffPathUtilities) - ffplayService := kernel.NewFFplay(ffPathUtilities) - - queue := kernel.NewQueueList() - application = kernel.NewApp( - appMetadata, - queue, - ffplayService, - convertorService, - ) -} - -func main() { - errorView := error2.NewView(application) - - settingRepository := setting.NewRepository(application.GetAppFyne()) - settingDirectoryForSaving := setting.NewSettingDirectoryForSaving(settingRepository) - - convertorRepository := convertor.NewRepository(settingRepository) - ffPathUtilities.FFmpeg = convertorRepository.GetPathFfmpeg() - ffPathUtilities.FFprobe = convertorRepository.GetPathFfprobe() - ffPathUtilities.FFplay = convertorRepository.GetPathFfplay() - - application.RunConvertor() - defer application.AfterClosing() - - localizerView := localizer.NewView(application) - convertorView := convertor.NewView(application) - itemsToConvertService := kernel.NewItemsToConvert( - application.GetWindow().GetLayout().GetRightTabs().GetAddedFilesContainer(), - application.GetFFplayService(), - application.GetLocalizerService(), - ) - convertorHandler := handler.NewConvertorHandler(application, convertorView, errorView, convertorRepository, settingDirectoryForSaving, itemsToConvertService) - - themeRepository := theme.NewRepository(settingRepository) - themeService := theme.NewTheme(application, themeRepository) - - menuView := menu.NewView(application) - menuSettingView := menu.NewViewSetting(application, themeService) - mainMenu := handler.NewMenuHandler(application, convertorHandler, menuView, menuSettingView, localizerView, themeService) - - mainHandler := handler.NewMainHandler(application, convertorHandler, mainMenu) - mainHandler.Start() - - application.GetWindow().SetMainMenu(mainMenu.GetMainMenu()) - application.GetWindow().ShowAndRun() + app.SetMetadata(appMetadata) + fyneApp := app.New() + progressBarService := application.NewProgressBar() + appSetting := setting.NewSetting(fyneApp) + ffmpegService := ffmpeg.NewUtilities(appSetting) + myApp := application.NewApp(fyneApp, appSetting, progressBarService, ffmpegService) + mainController := controller.NewController(myApp) + mainController.Start() + myApp.Run() }