.
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..564205c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,88 @@
+VERSION ?= $(shell grep '^ *Version *= *' FyneApp.toml | sed -E "s/.*=[[:space:]]*\"([0-9\.]+)\".*/\1/")
+
+BUILD_TMP := fyne-cross/tmp
+
+WINDOWS_AMD64 := gui-for-ffmpeg-$(VERSION)-windows-amd64
+BUILD_TMP_WINDOWS_AMD64 := $(BUILD_TMP)/$(WINDOWS_AMD64)
+
+LINUX_AMD64 := gui-for-ffmpeg-$(VERSION)-linux-amd64
+BUILD_TMP_LINUX_AMD64 := $(BUILD_TMP)/$(LINUX_AMD64)
+
+RELEASES := fyne-cross/releases/$(VERSION)
+
+default:
+ # Run "make build-for-linux_amd64"
+ # Run "make build-for-windows_amd64"
+ # Build for all
+ # Run "make build"
+
+build:
+ make build-for-linux_amd64
+ make build-for-windows_amd64
+ # $(RELEASES)/$(LINUX_AMD64).tar.gz
+ # $(RELEASES)/$(LINUX_AMD64).tar.gz.sha256
+ # $(RELEASES)/$(WINDOWS_AMD64).zip
+ # $(RELEASES)/$(WINDOWS_AMD64).zip.sha256
+
+build-for-windows_amd64:
+ fyne-cross windows
+
+ @if [ -d $(BUILD_TMP_WINDOWS_AMD64) ]; then \
+ rm -rf $(BUILD_TMP_WINDOWS_AMD64)/*; \
+ else \
+ mkdir -p $(BUILD_TMP_WINDOWS_AMD64); \
+ fi
+ cp LICENSE $(BUILD_TMP_WINDOWS_AMD64)/LICENSE
+ cp LICENSE-3RD-PARTY.txt $(BUILD_TMP_WINDOWS_AMD64)/LICENSE-3RD-PARTY.txt
+ cp "fyne-cross/bin/windows-amd64/GUI for FFmpeg.exe" $(BUILD_TMP_WINDOWS_AMD64)/gui-for-ffmpeg.exe
+ cd $(BUILD_TMP) && 7z a -tzip $(WINDOWS_AMD64).zip $(WINDOWS_AMD64)
+
+ @if [ ! -d $(RELEASES) ]; then \
+ mkdir -p $(RELEASES); \
+ fi
+
+ @if [ -f $(RELEASES)/$(WINDOWS_AMD64).zip ]; then \
+ rm $(RELEASES)/$(WINDOWS_AMD64).zip; \
+ fi
+
+ @if [ -f $(RELEASES)/$(WINDOWS_AMD64).zip.sha256 ]; then \
+ rm $(RELEASES)/$(WINDOWS_AMD64).zip.sha256; \
+ fi
+
+ mv $(BUILD_TMP)/$(WINDOWS_AMD64).zip $(RELEASES)/$(WINDOWS_AMD64).zip
+ cd $(RELEASES) && sha256sum $(WINDOWS_AMD64).zip > $(WINDOWS_AMD64).zip.sha256
+ # $(RELEASES)/$(WINDOWS_AMD64).zip
+ # $(RELEASES)/$(WINDOWS_AMD64).zip.sha256
+
+build-for-linux_amd64:
+ fyne-cross linux
+
+ @if [ -d $(BUILD_TMP_LINUX_AMD64) ]; then \
+ rm -rf $(BUILD_TMP_LINUX_AMD64)/*; \
+ else \
+ mkdir -p $(BUILD_TMP_LINUX_AMD64); \
+ fi
+ cp -r dist/linux/* $(BUILD_TMP_LINUX_AMD64)/
+ cp LICENSE $(BUILD_TMP_LINUX_AMD64)/LICENSE
+ cp LICENSE-3RD-PARTY.txt $(BUILD_TMP_LINUX_AMD64)/LICENSE-3RD-PARTY.txt
+ cp fyne-cross/bin/linux-amd64/gui-for-ffmpeg $(BUILD_TMP_LINUX_AMD64)/usr/local/bin/gui-for-ffmpeg
+ cp assets/icon.png $(BUILD_TMP_LINUX_AMD64)/usr/local/share/pixmaps/gui-for-ffmpeg.png
+
+ cd $(BUILD_TMP) && tar -czvf $(LINUX_AMD64).tar.gz $(LINUX_AMD64)
+
+ @if [ ! -d $(RELEASES) ]; then \
+ mkdir -p $(RELEASES); \
+ fi
+
+ @if [ -f $(RELEASES)/$(LINUX_AMD64).tar.gz ]; then \
+ rm $(RELEASES)/$(LINUX_AMD64).tar.gz; \
+ fi
+
+ @if [ -f $(RELEASES)/$(LINUX_AMD64).tar.gz.sha256 ]; then \
+ rm $(RELEASES)/$(LINUX_AMD64).tar.gz.sha256; \
+ fi
+
+ mv $(BUILD_TMP)/$(LINUX_AMD64).tar.gz $(RELEASES)/$(LINUX_AMD64).tar.gz
+ cd $(RELEASES) && sha256sum $(LINUX_AMD64).tar.gz > $(LINUX_AMD64).tar.gz.sha256
+ # $(RELEASES)/$(LINUX_AMD64).tar.gz
+ # $(RELEASES)/$(LINUX_AMD64).tar.gz.sha256
diff --git a/README.md b/README.md
index 8f59d1f..cd7e398 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@
# GUI for FFmpeg
Простенький интерфейс для консольной утилиты FFmpeg. Но я не являюсь автором самой утилиты FFmpeg.
-FFmpeg — торговая марка Fabrice Bellard, создателя проекта FFmpeg.
+FFmpeg — торговая марка Fabrice Bellard, создателя проекта FFmpeg.
Программное обеспечение является MIT (см. LICENSE) и использует сторонние библиотеки, которые распространяются на их собственных условиях (см. LICENSE-3RD-PARTY.txt).
-
+
Скачать скомпилированные готовые версии можно тут: https://git.kor-elf.net/kor-elf/gui-for-ffmpeg/releases.
@@ -13,6 +13,18 @@
1. go install fyne.io/fyne/v2/cmd/fyne@latest
2. fyne get git.kor-elf.net/kor-elf/gui-for-ffmpeg
+## Скомпилировать через Makefile:
+1. git clone https://git.kor-elf.net/kor-elf/gui-for-ffmpeg.git
+2. Переходим в папку проекта и там переходим в папку src: **cd gui-for-ffmpeg**
+3. Ознакамливаемся, что нужно ещё установить для Вашей ОС для простого запуска (через go run) тут: https://docs.fyne.io/started/
+4. go install github.com/fyne-io/fyne-cross@latest
+ * У Вас так же должен быть установлен docker
+ * О fyne-cross можно по подробней почитать тут: https://github.com/fyne-io/fyne-cross
+5. * make build-for-linux_amd64
+ * make build-for-windows_amd64
+ * Или просто **make build**
+6. Создаться папка с архивом в **fyne-cross/releases**
+
## Скомпилировать через исходники:
1. git clone https://git.kor-elf.net/kor-elf/gui-for-ffmpeg.git
2. Переходим в папку проекта и там переходим в папку src: **cd gui-for-ffmpeg**
@@ -21,25 +33,7 @@
5. go install github.com/fyne-io/fyne-cross@latest
* У Вас так же должен быть установлен docker
* О fyne-cross можно по подробней почитать тут: https://github.com/fyne-io/fyne-cross
-6. * fyne-cross windows --icon icon.png --app-id "." -name "gui-for-ffmpeg"
- * fyne-cross linux --icon icon.png --app-id "." -name "gui-for-ffmpeg"
-7. Создаться папка **fyne-cross/bin** и там будет созданна папка с тем названием под которую Вы компилировали приложения (linux-amd64 или windows-amd64).
-8. В папку **fyne-cross/bin/linux-amd64** или **fyne-cross/bin/windows-amd64** копируете:
- * icon.png
- * data
- * languages
- * LICENSE
- * LICENSE-3RD-PARTY.txt
-Структура должна получиться такая:
-
-
-## Работа с переводами:
-1. go install -v github.com/nicksnyder/go-i18n/v2/goi18n@latest
-3. Создаём файл languages/translate.\*.toml
-4. goi18n merge -sourceLanguage ru -outdir languages languages/active.\*.toml languages/translate.\*.toml
-5. В файлах **languages/translate.\*.toml** переводим текст на нужный язык
-6. goi18n merge -sourceLanguage ru -outdir languages languages/active.\*.toml languages/translate.\*.toml
-
-___где * подставляем нужный язык___
-
-Более подробно можно почитать тут: https://github.com/nicksnyder/go-i18n
\ No newline at end of file
+6. * fyne-cross windows
+ * fyne-cross linux
+7. Создаться папка **fyne-cross/dist** и там будет созданна папка с тем названием под которую Вы компилировали приложения (linux-amd64 или windows-amd64).
+8. В папке **fyne-cross/bin/linux-amd64** или **fyne-cross/bin/windows-amd64** будут архивы, которые надо распаковать и пользоваться программой.
diff --git a/assets/icon.png b/assets/icon.png
new file mode 100644
index 0000000..6eaf8f6
Binary files /dev/null and b/assets/icon.png differ
diff --git a/assets/screenshot-gui-for-ffmpeg.png b/assets/screenshot-gui-for-ffmpeg.png
new file mode 100644
index 0000000..0fc23fd
Binary files /dev/null and b/assets/screenshot-gui-for-ffmpeg.png differ
diff --git a/convertor/repository.go b/convertor/repository.go
deleted file mode 100644
index f751607..0000000
--- a/convertor/repository.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package convertor
-
-import (
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting"
-)
-
-type RepositoryContract interface {
- GetPathFfmpeg() (string, error)
- SavePathFfmpeg(code string) (setting.Setting, error)
- GetPathFfprobe() (string, error)
- SavePathFfprobe(code string) (setting.Setting, error)
- GetPathFfplay() (string, error)
- SavePathFfplay(code string) (setting.Setting, error)
-}
-
-type Repository struct {
- settingRepository setting.RepositoryContract
-}
-
-func NewRepository(settingRepository setting.RepositoryContract) *Repository {
- return &Repository{settingRepository: settingRepository}
-}
-
-func (r Repository) GetPathFfmpeg() (string, error) {
- return r.settingRepository.GetValue("ffmpeg")
-}
-
-func (r Repository) SavePathFfmpeg(path string) (setting.Setting, error) {
- return r.settingRepository.CreateOrUpdate("ffmpeg", path)
-}
-
-func (r Repository) GetPathFfprobe() (string, error) {
- return r.settingRepository.GetValue("ffprobe")
-}
-
-func (r Repository) SavePathFfprobe(path string) (setting.Setting, error) {
- return r.settingRepository.CreateOrUpdate("ffprobe", path)
-}
-
-func (r Repository) GetPathFfplay() (string, error) {
- return r.settingRepository.GetValue("ffplay")
-}
-
-func (r Repository) SavePathFfplay(path string) (setting.Setting, error) {
- return r.settingRepository.CreateOrUpdate("ffplay", path)
-}
diff --git a/convertor/view.go b/convertor/view.go
deleted file mode 100644
index 58e6a3f..0000000
--- a/convertor/view.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package convertor
-
-import (
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/canvas"
- "fyne.io/fyne/v2/container"
- "fyne.io/fyne/v2/widget"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor/view"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "github.com/nicksnyder/go-i18n/v2/i18n"
- "image/color"
-)
-
-type ViewContract interface {
- Main(
- formConversion view.ConversionContract,
- )
- SelectFFPath(
- ffmpegPath string,
- ffprobePath string,
- ffplayPath string,
- save func(ffmpegPath string, ffprobePath string, ffplayPath string) error,
- cancel func(),
- donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error,
- )
-}
-
-type View struct {
- app kernel.AppContract
- downloadFFmpeg *downloadFFmpeg
-}
-
-type downloadFFmpeg struct {
- isDownloadFFmpeg bool
- blockDownloadFFmpegContainer *fyne.Container
-}
-
-func NewView(app kernel.AppContract) *View {
- return &View{
- app: app,
- downloadFFmpeg: &downloadFFmpeg{
- blockDownloadFFmpegContainer: nil,
- },
- }
-}
-
-func (v View) Main(formConversion view.ConversionContract) {
- converterVideoFilesTitle := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "converterVideoFilesTitle",
- })
- v.app.GetWindow().SetContent(widget.NewCard(converterVideoFilesTitle, "", container.NewVScroll(formConversion.GetContent())))
- formConversion.AfterViewContent()
-}
-
-func setStringErrorStyle(text *canvas.Text) {
- text.Color = color.RGBA{R: 255, G: 0, B: 0, A: 255}
- text.Refresh()
-}
-
-func setStringSuccessStyle(text *canvas.Text) {
- text.Color = color.RGBA{R: 49, G: 127, B: 114, A: 255}
- text.Refresh()
-}
diff --git a/convertor/view/conversion.go b/convertor/view/conversion.go
deleted file mode 100644
index 947a37c..0000000
--- a/convertor/view/conversion.go
+++ /dev/null
@@ -1,539 +0,0 @@
-package view
-
-import (
- "errors"
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/canvas"
- "fyne.io/fyne/v2/container"
- "fyne.io/fyne/v2/storage"
- "fyne.io/fyne/v2/widget"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor/view/form_items"
- encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel/encoder"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting"
- "github.com/nicksnyder/go-i18n/v2/i18n"
- "image/color"
- "os"
- "path/filepath"
-)
-
-type ConversionContract interface {
- GetContent() fyne.CanvasObject
- AfterViewContent()
-}
-
-type Conversion struct {
- app kernel.AppContract
- form *form
- conversionMessage *canvas.Text
- fileForConversion *fileForConversion
- directoryForSaving *directoryForSaving
- overwriteOutputFiles *overwriteOutputFiles
- selectEncoder *selectEncoder
- runConvert func(setting HandleConvertSetting)
- itemsToConvertService kernel.ItemsToConvertContract
-}
-
-type HandleConvertSetting struct {
- DirectoryForSave string
- OverwriteOutputFiles bool
- Format string
- Encoder encoder2.EncoderContract
-}
-
-func NewConversion(app kernel.AppContract, formats encoder.ConvertorFormatsContract, runConvert func(setting HandleConvertSetting), settingDirectoryForSaving setting.DirectoryForSavingContract, itemsToConvertService kernel.ItemsToConvertContract) *Conversion {
- conversionMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
- conversionMessage.TextSize = 16
- conversionMessage.TextStyle = fyne.TextStyle{Bold: true}
-
- fileForConversion := newFileForConversion(app, itemsToConvertService)
- directoryForSaving := newDirectoryForSaving(app, settingDirectoryForSaving)
- overwriteOutputFiles := newOverwriteOutputFiles(app)
- selectEncoder := newSelectEncoder(app, formats)
-
- items := []*widget.FormItem{
- {
- Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "fileForConversionTitle"}),
- Widget: fileForConversion.button,
- },
- {
- Widget: container.NewHScroll(fileForConversion.message),
- },
- {
- Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "buttonForSelectedDirTitle"}),
- Widget: directoryForSaving.button,
- },
- {
- Widget: container.NewHScroll(directoryForSaving.message),
- },
- {
- Widget: overwriteOutputFiles.checkbox,
- },
- {
- Widget: selectEncoder.SelectFileType,
- },
- {
- Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "selectFormat"}),
- Widget: selectEncoder.SelectFormat,
- },
- {
- Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "selectEncoder"}),
- Widget: selectEncoder.SelectEncoder,
- },
- }
- form := newForm(app, items)
-
- return &Conversion{
- app: app,
- form: form,
- conversionMessage: conversionMessage,
- fileForConversion: fileForConversion,
- directoryForSaving: directoryForSaving,
- overwriteOutputFiles: overwriteOutputFiles,
- selectEncoder: selectEncoder,
- runConvert: runConvert,
- itemsToConvertService: itemsToConvertService,
- }
-}
-
-func (c Conversion) GetContent() fyne.CanvasObject {
- c.form.form.OnSubmit = c.submit
- c.fileForConversion.AddChangeCallback(c.selectFileForConversion)
- c.selectEncoder.AddChangeCallback(c.changeEncoder)
- if c.selectEncoder.Encoder != nil {
- c.selectEncoder.SelectEncoder.SetSelectedIndex(c.selectEncoder.SelectEncoder.SelectedIndex())
- }
-
- return container.NewVBox(
- c.form.form,
- c.conversionMessage,
- )
-}
-
-func (c Conversion) changeEncoder(encoder encoder2.EncoderContract) {
- items := []*widget.FormItem{}
-
- if form_items.Views[encoder.GetName()] != nil {
- items = form_items.Views[encoder.GetName()](encoder, c.app)
- }
-
- c.form.ChangeItems(items)
-}
-
-func (c Conversion) AfterViewContent() {
- if len(c.itemsToConvertService.GetItems()) == 0 {
- c.form.form.Disable()
- }
-}
-
-func (c Conversion) selectFileForConversion(err error) {
- c.conversionMessage.Text = ""
- if len(c.itemsToConvertService.GetItems()) == 0 {
- if err != nil {
- c.form.form.Disable()
- return
- }
- }
-
- c.form.form.Enable()
-}
-
-func (c Conversion) submit() {
- if len(c.itemsToConvertService.GetItems()) == 0 {
- showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorNoFilesAddedForConversion",
- })))
- c.enableFormConversion()
- return
- }
-
- if len(c.directoryForSaving.path) == 0 {
- showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorSelectedFolderSave",
- })))
- c.enableFormConversion()
- return
- }
- if len(c.selectEncoder.SelectFormat.Selected) == 0 {
- showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorSelectedFormat",
- })))
- return
- }
- if c.selectEncoder.Encoder == nil {
- showConversionMessage(c.conversionMessage, errors.New(c.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorSelectedEncoder",
- })))
- return
- }
- c.conversionMessage.Text = ""
-
- c.fileForConversion.button.Disable()
- c.directoryForSaving.button.Disable()
- c.form.form.Disable()
-
- c.runConvert(HandleConvertSetting{
- DirectoryForSave: c.directoryForSaving.path,
- OverwriteOutputFiles: c.overwriteOutputFiles.IsChecked(),
- Format: c.selectEncoder.SelectFormat.Selected,
- Encoder: c.selectEncoder.Encoder,
- })
- c.enableFormConversion()
-
- if len(c.itemsToConvertService.GetItems()) == 0 {
- c.form.form.Disable()
- }
-}
-
-func (c Conversion) enableFormConversion() {
- c.fileForConversion.button.Enable()
- c.directoryForSaving.button.Enable()
- c.form.form.Enable()
-}
-
-type fileForConversion struct {
- button *widget.Button
- message *canvas.Text
- file *kernel.File
-
- changeCallbacks map[int]func(err error)
-}
-
-func newFileForConversion(app kernel.AppContract, itemsToConvertService kernel.ItemsToConvertContract) *fileForConversion {
- message := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
- fileForConversion := &fileForConversion{
- message: message,
-
- changeCallbacks: map[int]func(err error){},
- }
-
- buttonTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "choose",
- }) + "\n" + app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "or",
- }) + "\n" + app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "dragAndDropFiles",
- })
-
- var locationURI fyne.ListableURI
-
- fileForConversion.button = widget.NewButton(buttonTitle, func() {
- app.GetWindow().NewFileOpen(func(r fyne.URIReadCloser, err error) {
- fyne.Do(func() {
- fileForConversion.message.Text = ""
- fileForConversion.message.Refresh()
- })
-
- if err != nil {
- fyne.Do(func() {
- fileForConversion.message.Text = err.Error()
- fileForConversion.message.Refresh()
- })
- fileForConversion.eventSelectFile(err)
- return
- }
- if r == nil {
- return
- }
- app.GetWindow().GetLayout().GetRightTabs().SelectAddedFilesTab()
-
- itemsToConvertService.Add(&kernel.File{
- Path: r.URI().Path(),
- Name: r.URI().Name(),
- Ext: r.URI().Extension(),
- })
-
- fileForConversion.eventSelectFile(nil)
-
- listableURI := storage.NewFileURI(filepath.Dir(r.URI().Path()))
- locationURI, _ = storage.ListerForURI(listableURI)
- }, locationURI)
- })
-
- app.GetWindow().SetOnDropped(func(position fyne.Position, uris []fyne.URI) {
- if len(uris) == 0 {
- return
- }
-
- isError := false
- for _, uri := range uris {
- info, err := os.Stat(uri.Path())
- if err != nil {
- isError = true
- continue
- }
- if info.IsDir() {
- isError = true
- continue
- }
-
- itemsToConvertService.Add(&kernel.File{
- Path: uri.Path(),
- Name: uri.Name(),
- Ext: uri.Extension(),
- })
-
- fileForConversion.eventSelectFile(nil)
-
- listableURI := storage.NewFileURI(filepath.Dir(uri.Path()))
- locationURI, _ = storage.ListerForURI(listableURI)
- }
- app.GetWindow().GetLayout().GetRightTabs().SelectAddedFilesTab()
- if isError {
- fileForConversion.message.Text = app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorDragAndDropFile",
- })
- setStringErrorStyle(fileForConversion.message)
- fileForConversion.eventSelectFile(errors.New(fileForConversion.message.Text))
- } else {
- fyne.Do(func() {
- fileForConversion.message.Text = ""
- fileForConversion.message.Refresh()
- })
- }
- })
-
- return fileForConversion
-}
-
-func (c fileForConversion) AddChangeCallback(callback func(err error)) {
- c.changeCallbacks[len(c.changeCallbacks)] = callback
-}
-
-func (c fileForConversion) eventSelectFile(err error) {
- for _, changeCallback := range c.changeCallbacks {
- changeCallback(err)
- }
-}
-
-type directoryForSaving struct {
- button *widget.Button
- message *canvas.Text
- path string
-}
-
-func newDirectoryForSaving(app kernel.AppContract, settingDirectoryForSaving setting.DirectoryForSavingContract) *directoryForSaving {
- directoryForSaving := &directoryForSaving{
- path: "",
- }
-
- directoryForSaving.message = canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
- directoryForSaving.message.TextSize = 16
- directoryForSaving.message.TextStyle = fyne.TextStyle{Bold: true}
-
- buttonTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "choose",
- })
-
- var locationURI fyne.ListableURI
-
- location, err := getDirectoryForSaving(settingDirectoryForSaving)
- if err == nil {
- directoryForSaving.path = location.Path()
- directoryForSaving.message.Text = location.Path()
- setStringSuccessStyle(directoryForSaving.message)
- }
-
- directoryForSaving.button = widget.NewButton(buttonTitle, func() {
- app.GetWindow().NewFolderOpen(func(r fyne.ListableURI, err error) {
- if err != nil {
- directoryForSaving.message.Text = err.Error()
- setStringErrorStyle(directoryForSaving.message)
- return
- }
- if r == nil {
- return
- }
-
- directoryForSaving.path = r.Path()
-
- directoryForSaving.message.Text = r.Path()
- setStringSuccessStyle(directoryForSaving.message)
- locationURI, err = storage.ListerForURI(r)
-
- if err == nil {
- _, _ = settingDirectoryForSaving.SaveDirectoryForSaving(locationURI.Path())
- }
-
- }, locationURI)
- })
-
- return directoryForSaving
-}
-
-func getDirectoryForSaving(settingDirectoryForSaving setting.DirectoryForSavingContract) (fyne.ListableURI, error) {
- path, err := settingDirectoryForSaving.GetDirectoryForSaving()
- if err != nil {
- return nil, err
- }
-
- if len(path) > 0 {
- path = "file://" + path
- }
-
- uri, err := storage.ParseURI(path)
- if err != nil {
- return nil, err
- }
-
- return storage.ListerForURI(uri)
-}
-
-type overwriteOutputFiles struct {
- checkbox *widget.Check
- isChecked bool
-}
-
-func newOverwriteOutputFiles(app kernel.AppContract) *overwriteOutputFiles {
- overwriteOutputFiles := &overwriteOutputFiles{
- isChecked: false,
- }
- checkboxOverwriteOutputFilesTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "checkboxOverwriteOutputFilesTitle",
- })
- overwriteOutputFiles.checkbox = widget.NewCheck(checkboxOverwriteOutputFilesTitle, func(b bool) {
- overwriteOutputFiles.isChecked = b
- })
-
- return overwriteOutputFiles
-}
-
-func (receiver overwriteOutputFiles) IsChecked() bool {
- return receiver.isChecked
-}
-
-type selectEncoder struct {
- SelectFileType *widget.RadioGroup
- SelectFormat *widget.Select
- SelectEncoder *widget.Select
- Encoder encoder2.EncoderContract
-
- changeCallbacks map[int]func(encoder encoder2.EncoderContract)
-}
-
-func newSelectEncoder(app kernel.AppContract, formats encoder.ConvertorFormatsContract) *selectEncoder {
- selectEncoder := &selectEncoder{
- changeCallbacks: map[int]func(encoder encoder2.EncoderContract){},
- }
-
- encoders := map[int]encoder2.EncoderDataContract{}
- selectEncoder.SelectEncoder = widget.NewSelect([]string{}, func(s string) {
- if encoders[selectEncoder.SelectEncoder.SelectedIndex()] == nil {
- return
- }
- selectEncoderData := encoders[selectEncoder.SelectEncoder.SelectedIndex()]
- selectEncoder.ChangeEncoder(selectEncoderData.NewEncoder())
- })
-
- formatSelected := ""
- selectEncoder.SelectFormat = widget.NewSelect([]string{}, func(s string) {
- if formatSelected == s {
- return
- }
- formatSelected = s
- format, err := formats.GetFormat(s)
- if err != nil {
- return
- }
- encoderOptions := []string{}
- encoders = map[int]encoder2.EncoderDataContract{}
- for _, e := range format.GetEncoders() {
- encoders[len(encoders)] = e
- encoderOptions = append(encoderOptions, app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "encoder_" + e.GetTitle()}))
- }
- selectEncoder.SelectEncoder.SetOptions(encoderOptions)
- selectEncoder.SelectEncoder.SetSelectedIndex(0)
- })
-
- fileTypeOptions := []string{}
- for _, fileType := range encoder2.GetListFileType() {
- fileTypeOptions = append(fileTypeOptions, fileType.Name())
- }
-
- encoderGroupVideo := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "encoderGroupVideo"})
- encoderGroupAudio := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "encoderGroupAudio"})
- encoderGroupImage := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "encoderGroupImage"})
- encoderGroup := map[string]string{
- encoderGroupVideo: "video",
- encoderGroupAudio: "audio",
- encoderGroupImage: "image",
- }
- selectEncoder.SelectFileType = widget.NewRadioGroup([]string{encoderGroupVideo, encoderGroupAudio, encoderGroupImage}, func(s string) {
- groupCode := encoderGroup[s]
-
- formatOptions := []string{}
- for _, f := range formats.GetFormats() {
- if groupCode != f.GetFileType().Name() {
- continue
- }
- formatOptions = append(formatOptions, f.GetTitle())
- }
- selectEncoder.SelectFormat.SetOptions(formatOptions)
- if groupCode == encoder2.FileType(encoder2.Video).Name() {
- selectEncoder.SelectFormat.SetSelected("mp4")
- } else {
- selectEncoder.SelectFormat.SetSelectedIndex(0)
- }
- })
- selectEncoder.SelectFileType.Horizontal = true
- selectEncoder.SelectFileType.Required = true
- selectEncoder.SelectFileType.SetSelected(encoderGroupVideo)
-
- return selectEncoder
-}
-
-func (e *selectEncoder) ChangeEncoder(encoder encoder2.EncoderContract) {
- e.Encoder = encoder
- e.eventSelectEncoder(e.Encoder)
-}
-
-func (e *selectEncoder) AddChangeCallback(callback func(encoder encoder2.EncoderContract)) {
- e.changeCallbacks[len(e.changeCallbacks)] = callback
-}
-
-func (e *selectEncoder) eventSelectEncoder(encoder encoder2.EncoderContract) {
- for _, changeCallback := range e.changeCallbacks {
- changeCallback(encoder)
- }
-}
-
-func setStringErrorStyle(text *canvas.Text) {
- text.Color = color.RGBA{R: 255, G: 0, B: 0, A: 255}
- text.Refresh()
-}
-
-func setStringSuccessStyle(text *canvas.Text) {
- text.Color = color.RGBA{R: 49, G: 127, B: 114, A: 255}
- text.Refresh()
-}
-
-func showConversionMessage(conversionMessage *canvas.Text, err error) {
- conversionMessage.Text = err.Error()
- setStringErrorStyle(conversionMessage)
-}
-
-type form struct {
- form *widget.Form
- items []*widget.FormItem
-}
-
-func newForm(app kernel.AppContract, items []*widget.FormItem) *form {
- f := widget.NewForm()
- f.SubmitText = app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "converterVideoFilesSubmitTitle",
- })
- f.Items = items
-
- return &form{
- form: f,
- items: items,
- }
-}
-
-func (f form) ChangeItems(items []*widget.FormItem) {
- f.form.Items = f.items
- f.form.Refresh()
- f.form.Items = append(f.form.Items, items...)
- f.form.Refresh()
-}
diff --git a/convertor/view/form_items/form.go b/convertor/view/form_items/form.go
deleted file mode 100644
index c0d1a7d..0000000
--- a/convertor/view/form_items/form.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package form_items
-
-import (
- "fyne.io/fyne/v2/widget"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor/view/form_items/h264_nvenc"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor/view/form_items/libx264"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor/view/form_items/libx265"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
-)
-
-var Views = map[string]func(encoder encoder.EncoderContract, app kernel.AppContract) []*widget.FormItem{
- "libx264": libx264.View,
- "h264_nvenc": h264_nvenc.View,
- "libx265": libx265.View,
-}
diff --git a/convertor/view_setting.go b/convertor/view_setting.go
deleted file mode 100644
index ca5e3f4..0000000
--- a/convertor/view_setting.go
+++ /dev/null
@@ -1,145 +0,0 @@
-package convertor
-
-import (
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/canvas"
- "fyne.io/fyne/v2/container"
- "fyne.io/fyne/v2/storage"
- "fyne.io/fyne/v2/widget"
- "github.com/nicksnyder/go-i18n/v2/i18n"
- "image/color"
- "net/url"
- "path/filepath"
-)
-
-func (v View) SelectFFPath(
- currentPathFfmpeg string,
- currentPathFfprobe string,
- currentPathFfplay string,
- save func(ffmpegPath string, ffprobePath string, ffplayPath string) error,
- cancel func(),
- donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error,
-) {
- errorMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
- errorMessage.TextSize = 16
- errorMessage.TextStyle = fyne.TextStyle{Bold: true}
-
- ffmpegPath, buttonFFmpeg, buttonFFmpegMessage := v.getButtonSelectFile(currentPathFfmpeg)
- ffprobePath, buttonFFprobe, buttonFFprobeMessage := v.getButtonSelectFile(currentPathFfprobe)
- ffplayPath, buttonFFplay, buttonFFplayMessage := v.getButtonSelectFile(currentPathFfplay)
-
- link := widget.NewHyperlink("https://ffmpeg.org/download.html", &url.URL{
- Scheme: "https",
- Host: "ffmpeg.org",
- Path: "download.html",
- })
-
- form := &widget.Form{
- Items: []*widget.FormItem{
- {
- Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "titleDownloadLink",
- }),
- Widget: link,
- },
- {
- Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "pathToFfmpeg",
- }),
- Widget: buttonFFmpeg,
- },
- {
- Widget: container.NewHScroll(buttonFFmpegMessage),
- },
- {
- Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "pathToFfprobe",
- }),
- Widget: buttonFFprobe,
- },
- {
- Widget: container.NewHScroll(buttonFFprobeMessage),
- },
- {
- Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "pathToFfplay",
- }),
- Widget: buttonFFplay,
- },
- {
- Widget: container.NewHScroll(buttonFFplayMessage),
- },
- {
- Widget: errorMessage,
- },
- },
- SubmitText: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "save",
- }),
- OnSubmit: func() {
- err := save(*ffmpegPath, *ffprobePath, *ffplayPath)
- if err != nil {
- errorMessage.Text = err.Error()
- }
- },
- }
- if cancel != nil {
- form.OnCancel = cancel
- form.CancelText = v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "cancel",
- })
- }
- selectFFPathTitle := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "selectFFPathTitle",
- })
-
- if v.downloadFFmpeg.blockDownloadFFmpegContainer == nil {
- v.downloadFFmpeg.blockDownloadFFmpegContainer = v.blockDownloadFFmpeg(donwloadFFmpeg)
- }
-
- v.app.GetWindow().SetContent(widget.NewCard(selectFFPathTitle, "", container.NewVBox(
- form,
- v.downloadFFmpeg.blockDownloadFFmpegContainer,
- )))
-}
-
-func (v View) getButtonSelectFile(path string) (filePath *string, button *widget.Button, buttonMessage *canvas.Text) {
- filePath = &path
-
- buttonMessage = canvas.NewText(path, color.RGBA{R: 49, G: 127, B: 114, A: 255})
- buttonMessage.TextSize = 16
- buttonMessage.TextStyle = fyne.TextStyle{Bold: true}
-
- buttonTitle := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "choose",
- })
-
- var locationURI fyne.ListableURI
- if len(path) > 0 {
- listableURI := storage.NewFileURI(filepath.Dir(path))
- locationURI, _ = storage.ListerForURI(listableURI)
- }
-
- button = widget.NewButton(buttonTitle, func() {
- v.app.GetWindow().NewFileOpen(func(r fyne.URIReadCloser, err error) {
- if err != nil {
- buttonMessage.Text = err.Error()
- setStringErrorStyle(buttonMessage)
- return
- }
- if r == nil {
- return
- }
-
- path = r.URI().Path()
-
- buttonMessage.Text = r.URI().Path()
- setStringSuccessStyle(buttonMessage)
-
- listableURI := storage.NewFileURI(filepath.Dir(r.URI().Path()))
- locationURI, _ = storage.ListerForURI(listableURI)
- }, locationURI)
- })
-
- return
-}
diff --git a/convertor/view_setting_button_download_ffmpeg_anyos.go b/convertor/view_setting_button_download_ffmpeg_anyos.go
deleted file mode 100644
index 794fd91..0000000
--- a/convertor/view_setting_button_download_ffmpeg_anyos.go
+++ /dev/null
@@ -1,17 +0,0 @@
-//go:build !windows && !linux
-// +build !windows,!linux
-
-package convertor
-
-import (
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/canvas"
- "fyne.io/fyne/v2/container"
- "fyne.io/fyne/v2/widget"
-)
-
-func (v View) blockDownloadFFmpeg(
- donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error,
-) *fyne.Container {
- return container.NewVBox()
-}
diff --git a/data/.gitignore b/data/.gitignore
deleted file mode 100644
index c96a04f..0000000
--- a/data/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*
-!.gitignore
\ No newline at end of file
diff --git a/db/db.go b/db/db.go
deleted file mode 100644
index ce2ddf9..0000000
--- a/db/db.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package db
-
-import "errors"
-
-var (
- ErrRecordNotFound = errors.New("record not found")
-)
diff --git a/dist/linux/Makefile b/dist/linux/Makefile
new file mode 100644
index 0000000..f8ba5e5
--- /dev/null
+++ b/dist/linux/Makefile
@@ -0,0 +1,39 @@
+# If PREFIX isn't provided, we check for $(DESTDIR)/usr/local and use that if it exists.
+# Otherwice we fall back to using /usr.
+
+LOCAL != test -d $(DESTDIR)/usr/local && echo -n "/local" || echo -n ""
+LOCAL ?= $(shell test -d $(DESTDIR)/usr/local && echo "/local" || echo "")
+PREFIX ?= /usr$(LOCAL)
+
+Name := "gui-for-ffmpeg"
+Exec := "gui-for-ffmpeg"
+Icon := "gui-for-ffmpeg.png"
+
+default:
+ # User install
+ # Run "make user-install" to install in ~/.local/
+ # Run "make user-uninstall" to uninstall from ~/.local/
+ #
+ # System install
+ # Run "sudo make install" to install the application.
+ # Run "sudo make uninstall" to uninstall the application.
+
+install:
+ install -Dm00644 usr/local/share/applications/$(Name).desktop $(DESTDIR)$(PREFIX)/share/applications/$(Name).desktop
+ install -Dm00755 usr/local/bin/$(Exec) $(DESTDIR)$(PREFIX)/bin/$(Exec)
+ install -Dm00644 usr/local/share/pixmaps/$(Icon) $(DESTDIR)$(PREFIX)/share/pixmaps/$(Icon)
+uninstall:
+ -rm $(DESTDIR)$(PREFIX)/share/applications/$(Name).desktop
+ -rm $(DESTDIR)$(PREFIX)/bin/$(Exec)
+ -rm $(DESTDIR)$(PREFIX)/share/pixmaps/$(Icon)
+
+user-install:
+ install -Dm00644 usr/local/share/applications/$(Name).desktop $(DESTDIR)$(HOME)/.local/share/applications/$(Name).desktop
+ install -Dm00755 usr/local/bin/$(Exec) $(DESTDIR)$(HOME)/.local/bin/$(Exec)
+ install -Dm00644 usr/local/share/pixmaps/$(Icon) $(DESTDIR)$(HOME)/.local/share/icons/$(Icon)
+ sed -i -e "s,Exec=$(Exec),Exec=$(DESTDIR)$(HOME)/.local/bin/$(Exec),g" $(DESTDIR)$(HOME)/.local/share/applications/$(Name).desktop
+
+user-uninstall:
+ -rm $(DESTDIR)$(HOME)/.local/share/applications/$(Name).desktop
+ -rm $(DESTDIR)$(HOME)/.local/bin/$(Exec)
+ -rm $(DESTDIR)$(HOME)/.local/share/icons/$(Icon)
diff --git a/dist/linux/Readme-eng.txt b/dist/linux/Readme-eng.txt
new file mode 100644
index 0000000..0548615
--- /dev/null
+++ b/dist/linux/Readme-eng.txt
@@ -0,0 +1,7 @@
+User install
+Run "make user-install" to install in ~/.local/
+Run "make user-uninstall" to uninstall from ~/.local/
+
+System install
+Run "sudo make install" to install the application.
+Run "sudo make uninstall" to uninstall the application.
diff --git a/dist/linux/Readme-rus.txt b/dist/linux/Readme-rus.txt
new file mode 100644
index 0000000..9331b2b
--- /dev/null
+++ b/dist/linux/Readme-rus.txt
@@ -0,0 +1,7 @@
+Установить для пользователя (рекомендуется)
+Запустите "make user-install" для установки в домашнюю папку ~/.local/
+Запустите "make user-uninstall" для удаления из домашней папки ~/.local/
+
+Установить для всей системы
+Запустить "sudo make install" Для установки в систему.
+Запустить "sudo make uninstall" Для удаления из системы.
diff --git a/dist/linux/usr/local/share/applications/gui-for-ffmpeg.desktop b/dist/linux/usr/local/share/applications/gui-for-ffmpeg.desktop
new file mode 100644
index 0000000..cda0b2b
--- /dev/null
+++ b/dist/linux/usr/local/share/applications/gui-for-ffmpeg.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Type=Application
+Name=GUI for FFmpeg
+GenericName=GUI for FFmpeg
+Exec=gui-for-ffmpeg
+Icon=gui-for-ffmpeg
+Comment=A simple interface for the FFmpeg console utility.
+Categories=AudioVideo;Utility;
+Keywords=ffmpeg;media;convert;transcode;audio;video;конвертер;видео;аудио;кодек;
diff --git a/encoder/apng/encoder.go b/encoder/apng/encoder.go
deleted file mode 100644
index c43b48a..0000000
--- a/encoder/apng/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package apng
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "apng"}
- }
-
- return encoder2.NewEncoder("apng", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "apng"
- formats := []string{"apng"}
- fileType := encoder2.FileType(encoder2.Image)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/bmp/encoder.go b/encoder/bmp/encoder.go
deleted file mode 100644
index f72a6d9..0000000
--- a/encoder/bmp/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package bmp
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "bmp"}
- }
-
- return encoder2.NewEncoder("bmp", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "bmp"
- formats := []string{"bmp"}
- fileType := encoder2.FileType(encoder2.Image)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/flv/encoder.go b/encoder/flv/encoder.go
deleted file mode 100644
index 7c2c8e4..0000000
--- a/encoder/flv/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package flv
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "flv"}
- }
-
- return encoder2.NewEncoder("flv", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "flv"
- formats := []string{"flv"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/gif/encoder.go b/encoder/gif/encoder.go
deleted file mode 100644
index d138ae1..0000000
--- a/encoder/gif/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package gif
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "gif"}
- }
-
- return encoder2.NewEncoder("gif", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "gif"
- formats := []string{"gif"}
- fileType := encoder2.FileType(encoder2.Image)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/libmp3lame/encoder.go b/encoder/libmp3lame/encoder.go
deleted file mode 100644
index 33c2f1a..0000000
--- a/encoder/libmp3lame/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package libmp3lame
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:a", "libmp3lame"}
- }
-
- return encoder2.NewEncoder("libmp3lame", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "libmp3lame"
- formats := []string{"mp3"}
- fileType := encoder2.FileType(encoder2.Audio)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/libshine/encoder.go b/encoder/libshine/encoder.go
deleted file mode 100644
index d7859b4..0000000
--- a/encoder/libshine/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package libshine
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:a", "libshine"}
- }
-
- return encoder2.NewEncoder("libshine", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "libshine"
- formats := []string{"mp3"}
- fileType := encoder2.FileType(encoder2.Audio)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/libtwolame/encoder.go b/encoder/libtwolame/encoder.go
deleted file mode 100644
index 87f5ba4..0000000
--- a/encoder/libtwolame/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package libtwolame
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:a", "libtwolame"}
- }
-
- return encoder2.NewEncoder("libtwolame", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "libtwolame"
- formats := []string{"mp2"}
- fileType := encoder2.FileType(encoder2.Audio)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/libvpx/encoder.go b/encoder/libvpx/encoder.go
deleted file mode 100644
index 86ab780..0000000
--- a/encoder/libvpx/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package libvpx
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "libvpx"}
- }
-
- return encoder2.NewEncoder("libvpx", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "libvpx"
- formats := []string{"webm", "mkv"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/libvpx_vp9/encoder.go b/encoder/libvpx_vp9/encoder.go
deleted file mode 100644
index 00cecc3..0000000
--- a/encoder/libvpx_vp9/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package libvpx_vp9
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "libvpx-vp9"}
- }
-
- return encoder2.NewEncoder("libvpx_vp9", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "libvpx-vp9"
- formats := []string{"webm", "mkv"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/libwebp/encoder.go b/encoder/libwebp/encoder.go
deleted file mode 100644
index b324503..0000000
--- a/encoder/libwebp/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package libwebp
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "libwebp"}
- }
-
- return encoder2.NewEncoder("libwebp", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "libwebp"
- formats := []string{"webp"}
- fileType := encoder2.FileType(encoder2.Image)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/libwebp_anim/encoder.go b/encoder/libwebp_anim/encoder.go
deleted file mode 100644
index 0a6fcc5..0000000
--- a/encoder/libwebp_anim/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package libwebp_anim
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "libwebp_anim"}
- }
-
- return encoder2.NewEncoder("libwebp_anim", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "libwebp_anim"
- formats := []string{"webp"}
- fileType := encoder2.FileType(encoder2.Image)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/libxvid/encoder.go b/encoder/libxvid/encoder.go
deleted file mode 100644
index fca496a..0000000
--- a/encoder/libxvid/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package libxvid
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "libxvid"}
- }
-
- return encoder2.NewEncoder("libxvid", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "libxvid"
- formats := []string{"avi"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/mjpeg/encoder.go b/encoder/mjpeg/encoder.go
deleted file mode 100644
index be934e7..0000000
--- a/encoder/mjpeg/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package mjpeg
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "mjpeg"}
- }
-
- return encoder2.NewEncoder("mjpeg", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "mjpeg"
- formats := []string{"jpg"}
- fileType := encoder2.FileType(encoder2.Image)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/mp2/encoder.go b/encoder/mp2/encoder.go
deleted file mode 100644
index 3d1a98e..0000000
--- a/encoder/mp2/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package mp2
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:a", "mp2"}
- }
-
- return encoder2.NewEncoder("mp2", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "mp2"
- formats := []string{"mp2"}
- fileType := encoder2.FileType(encoder2.Audio)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/mp2fixed/encoder.go b/encoder/mp2fixed/encoder.go
deleted file mode 100644
index c235bee..0000000
--- a/encoder/mp2fixed/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package mp2fixed
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:a", "mp2fixed"}
- }
-
- return encoder2.NewEncoder("mp2fixed", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "mp2fixed"
- formats := []string{"mp2"}
- fileType := encoder2.FileType(encoder2.Audio)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/mpeg1video/encoder.go b/encoder/mpeg1video/encoder.go
deleted file mode 100644
index 11c43e3..0000000
--- a/encoder/mpeg1video/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package mpeg1video
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "mpeg1video"}
- }
-
- return encoder2.NewEncoder("mpeg1video", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "mpeg1video"
- formats := []string{"mpg", "mpeg"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/mpeg2video/encoder.go b/encoder/mpeg2video/encoder.go
deleted file mode 100644
index 05192ef..0000000
--- a/encoder/mpeg2video/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package mpeg2video
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "mpeg2video"}
- }
-
- return encoder2.NewEncoder("mpeg2video", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "mpeg2video"
- formats := []string{"mpg", "mpeg"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/mpeg4/encoder.go b/encoder/mpeg4/encoder.go
deleted file mode 100644
index 5943f35..0000000
--- a/encoder/mpeg4/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package mpeg4
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "mpeg4"}
- }
-
- return encoder2.NewEncoder("mpeg4", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "mpeg4"
- formats := []string{"avi"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/msmpeg4/encoder.go b/encoder/msmpeg4/encoder.go
deleted file mode 100644
index 246683d..0000000
--- a/encoder/msmpeg4/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package msmpeg4
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "msmpeg4"}
- }
-
- return encoder2.NewEncoder("msmpeg4", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "msmpeg4"
- formats := []string{"avi"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/msmpeg4v2/encoder.go b/encoder/msmpeg4v2/encoder.go
deleted file mode 100644
index cc2cd5f..0000000
--- a/encoder/msmpeg4v2/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package msmpeg4v2
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "msmpeg4v2"}
- }
-
- return encoder2.NewEncoder("msmpeg4v2", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "msmpeg4v2"
- formats := []string{"avi"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/msvideo1/encoder.go b/encoder/msvideo1/encoder.go
deleted file mode 100644
index e9bd448..0000000
--- a/encoder/msvideo1/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package msvideo1
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "msvideo1"}
- }
-
- return encoder2.NewEncoder("msvideo1", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "msvideo1"
- formats := []string{"avi"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/png/encoder.go b/encoder/png/encoder.go
deleted file mode 100644
index 3166e58..0000000
--- a/encoder/png/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package png
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "png"}
- }
-
- return encoder2.NewEncoder("png", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "png"
- formats := []string{"png"}
- fileType := encoder2.FileType(encoder2.Image)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/qtrle/encoder.go b/encoder/qtrle/encoder.go
deleted file mode 100644
index befac18..0000000
--- a/encoder/qtrle/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package qtrle
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "qtrle"}
- }
-
- return encoder2.NewEncoder("qtrle", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "qtrle"
- formats := []string{"mov"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/sgi/encoder.go b/encoder/sgi/encoder.go
deleted file mode 100644
index b666b9b..0000000
--- a/encoder/sgi/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package sgi
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "sgi"}
- }
-
- return encoder2.NewEncoder("sgi", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "sgi"
- formats := []string{"sgi"}
- fileType := encoder2.FileType(encoder2.Image)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/tiff/encoder.go b/encoder/tiff/encoder.go
deleted file mode 100644
index 788d743..0000000
--- a/encoder/tiff/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package tiff
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "tiff"}
- }
-
- return encoder2.NewEncoder("tiff", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "tiff"
- formats := []string{"tiff"}
- fileType := encoder2.FileType(encoder2.Image)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/wmav1/encoder.go b/encoder/wmav1/encoder.go
deleted file mode 100644
index a2b9239..0000000
--- a/encoder/wmav1/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package wmav1
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:a", "wmav1"}
- }
-
- return encoder2.NewEncoder("wmav1", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "wmav1"
- formats := []string{"wma"}
- fileType := encoder2.FileType(encoder2.Audio)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/wmav2/encoder.go b/encoder/wmav2/encoder.go
deleted file mode 100644
index 66f490c..0000000
--- a/encoder/wmav2/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package wmav2
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:a", "wmav2"}
- }
-
- return encoder2.NewEncoder("wmav2", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "wmav2"
- formats := []string{"wma"}
- fileType := encoder2.FileType(encoder2.Audio)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/wmv1/encoder.go b/encoder/wmv1/encoder.go
deleted file mode 100644
index e5cf873..0000000
--- a/encoder/wmv1/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package wmv1
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "wmv1"}
- }
-
- return encoder2.NewEncoder("wmv1", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "wmv1"
- formats := []string{"wmv"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/wmv2/encoder.go b/encoder/wmv2/encoder.go
deleted file mode 100644
index 4ca9797..0000000
--- a/encoder/wmv2/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package wmv2
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "wmv2"}
- }
-
- return encoder2.NewEncoder("wmv2", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "wmv2"
- formats := []string{"wmv"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/encoder/xbm/encoder.go b/encoder/xbm/encoder.go
deleted file mode 100644
index d23f4a8..0000000
--- a/encoder/xbm/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package xbm
-
-import encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
-
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
- return []string{"-c:v", "xbm"}
- }
-
- return encoder2.NewEncoder("xbm", parameters, getParams)
-}
-
-func NewData() encoder2.EncoderDataContract {
- title := "xbm"
- formats := []string{"xbm"}
- fileType := encoder2.FileType(encoder2.Image)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
-}
diff --git a/error/view.go b/error/view.go
deleted file mode 100644
index 2d68856..0000000
--- a/error/view.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package error
-
-import (
- "errors"
- "fyne.io/fyne/v2/container"
- "fyne.io/fyne/v2/lang"
- "fyne.io/fyne/v2/widget"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/localizer"
- "github.com/nicksnyder/go-i18n/v2/i18n"
- "go.etcd.io/bbolt"
-)
-
-type ViewContract interface {
- PanicError(err error)
-}
-
-type View struct {
- app kernel.AppContract
- isSetLanguage bool
-}
-
-func NewView(app kernel.AppContract) *View {
- return &View{
- app: app,
- isSetLanguage: true,
- }
-}
-
-func (v View) PanicError(err error) {
- if v.isSetLanguage {
- v.isSetLanguage = false
- _ = v.app.GetLocalizerService().SetCurrentLanguageByCode(lang.SystemLocale().LanguageString())
- }
-
- messageHead := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "error",
- })
-
- messagetText := err.Error()
- if errors.Is(err, bbolt.ErrTimeout) {
- messagetText = v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorDatabaseTimeout",
- })
- }
-
- v.app.GetWindow().SetContent(container.NewBorder(
- container.NewVBox(
- widget.NewLabel(messageHead),
- widget.NewLabel(messagetText),
- ),
- nil,
- nil,
- nil,
- localizer.LanguageSelectionForm(v.app.GetLocalizerService(), func(lang kernel.Lang) {
- v.PanicError(err)
- }),
- ))
-}
-
-func (v View) PanicErrorWriteDirectoryData() {
- if v.isSetLanguage {
- v.isSetLanguage = false
- _ = v.app.GetLocalizerService().SetCurrentLanguageByCode(lang.SystemLocale().LanguageString())
- }
-
- message := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorDatabase",
- })
- messageHead := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "error",
- })
-
- v.app.GetWindow().SetContent(container.NewBorder(
- container.NewVBox(
- widget.NewLabel(messageHead),
- widget.NewLabel(message),
- ),
- nil,
- nil,
- nil,
- localizer.LanguageSelectionForm(v.app.GetLocalizerService(), func(lang kernel.Lang) {
- v.PanicErrorWriteDirectoryData()
- }),
- ))
-}
diff --git a/go.mod b/go.mod
index 721120e..2c96e56 100644
--- a/go.mod
+++ b/go.mod
@@ -6,16 +6,13 @@ toolchain go1.23.9
require (
fyne.io/fyne/v2 v2.6.1
- github.com/BurntSushi/toml v1.5.0
- github.com/nicksnyder/go-i18n/v2 v2.6.0
github.com/ulikunitz/xz v0.5.12
- go.etcd.io/bbolt v1.4.0
golang.org/x/image v0.27.0
- golang.org/x/text v0.25.0
)
require (
fyne.io/systray v1.11.0 // indirect
+ github.com/BurntSushi/toml v1.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fredbi/uri v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
@@ -34,6 +31,7 @@ require (
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
+ github.com/nicksnyder/go-i18n/v2 v2.6.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rymdport/portal v0.4.1 // indirect
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
@@ -42,5 +40,6 @@ require (
github.com/yuin/goldmark v1.7.11 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/sys v0.33.0 // indirect
+ golang.org/x/text v0.25.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index 9db999c..2efe54d 100644
--- a/go.sum
+++ b/go.sum
@@ -67,14 +67,10 @@ github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/yuin/goldmark v1.7.11 h1:ZCxLyDMtz0nT2HFfsYG8WZ47Trip2+JyLysKcMYE5bo=
github.com/yuin/goldmark v1.7.11/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
-go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=
-go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=
golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w=
golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
-golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
-golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
diff --git a/handler/convertor.go b/handler/convertor.go
deleted file mode 100644
index a0cd29b..0000000
--- a/handler/convertor.go
+++ /dev/null
@@ -1,185 +0,0 @@
-package handler
-
-import (
- "errors"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor/view"
- error2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/error"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/helper"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting"
- "github.com/nicksnyder/go-i18n/v2/i18n"
-)
-
-type ConvertorHandlerContract interface {
- MainConvertor()
- FfPathSelection()
- GetFfmpegVersion() (string, error)
- GetFfprobeVersion() (string, error)
- GetFfplayVersion() (string, error)
-}
-
-type ConvertorHandler struct {
- app kernel.AppContract
- convertorView convertor.ViewContract
- errorView error2.ViewContract
- convertorRepository convertor.RepositoryContract
- settingDirectoryForSaving setting.DirectoryForSavingContract
- itemsToConvertService kernel.ItemsToConvertContract
-}
-
-func NewConvertorHandler(
- app kernel.AppContract,
- convertorView convertor.ViewContract,
- errorView error2.ViewContract,
- convertorRepository convertor.RepositoryContract,
- settingDirectoryForSaving setting.DirectoryForSavingContract,
- itemsToConvertService kernel.ItemsToConvertContract,
-) *ConvertorHandler {
- return &ConvertorHandler{
- app: app,
- convertorView: convertorView,
- errorView: errorView,
- convertorRepository: convertorRepository,
- settingDirectoryForSaving: settingDirectoryForSaving,
- itemsToConvertService: itemsToConvertService,
- }
-}
-
-func (h ConvertorHandler) MainConvertor() {
- if h.checkingFFPathUtilities() == true {
- formats, err := h.app.GetConvertorService().GetSupportFormats()
- if err != nil {
- h.errorView.PanicError(err)
- return
- }
- conversion := view.NewConversion(h.app, formats, h.runConvert, h.settingDirectoryForSaving, h.itemsToConvertService)
- h.convertorView.Main(conversion)
- return
- }
- h.convertorView.SelectFFPath("", "", "", h.saveSettingFFPath, nil, h.downloadFFmpeg)
-}
-
-func (h ConvertorHandler) FfPathSelection() {
- ffmpeg, _ := h.convertorRepository.GetPathFfmpeg()
- ffprobe, _ := h.convertorRepository.GetPathFfprobe()
- ffplay, _ := h.convertorRepository.GetPathFfplay()
- h.convertorView.SelectFFPath(ffmpeg, ffprobe, ffplay, h.saveSettingFFPath, h.MainConvertor, h.downloadFFmpeg)
-}
-
-func (h ConvertorHandler) GetFfmpegVersion() (string, error) {
- return h.app.GetConvertorService().GetFFmpegVesrion()
-}
-
-func (h ConvertorHandler) GetFfprobeVersion() (string, error) {
- return h.app.GetConvertorService().GetFFprobeVersion()
-}
-
-func (h ConvertorHandler) GetFfplayVersion() (string, error) {
- return h.app.GetConvertorService().GetFFplayVersion()
-}
-
-func (h ConvertorHandler) runConvert(setting view.HandleConvertSetting) {
- h.app.GetWindow().GetLayout().GetRightTabs().SelectFileQueueTab()
-
- for _, item := range h.itemsToConvertService.GetItems() {
- file := item.GetFile()
- if file == nil {
- continue
- }
-
- h.app.GetQueue().Add(&kernel.ConvertSetting{
- VideoFileInput: *file,
- VideoFileOut: kernel.File{
- Path: setting.DirectoryForSave + helper.PathSeparator() + file.Name + "." + setting.Format,
- Name: file.Name,
- Ext: "." + setting.Format,
- },
- OverwriteOutputFiles: setting.OverwriteOutputFiles,
- Encoder: setting.Encoder,
- })
- }
- h.itemsToConvertService.AfterAddingQueue()
-}
-
-func (h ConvertorHandler) checkingFFPathUtilities() bool {
- if h.checkingFFPath() == true {
- return true
- }
-
- pathsToFF := getPathsToFF()
- for _, item := range pathsToFF {
- ffmpegChecking, _ := h.app.GetConvertorService().ChangeFFmpegPath(item.FFmpeg)
- if ffmpegChecking == false {
- continue
- }
- ffprobeChecking, _ := h.app.GetConvertorService().ChangeFFprobePath(item.FFprobe)
- if ffprobeChecking == false {
- continue
- }
-
- ffplayChecking, _ := h.app.GetConvertorService().ChangeFFplayPath(item.FFplay)
- if ffplayChecking == false {
- continue
- }
- _, _ = h.convertorRepository.SavePathFfmpeg(item.FFmpeg)
- _, _ = h.convertorRepository.SavePathFfprobe(item.FFprobe)
- _, _ = h.convertorRepository.SavePathFfplay(item.FFplay)
- return true
- }
-
- return false
-}
-
-func (h ConvertorHandler) saveSettingFFPath(ffmpegPath string, ffprobePath string, ffplayPath string) error {
- ffmpegChecking, _ := h.app.GetConvertorService().ChangeFFmpegPath(ffmpegPath)
- if ffmpegChecking == false {
- errorText := h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorFFmpeg",
- })
- return errors.New(errorText)
- }
-
- ffprobeChecking, _ := h.app.GetConvertorService().ChangeFFprobePath(ffprobePath)
- if ffprobeChecking == false {
- errorText := h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorFFprobe",
- })
- return errors.New(errorText)
- }
-
- ffplayChecking, _ := h.app.GetConvertorService().ChangeFFplayPath(ffplayPath)
- if ffplayChecking == false {
- errorText := h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorFFplay",
- })
- return errors.New(errorText)
- }
-
- _, _ = h.convertorRepository.SavePathFfmpeg(ffmpegPath)
- _, _ = h.convertorRepository.SavePathFfprobe(ffprobePath)
- _, _ = h.convertorRepository.SavePathFfplay(ffplayPath)
-
- h.MainConvertor()
-
- return nil
-}
-
-func (h ConvertorHandler) checkingFFPath() bool {
- _, err := h.app.GetConvertorService().GetFFmpegVesrion()
- if err != nil {
- return false
- }
-
- _, err = h.app.GetConvertorService().GetFFprobeVersion()
- if err != nil {
- return false
- }
-
- _, err = h.app.GetConvertorService().GetFFplayVersion()
- if err != nil {
- return false
- }
-
- return true
-}
diff --git a/handler/convertor_anyos.go b/handler/convertor_anyos.go
deleted file mode 100644
index 76daa45..0000000
--- a/handler/convertor_anyos.go
+++ /dev/null
@@ -1,18 +0,0 @@
-//go:build !windows && !linux
-// +build !windows,!linux
-
-package handler
-
-import (
- "fyne.io/fyne/v2/canvas"
- "fyne.io/fyne/v2/widget"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
-)
-
-func getPathsToFF() []kernel.FFPathUtilities {
- return []kernel.FFPathUtilities{{FFmpeg: "ffmpeg/bin/ffmpeg", FFprobe: "ffmpeg/bin/ffprobe", FFplay: "ffmpeg/bin/ffplay"}, {FFmpeg: "ffmpeg", FFprobe: "ffprobe", FFplay: "ffplay"}}
-}
-
-func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) {
- return nil
-}
diff --git a/handler/main.go b/handler/main.go
deleted file mode 100644
index 0e97c6f..0000000
--- a/handler/main.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package handler
-
-import (
- "fyne.io/fyne/v2/lang"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/localizer"
-)
-
-type MainHandler struct {
- app kernel.AppContract
- convertorHandler ConvertorHandlerContract
- menuHandler MenuHandlerContract
- localizerRepository localizer.RepositoryContract
-}
-
-func NewMainHandler(
- app kernel.AppContract,
- convertorHandler ConvertorHandlerContract,
- menuHandler MenuHandlerContract,
- localizerRepository localizer.RepositoryContract,
-) *MainHandler {
- return &MainHandler{
- app: app,
- convertorHandler: convertorHandler,
- menuHandler: menuHandler,
- localizerRepository: localizerRepository,
- }
-}
-
-func (h MainHandler) Start() {
- language, err := h.localizerRepository.GetCode()
- if err != nil {
- err = h.app.GetLocalizerService().SetCurrentLanguageByCode(lang.SystemLocale().LanguageString())
- if err != nil {
- h.menuHandler.LanguageSelection()
- return
- }
- }
- _ = h.app.GetLocalizerService().SetCurrentLanguageByCode(language)
-
- h.convertorHandler.MainConvertor()
-}
diff --git a/handler/menu.go b/handler/menu.go
deleted file mode 100644
index fa32d8b..0000000
--- a/handler/menu.go
+++ /dev/null
@@ -1,174 +0,0 @@
-package handler
-
-import (
- "fyne.io/fyne/v2"
- "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/theme"
- "github.com/nicksnyder/go-i18n/v2/i18n"
-)
-
-type MenuHandlerContract interface {
- GetMainMenu() *fyne.MainMenu
- LanguageSelection()
-}
-
-type MenuHandler struct {
- app kernel.AppContract
- convertorHandler ConvertorHandlerContract
- menuView menu.ViewContract
- menuViewSetting menu.ViewSettingContract
- localizerView localizer.ViewContract
- localizerRepository localizer.RepositoryContract
- themeService theme.ThemeContract
-}
-
-func NewMenuHandler(
- app kernel.AppContract,
- convertorHandler ConvertorHandlerContract,
- menuView menu.ViewContract,
- menuViewSetting menu.ViewSettingContract,
- localizerView localizer.ViewContract,
- localizerRepository localizer.RepositoryContract,
- themeService theme.ThemeContract,
-) *MenuHandler {
- return &MenuHandler{
- app: app,
- convertorHandler: convertorHandler,
- menuView: menuView,
- menuViewSetting: menuViewSetting,
- localizerView: localizerView,
- localizerRepository: localizerRepository,
- themeService: themeService,
- }
-}
-
-func (h MenuHandler) GetMainMenu() *fyne.MainMenu {
- settings := h.getMenuSettings()
- help := h.getMenuHelp()
-
- return fyne.NewMainMenu(settings, help)
-}
-
-func (h MenuHandler) getMenuSettings() *fyne.Menu {
- quit := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "exit",
- }), nil)
- quit.IsQuit = true
- h.app.GetLocalizerService().AddChangeCallback("exit", func(text string) {
- quit.Label = text
- })
-
- settingsSelection := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "settings",
- }), h.settingsSelection)
- h.app.GetLocalizerService().AddChangeCallback("settings", func(text string) {
- settingsSelection.Label = text
- })
-
- ffPathSelection := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "changeFFPath",
- }), h.convertorHandler.FfPathSelection)
- h.app.GetLocalizerService().AddChangeCallback("changeFFPath", func(text string) {
- ffPathSelection.Label = text
- })
-
- settings := fyne.NewMenu(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "settings",
- }), settingsSelection, ffPathSelection, quit)
- h.app.GetLocalizerService().AddChangeCallback("settings", func(text string) {
- settings.Label = text
- settings.Refresh()
- })
-
- return settings
-}
-
-func (h MenuHandler) getMenuHelp() *fyne.Menu {
- about := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "about",
- }), h.openAbout)
- h.app.GetLocalizerService().AddChangeCallback("about", func(text string) {
- about.Label = text
- })
-
- gratitude := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "gratitude",
- }), h.menuView.Gratitude)
- h.app.GetLocalizerService().AddChangeCallback("gratitude", func(text string) {
- gratitude.Label = text
- })
-
- helpFFplay := fyne.NewMenuItem(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplay",
- }), h.menuView.HelpFFplay)
- h.app.GetLocalizerService().AddChangeCallback("helpFFplay", func(text string) {
- helpFFplay.Label = text
- })
-
- help := fyne.NewMenu(h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "help",
- }), helpFFplay, about, gratitude)
- h.app.GetLocalizerService().AddChangeCallback("help", func(text string) {
- help.Label = text
- help.Refresh()
- })
-
- return help
-}
-
-func (h MenuHandler) openAbout() {
- ffmpeg, err := h.convertorHandler.GetFfmpegVersion()
- if err != nil {
- ffmpeg = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorFFmpegVersion",
- })
- }
- ffprobe, err := h.convertorHandler.GetFfprobeVersion()
- if err != nil {
- ffprobe = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorFFprobeVersion",
- })
- }
- ffplay, err := h.convertorHandler.GetFfplayVersion()
- if err != nil {
- ffplay = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorFFplayVersion",
- })
- }
-
- h.menuView.About(ffmpeg, ffprobe, ffplay)
-}
-
-func (h MenuHandler) LanguageSelection() {
- h.localizerView.LanguageSelection(func(lang kernel.Lang) {
- _, _ = h.localizerRepository.Save(lang.Code)
- h.convertorHandler.MainConvertor()
- })
-}
-
-func (h MenuHandler) settingsSelection() {
- save := func(setting *menu.SettingForm) error {
- err := h.app.GetLocalizerService().SetCurrentLanguage(setting.Language)
- if err != nil {
- return err
- }
- _, err = h.localizerRepository.Save(setting.Language.Code)
- if err != nil {
- return err
- }
-
- err = h.themeService.SetCurrentTheme(setting.ThemeInfo)
- if err != nil {
- return err
- }
-
- h.convertorHandler.MainConvertor()
- return nil
- }
- cancel := func() {
- h.convertorHandler.MainConvertor()
- }
- h.menuViewSetting.Main(save, cancel)
-}
diff --git a/images/screenshot-folder-structure.png b/images/screenshot-folder-structure.png
deleted file mode 100644
index 19b2a3f..0000000
Binary files a/images/screenshot-folder-structure.png and /dev/null differ
diff --git a/internal/application/app.go b/internal/application/app.go
new file mode 100644
index 0000000..dc26bf3
--- /dev/null
+++ b/internal/application/app.go
@@ -0,0 +1,137 @@
+package application
+
+import (
+ "fyne.io/fyne/v2"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/convertor"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/setting"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg"
+ "time"
+)
+
+type AppContract interface {
+ FyneApp() fyne.App
+ GetSetting() setting.SettingContract
+ GetProgressBarService() convertor.ProgressBarContract
+ GetFFmpegService() ffmpeg.UtilitiesContract
+ GetConvertorService() convertor.ConvertorContract
+ GetItemsToConvert() convertor.ItemsToConvertContract
+ GetQueueService() convertor.QueueListContract
+ Run()
+ AfterClosing()
+ RunConvertor()
+}
+
+type application struct {
+ fyneApp fyne.App
+ setting setting.SettingContract
+ progressBarService convertor.ProgressBarContract
+ ffmpegService ffmpeg.UtilitiesContract
+ itemsToConvert convertor.ItemsToConvertContract
+ queueService convertor.QueueListContract
+ convertorService convertor.ConvertorContract
+}
+
+func NewApp(
+ fyneApp fyne.App,
+ setting setting.SettingContract,
+ progressBarService convertor.ProgressBarContract,
+ ffmpegService ffmpeg.UtilitiesContract,
+ itemsToConvert convertor.ItemsToConvertContract,
+ queueService convertor.QueueListContract,
+ convertorService convertor.ConvertorContract,
+) AppContract {
+ return &application{
+ fyneApp: fyneApp,
+ setting: setting,
+ progressBarService: progressBarService,
+ ffmpegService: ffmpegService,
+ itemsToConvert: itemsToConvert,
+ queueService: queueService,
+ convertorService: convertorService,
+ }
+}
+
+func (a *application) FyneApp() fyne.App {
+ return a.fyneApp
+}
+
+func (a *application) GetSetting() setting.SettingContract {
+ return a.setting
+}
+
+func (a *application) GetProgressBarService() convertor.ProgressBarContract {
+ return a.progressBarService
+}
+
+func (a *application) GetFFmpegService() ffmpeg.UtilitiesContract {
+ return a.ffmpegService
+}
+
+func (a *application) GetItemsToConvert() convertor.ItemsToConvertContract {
+ return a.itemsToConvert
+}
+
+func (a *application) GetQueueService() convertor.QueueListContract {
+ return a.queueService
+}
+
+func (a *application) GetConvertorService() convertor.ConvertorContract {
+ return a.convertorService
+}
+
+func (a *application) Run() {
+ a.fyneApp.Run()
+}
+
+func (a *application) RunConvertor() {
+ go func() {
+ for {
+ time.Sleep(time.Millisecond * 3000)
+ queueId, queue := a.queueService.Next()
+ if queue == nil {
+ continue
+ }
+
+ queue.Status = convertor.StatusType(convertor.InProgress)
+ a.queueService.EventChangeQueue(queueId, queue)
+
+ if a.progressBarService.GetContainer().Hidden {
+ a.progressBarService.GetContainer().Show()
+ }
+
+ totalDuration := float64(0)
+ ffprobe, err := a.ffmpegService.GetFFprobe()
+ if err == nil {
+ totalDuration, err = ffprobe.GetTotalDuration(&queue.Setting.FileInput)
+ if err != nil {
+ totalDuration = float64(0)
+ }
+ }
+
+ progress := a.progressBarService.GetProgressbar(
+ totalDuration,
+ queue.Setting.FileInput.Path,
+ )
+
+ err = a.convertorService.RunConvert(*queue.Setting, progress)
+ if err != nil {
+ queue.Status = convertor.StatusType(convertor.Error)
+ queue.Error = err
+ a.queueService.EventChangeQueue(queueId, queue)
+ a.progressBarService.ProcessEndedWithError(err.Error())
+
+ continue
+ }
+
+ queue.Status = convertor.StatusType(convertor.Completed)
+ a.queueService.EventChangeQueue(queueId, queue)
+ a.progressBarService.ProcessEndedWithSuccess(&queue.Setting.FileOut)
+ }
+ }()
+}
+
+func (a *application) AfterClosing() {
+ for _, cmd := range a.convertorService.GetRunningProcesses() {
+ _ = cmd.Process.Kill()
+ }
+}
diff --git a/internal/application/convertor/convertor.go b/internal/application/convertor/convertor.go
new file mode 100644
index 0000000..2cce78b
--- /dev/null
+++ b/internal/application/convertor/convertor.go
@@ -0,0 +1,87 @@
+package convertor
+
+import (
+ "bufio"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/convertor/encoder"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg"
+ "io"
+ "os/exec"
+ "strings"
+)
+
+type ConvertorContract interface {
+ RunConvert(setting ffmpeg.ConvertSetting, progress ffmpeg.ProgressContract) error
+ GetSupportFormats() (encoder.ConvertorFormatsContract, error)
+ GetRunningProcesses() map[int]*exec.Cmd
+}
+
+type runningProcesses struct {
+ items map[int]*exec.Cmd
+ numberOfStarts int
+}
+
+type convertor struct {
+ ffmpegService ffmpeg.UtilitiesContract
+ runningProcesses *runningProcesses
+}
+
+func NewConvertor(
+ ffmpegService ffmpeg.UtilitiesContract,
+) ConvertorContract {
+ return &convertor{
+ ffmpegService: ffmpegService,
+ runningProcesses: &runningProcesses{items: map[int]*exec.Cmd{}, numberOfStarts: 0},
+ }
+}
+
+func (c *convertor) RunConvert(setting ffmpeg.ConvertSetting, progress ffmpeg.ProgressContract) error {
+ ffmpegService, err := c.ffmpegService.GetFFmpeg()
+ if err != nil {
+ return err
+ }
+
+ index := c.runningProcesses.numberOfStarts
+ beforeWait := func(cmd *exec.Cmd) {
+ c.runningProcesses.numberOfStarts++
+ c.runningProcesses.items[index] = cmd
+ }
+
+ afterWait := func(cmd *exec.Cmd) {
+ delete(c.runningProcesses.items, index)
+ }
+
+ return ffmpegService.RunConvert(setting, progress, beforeWait, afterWait)
+}
+
+func (c *convertor) GetSupportFormats() (encoder.ConvertorFormatsContract, error) {
+ var err error
+
+ formats := encoder.NewConvertorFormats()
+ ffmpeg, err := c.ffmpegService.GetFFmpeg()
+ if err != nil {
+ return formats, err
+ }
+ err = ffmpeg.GetEncoders(func(scanner *bufio.Reader) {
+ for {
+ line, _, err := scanner.ReadLine()
+ if err != nil {
+ if err == io.EOF {
+ break
+ }
+ continue
+ }
+ text := strings.Split(strings.TrimSpace(string(line)), " ")
+ encoderType := string(text[0][0])
+ if len(text) < 2 || (encoderType != "V" && encoderType != "A") {
+ continue
+ }
+ formats.NewEncoder(text[1])
+ }
+ })
+
+ return formats, err
+}
+
+func (c *convertor) GetRunningProcesses() map[int]*exec.Cmd {
+ return c.runningProcesses.items
+}
diff --git a/kernel/encoder/encoder.go b/internal/application/convertor/encoder/encoder.go
similarity index 66%
rename from kernel/encoder/encoder.go
rename to internal/application/convertor/encoder/encoder.go
index db4e25f..0da7a01 100644
--- a/kernel/encoder/encoder.go
+++ b/internal/application/convertor/encoder/encoder.go
@@ -2,7 +2,7 @@ package encoder
import (
"errors"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
)
type ConvertorFormatContract interface {
@@ -18,7 +18,7 @@ type ConvertorFormat struct {
encoders map[int]encoder.EncoderDataContract
}
-func NewConvertorFormat(title string, fileType encoder.FileTypeContract) *ConvertorFormat {
+func NewConvertorFormat(title string, fileType encoder.FileTypeContract) ConvertorFormatContract {
return &ConvertorFormat{
title: title,
fileType: fileType,
@@ -26,19 +26,19 @@ func NewConvertorFormat(title string, fileType encoder.FileTypeContract) *Conver
}
}
-func (f ConvertorFormat) GetTitle() string {
+func (f *ConvertorFormat) GetTitle() string {
return f.title
}
-func (f ConvertorFormat) AddEncoder(encoder encoder.EncoderDataContract) {
+func (f *ConvertorFormat) AddEncoder(encoder encoder.EncoderDataContract) {
f.encoders[len(f.encoders)] = encoder
}
-func (f ConvertorFormat) GetEncoders() map[int]encoder.EncoderDataContract {
+func (f *ConvertorFormat) GetEncoders() map[int]encoder.EncoderDataContract {
return f.encoders
}
-func (f ConvertorFormat) GetFileType() encoder.FileTypeContract {
+func (f *ConvertorFormat) GetFileType() encoder.FileTypeContract {
return f.fileType
}
@@ -52,13 +52,13 @@ type ConvertorFormats struct {
formats map[string]ConvertorFormatContract
}
-func NewConvertorFormats() *ConvertorFormats {
+func NewConvertorFormats() ConvertorFormatsContract {
return &ConvertorFormats{
formats: map[string]ConvertorFormatContract{},
}
}
-func (f ConvertorFormats) NewEncoder(encoderName string) bool {
+func (f *ConvertorFormats) NewEncoder(encoderName string) bool {
if supportEncoders[encoderName] == nil {
return false
}
@@ -72,13 +72,13 @@ func (f ConvertorFormats) NewEncoder(encoderName string) bool {
return true
}
-func (f ConvertorFormats) GetFormats() map[string]ConvertorFormatContract {
+func (f *ConvertorFormats) GetFormats() map[string]ConvertorFormatContract {
return f.formats
}
-func (f ConvertorFormats) GetFormat(format string) (ConvertorFormatContract, error) {
+func (f *ConvertorFormats) GetFormat(format string) (ConvertorFormatContract, error) {
if f.formats[format] == nil {
- return ConvertorFormat{}, errors.New("not found ConvertorFormat")
+ return &ConvertorFormat{}, errors.New("not found ConvertorFormat")
}
return f.formats[format], nil
}
diff --git a/internal/application/convertor/encoder/encoders.go b/internal/application/convertor/encoder/encoders.go
new file mode 100644
index 0000000..b2d2904
--- /dev/null
+++ b/internal/application/convertor/encoder/encoders.go
@@ -0,0 +1,74 @@
+package encoder
+
+import (
+ encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/apng"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/bmp"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/flv"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/gif"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/h264_nvenc"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libmp3lame"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libshine"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libtwolame"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libvpx"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libvpx_vp9"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libwebp"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libwebp_anim"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libx264"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libx265"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libxvid"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/mjpeg"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/mp2"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/mp2fixed"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/mpeg1video"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/mpeg2video"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/mpeg4"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/msmpeg4"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/msmpeg4v2"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/msvideo1"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/png"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/qtrle"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/sgi"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/tiff"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/wmav1"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/wmav2"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/wmv1"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/wmv2"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/xbm"
+)
+
+var supportEncoders = map[string]func() encoder2.EncoderDataContract{
+ "libx264": libx264.NewData,
+ "h264_nvenc": h264_nvenc.NewData,
+ "libx265": libx265.NewData,
+ "png": png.NewData,
+ "gif": gif.NewData,
+ "flv": flv.NewData,
+ "apng": apng.NewData,
+ "bmp": bmp.NewData,
+ "mjpeg": mjpeg.NewData,
+ "mpeg1video": mpeg1video.NewData,
+ "mpeg2video": mpeg2video.NewData,
+ "mpeg4": mpeg4.NewData,
+ "libxvid": libxvid.NewData,
+ "msmpeg4v2": msmpeg4v2.NewData,
+ "msmpeg4": msmpeg4.NewData,
+ "msvideo1": msvideo1.NewData,
+ "qtrle": qtrle.NewData,
+ "tiff": tiff.NewData,
+ "sgi": sgi.NewData,
+ "libvpx": libvpx.NewData,
+ "libvpx-vp9": libvpx_vp9.NewData,
+ "libwebp_anim": libwebp_anim.NewData,
+ "libwebp": libwebp.NewData,
+ "wmv1": wmv1.NewData,
+ "wmv2": wmv2.NewData,
+ "xbm": xbm.NewData,
+ "mp2": mp2.NewData,
+ "mp2fixed": mp2fixed.NewData,
+ "libtwolame": libtwolame.NewData,
+ "libmp3lame": libmp3lame.NewData,
+ "libshine": libshine.NewData,
+ "wmav1": wmav1.NewData,
+ "wmav2": wmav2.NewData,
+}
diff --git a/internal/application/convertor/items_to_convert.go b/internal/application/convertor/items_to_convert.go
new file mode 100644
index 0000000..32062c9
--- /dev/null
+++ b/internal/application/convertor/items_to_convert.go
@@ -0,0 +1,139 @@
+package convertor
+
+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"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg"
+)
+
+type ItemsToConvertContract interface {
+ Add(file *ffmpeg.File)
+ Clear()
+ GetItems() map[int]ItemToConvertContract
+ GetItemsContainer() *fyne.Container
+ AfterAddingQueue()
+ GetIsAutoRemove() bool
+ SetIsAutoRemove(isAutoRemove bool)
+}
+
+type itemsToConvert struct {
+ ffmpeg ffmpeg.UtilitiesContract
+ nextId int
+ items map[int]ItemToConvertContract
+ itemsContainer *fyne.Container
+ isAutoRemove bool
+}
+
+func NewItemsToConvert(ffmpeg ffmpeg.UtilitiesContract) ItemsToConvertContract {
+ return &itemsToConvert{
+ ffmpeg: ffmpeg,
+ nextId: 0,
+ items: map[int]ItemToConvertContract{},
+ itemsContainer: container.NewVBox(),
+ isAutoRemove: true,
+ }
+}
+
+func (items *itemsToConvert) GetItemsContainer() *fyne.Container {
+ return items.itemsContainer
+}
+
+func (items *itemsToConvert) Add(file *ffmpeg.File) {
+ nextId := items.nextId
+ var content *fyne.Container
+ var buttonPlay *widget.Button
+
+ buttonPlay = widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
+ buttonPlay.Disable()
+ go func() {
+ ffplay, err := items.ffmpeg.GetFFplay()
+ if err != nil {
+ fyne.Do(func() {
+ buttonPlay.Enable()
+ })
+ return
+ }
+
+ _ = ffplay.Play(file)
+ fyne.Do(func() {
+ buttonPlay.Enable()
+ })
+ }()
+ })
+
+ buttonRemove := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameDelete), func() {
+ items.itemsContainer.Remove(content)
+ items.itemsContainer.Refresh()
+ delete(items.items, nextId)
+ })
+ buttonRemove.Importance = widget.DangerImportance
+
+ content = container.NewVBox(
+ container.NewBorder(
+ nil,
+ nil,
+ buttonPlay,
+ buttonRemove,
+ container.NewHScroll(widget.NewLabel(file.Name)),
+ ),
+ container.NewHScroll(widget.NewLabel(file.Path)),
+ container.NewPadded(),
+ canvas.NewLine(theme.Color(theme.ColorNameFocus)),
+ container.NewPadded(),
+ )
+
+ items.itemsContainer.Add(content)
+ items.items[nextId] = newItemToConvert(file, content)
+ items.nextId++
+}
+
+func (items *itemsToConvert) GetIsAutoRemove() bool {
+ return items.isAutoRemove
+}
+
+func (items *itemsToConvert) SetIsAutoRemove(isAutoRemove bool) {
+ items.isAutoRemove = isAutoRemove
+}
+
+func (items *itemsToConvert) GetItems() map[int]ItemToConvertContract {
+ return items.items
+}
+
+func (items *itemsToConvert) AfterAddingQueue() {
+ if items.isAutoRemove {
+ items.Clear()
+ }
+}
+
+func (items *itemsToConvert) Clear() {
+ items.itemsContainer.RemoveAll()
+ items.items = map[int]ItemToConvertContract{}
+}
+
+type ItemToConvertContract interface {
+ GetFile() *ffmpeg.File
+ GetContent() *fyne.Container
+}
+
+type itemToConvert struct {
+ file *ffmpeg.File
+ content *fyne.Container
+}
+
+func newItemToConvert(file *ffmpeg.File, content *fyne.Container) ItemToConvertContract {
+ return &itemToConvert{
+ file: file,
+ content: content,
+ }
+}
+
+func (item *itemToConvert) GetFile() *ffmpeg.File {
+ return item.file
+}
+
+func (item *itemToConvert) GetContent() *fyne.Container {
+ return item.content
+}
diff --git a/internal/application/convertor/progressbar.go b/internal/application/convertor/progressbar.go
new file mode 100644
index 0000000..30c8155
--- /dev/null
+++ b/internal/application/convertor/progressbar.go
@@ -0,0 +1,217 @@
+package convertor
+
+import (
+ "bufio"
+ "errors"
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/canvas"
+ "fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/lang"
+ "fyne.io/fyne/v2/theme"
+ "fyne.io/fyne/v2/widget"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg"
+ "image/color"
+ "io"
+ "regexp"
+ "strconv"
+ "strings"
+)
+
+type ProgressBarContract interface {
+ GetContainer() *fyne.Container
+ GetProgressbar(totalDuration float64, filePath string) ffmpeg.ProgressContract
+ ProcessEndedWithError(errorText string)
+ ProcessEndedWithSuccess(file *ffmpeg.File)
+}
+
+type progressBar struct {
+ container *fyne.Container
+ label *widget.Label
+ progressbar *widget.ProgressBar
+ errorBlock *container.Scroll
+ messageError *canvas.Text
+ statusMessage *canvas.Text
+ buttonPlay *widget.Button
+ ffmpegService ffmpeg.UtilitiesContract
+}
+
+func NewProgressBar(ffmpegService ffmpeg.UtilitiesContract) 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,
+ ffmpegService: ffmpegService,
+ }
+}
+
+func (p *progressBar) GetContainer() *fyne.Container {
+ return p.container
+}
+
+func (p *progressBar) GetProgressbar(totalDuration float64, filePath string) ffmpeg.ProgressContract {
+ p.label.Text = filePath
+ p.statusMessage.Color = theme.Color(theme.ColorNamePrimary)
+ p.statusMessage.Text = lang.L("inProgressQueue")
+ p.messageError.Text = ""
+ fyne.Do(func() {
+ p.buttonPlay.Hide()
+ if p.errorBlock.Visible() {
+ p.errorBlock.Hide()
+ }
+ p.statusMessage.Refresh()
+ p.container.Refresh()
+ p.errorBlock.Refresh()
+ })
+
+ p.progressbar.Value = 0
+ return NewProgress(totalDuration, p.progressbar)
+}
+
+func (p *progressBar) ProcessEndedWithError(errorText string) {
+ fyne.Do(func() {
+ p.statusMessage.Color = theme.Color(theme.ColorNameError)
+ p.statusMessage.Text = lang.L("errorQueue")
+ p.messageError.Text = errorText
+ p.errorBlock.Show()
+ })
+}
+
+func (p *progressBar) ProcessEndedWithSuccess(file *ffmpeg.File) {
+ fyne.Do(func() {
+ p.statusMessage.Color = color.RGBA{R: 49, G: 127, B: 114, A: 255}
+ p.statusMessage.Text = lang.L("completedQueue")
+ p.buttonPlay.Show()
+ p.buttonPlay.OnTapped = func() {
+ p.buttonPlay.Disable()
+ go func() {
+ ffplay, err := p.ffmpegService.GetFFplay()
+ if err == nil {
+ _ = ffplay.Play(file)
+ }
+
+ fyne.Do(func() {
+ p.buttonPlay.Enable()
+ })
+ }()
+ }
+ })
+}
+
+type Progress struct {
+ totalDuration float64
+ progressbar *widget.ProgressBar
+ protocol string
+}
+
+func NewProgress(totalDuration float64, progressbar *widget.ProgressBar) ffmpeg.ProgressContract {
+ return &Progress{
+ totalDuration: totalDuration,
+ progressbar: progressbar,
+ protocol: "pipe:",
+ }
+}
+
+func (p *Progress) GetProtocole() string {
+ return p.protocol
+}
+
+func (p *Progress) Run(stdOut io.ReadCloser, stdErr io.ReadCloser) error {
+ isProcessCompleted := false
+ var errorText string
+
+ p.progressbar.Value = 0
+ p.progressbar.Max = p.totalDuration
+ fyne.Do(func() {
+ p.progressbar.Refresh()
+ })
+ progress := 0.0
+
+ go func() {
+ scannerErr := bufio.NewReader(stdErr)
+ for {
+ line, _, err := scannerErr.ReadLine()
+ if err != nil {
+ if err == io.EOF {
+ break
+ }
+ continue
+ }
+ data := strings.TrimSpace(string(line))
+ errorText = data
+ }
+ }()
+
+ scannerOut := bufio.NewReader(stdOut)
+ for {
+ line, _, err := scannerOut.ReadLine()
+ if err != nil {
+ if err == io.EOF {
+ break
+ }
+ continue
+ }
+ data := strings.TrimSpace(string(line))
+ if strings.Contains(data, "progress=end") {
+ p.progressbar.Value = p.totalDuration
+ fyne.Do(func() {
+ p.progressbar.Refresh()
+ })
+ isProcessCompleted = true
+ break
+ }
+
+ re := regexp.MustCompile(`frame=(\d+)`)
+ a := re.FindAllStringSubmatch(data, -1)
+
+ if len(a) > 0 && len(a[len(a)-1]) > 0 {
+ c, err := strconv.Atoi(a[len(a)-1][len(a[len(a)-1])-1])
+ if err != nil {
+ continue
+ }
+ progress = float64(c)
+ }
+ if p.progressbar.Value != progress {
+ p.progressbar.Value = progress
+ fyne.Do(func() {
+ p.progressbar.Refresh()
+ })
+ }
+ }
+
+ if isProcessCompleted == false {
+ if len(errorText) == 0 {
+ errorText = lang.L("errorConverter")
+ }
+ return errors.New(errorText)
+ }
+
+ return nil
+}
diff --git a/internal/application/convertor/queue.go b/internal/application/convertor/queue.go
new file mode 100644
index 0000000..455009c
--- /dev/null
+++ b/internal/application/convertor/queue.go
@@ -0,0 +1,152 @@
+package convertor
+
+import (
+ "errors"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg"
+)
+
+type Queue struct {
+ Setting *ffmpeg.ConvertSetting
+ Status StatusContract
+ Error error
+}
+
+type StatusContract interface {
+ Name() string
+ Ordinal() int
+}
+
+const (
+ Waiting = iota
+ InProgress
+ Completed
+ Error
+)
+
+type StatusType uint
+
+var statusTypeStrings = []string{
+ "waiting",
+ "inProgress",
+ "completed",
+ "error",
+}
+
+func (status StatusType) Name() string {
+ return statusTypeStrings[status]
+}
+
+func (status StatusType) Ordinal() int {
+ return int(status)
+}
+
+type QueueListenerContract interface {
+ AddQueue(key int, queue *Queue)
+ ChangeQueue(key int, queue *Queue)
+ RemoveQueue(key int, status StatusContract)
+}
+
+type QueueListContract interface {
+ AddListener(queueListener QueueListenerContract)
+ GetItems() map[int]*Queue
+ Add(setting *ffmpeg.ConvertSetting)
+ EventChangeQueue(key int, queue *Queue)
+ Remove(key int)
+ GetItem(key int) (*Queue, error)
+ Next() (key int, queue *Queue)
+}
+
+type queueList struct {
+ currentKey int
+ items map[int]*Queue
+ queue map[int]int
+ queueListener map[int]QueueListenerContract
+}
+
+func NewQueueList() QueueListContract {
+ return &queueList{
+ currentKey: 0,
+ items: map[int]*Queue{},
+ queue: map[int]int{},
+ queueListener: map[int]QueueListenerContract{},
+ }
+}
+
+func (l *queueList) GetItems() map[int]*Queue {
+ return l.items
+}
+
+func (l *queueList) Add(setting *ffmpeg.ConvertSetting) {
+ queue := Queue{
+ Setting: setting,
+ Status: StatusType(Waiting),
+ }
+
+ l.currentKey += 1
+ l.items[l.currentKey] = &queue
+ l.queue[l.currentKey] = l.currentKey
+
+ l.eventAdd(l.currentKey, &queue)
+}
+
+func (l *queueList) EventChangeQueue(key int, queue *Queue) {
+ l.eventChange(key, queue)
+}
+
+func (l *queueList) Remove(key int) {
+ if _, ok := l.queue[key]; ok {
+ delete(l.queue, key)
+ }
+
+ if _, ok := l.items[key]; ok {
+ status := l.items[key].Status
+ l.eventRemove(key, status)
+ delete(l.items, key)
+ }
+}
+
+func (l *queueList) GetItem(key int) (*Queue, error) {
+ if item, ok := l.items[key]; ok {
+ return item, nil
+ }
+
+ return nil, errors.New("key not found")
+}
+
+func (l *queueList) AddListener(queueListener QueueListenerContract) {
+ l.queueListener[len(l.queueListener)] = queueListener
+}
+
+func (l *queueList) Next() (key int, queue *Queue) {
+ statusWaiting := StatusType(Waiting)
+ for key, queueId := range l.queue {
+ if queue, ok := l.items[queueId]; ok {
+ if queue.Status == statusWaiting {
+ return queueId, queue
+ }
+ }
+
+ if _, ok := l.queue[key]; ok {
+ delete(l.queue, key)
+ }
+ }
+ return -1, nil
+}
+
+func (l *queueList) eventAdd(key int, queue *Queue) {
+ for _, listener := range l.queueListener {
+ listener.AddQueue(key, queue)
+ }
+}
+
+func (l *queueList) eventChange(key int, queue *Queue) {
+ for _, listener := range l.queueListener {
+ listener.ChangeQueue(key, queue)
+ }
+}
+
+func (l *queueList) eventRemove(key int, status StatusContract) {
+ for _, listener := range l.queueListener {
+ listener.RemoveQueue(key, status)
+ }
+}
diff --git a/internal/application/setting/ffmpeg.go b/internal/application/setting/ffmpeg.go
new file mode 100644
index 0000000..e20bb93
--- /dev/null
+++ b/internal/application/setting/ffmpeg.go
@@ -0,0 +1,40 @@
+package setting
+
+func (s *setting) GetFFmpegPath() string {
+ path := s.fyneApp.Preferences().String("ffmpegPath")
+ if path == "" {
+ return "ffmpeg"
+ }
+
+ return path
+}
+
+func (s *setting) SetFFmpegPath(path string) {
+ s.fyneApp.Preferences().SetString("ffmpegPath", path)
+}
+
+func (s *setting) GetFFprobePath() string {
+ path := s.fyneApp.Preferences().String("ffprobePath")
+ if path == "" {
+ return "ffprobe"
+ }
+
+ return path
+}
+
+func (s *setting) SetFFprobePath(path string) {
+ s.fyneApp.Preferences().SetString("ffprobePath", path)
+}
+
+func (s *setting) GetFFplayPath() string {
+ path := s.fyneApp.Preferences().String("ffplayPath")
+ if path == "" {
+ return "ffplay"
+ }
+
+ return path
+}
+
+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..b6afe5b
--- /dev/null
+++ b/internal/application/setting/setting.go
@@ -0,0 +1,84 @@
+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
+
+ GetDirectoryForSaving() string
+ SetDirectoryForSaving(path string)
+
+ GetFFmpegPath() string
+ SetFFmpegPath(path string)
+
+ GetFFprobePath() string
+ SetFFprobePath(path string)
+
+ GetFFplayPath() string
+ SetFFplayPath(path string)
+
+ ThemeInit()
+ GetThemes() map[string]ThemeInfoContract
+ GetTheme() ThemeInfoContract
+ SetTheme(themeInfo ThemeInfoContract)
+}
+
+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
+}
+
+func (s *setting) GetDirectoryForSaving() string {
+ return s.fyneApp.Preferences().String("directoryForSaving")
+}
+
+func (s *setting) SetDirectoryForSaving(path string) {
+ s.fyneApp.Preferences().SetString("directoryForSaving", path)
+}
diff --git a/internal/application/setting/theme.go b/internal/application/setting/theme.go
new file mode 100644
index 0000000..b81547b
--- /dev/null
+++ b/internal/application/setting/theme.go
@@ -0,0 +1,110 @@
+package setting
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/lang"
+ "fyne.io/fyne/v2/theme"
+ "image/color"
+)
+
+func (s *setting) GetTheme() ThemeInfoContract {
+ name := s.fyneApp.Preferences().String("theme")
+ if name != "" {
+ if _, ok := s.GetThemes()[name]; ok {
+ return s.GetThemes()[name]
+ }
+ }
+
+ return s.GetThemes()["default"]
+}
+
+func (s *setting) SetTheme(themeInfo ThemeInfoContract) {
+ s.fyneApp.Preferences().SetString("theme", themeInfo.GetName())
+
+ if themeInfo.GetName() == "default" {
+ s.fyneApp.Settings().SetTheme(theme.DefaultTheme())
+ return
+ }
+ s.fyneApp.Settings().SetTheme(&forcedVariant{theme: theme.DefaultTheme(), variant: themeInfo.GetVariant()})
+}
+
+func (s *setting) ThemeInit() {
+ themeInfo := s.GetTheme()
+ if themeInfo.GetName() == "default" {
+ s.fyneApp.Settings().SetTheme(theme.DefaultTheme())
+ return
+ }
+ s.fyneApp.Settings().SetTheme(&forcedVariant{theme: theme.DefaultTheme(), variant: themeInfo.GetVariant()})
+}
+
+func (s *setting) GetThemes() map[string]ThemeInfoContract {
+ themesNameDefault := &themeInfo{
+ name: "default",
+ title: lang.L("themesNameDefault"),
+ }
+
+ themesNameLight := &themeInfo{
+ name: "light",
+ title: lang.L("themesNameLight"),
+ variant: theme.VariantLight,
+ }
+
+ themesNameDark := &themeInfo{
+ name: "dark",
+ title: lang.L("themesNameDark"),
+ variant: theme.VariantDark,
+ }
+
+ list := map[string]ThemeInfoContract{
+ "default": themesNameDefault,
+ "light": themesNameLight,
+ "dark": themesNameDark,
+ }
+
+ return list
+}
+
+type ThemeInfoContract interface {
+ GetName() string
+ GetTitle() string
+ GetVariant() fyne.ThemeVariant
+}
+
+type themeInfo struct {
+ name string
+ title string
+ variant fyne.ThemeVariant
+}
+
+func (inf *themeInfo) GetName() string {
+ return inf.name
+}
+
+func (inf *themeInfo) GetTitle() string {
+ return inf.title
+}
+
+func (inf *themeInfo) GetVariant() fyne.ThemeVariant {
+ return inf.variant
+}
+
+type forcedVariant struct {
+ theme fyne.Theme
+ variant fyne.ThemeVariant
+}
+
+func (f *forcedVariant) Color(name fyne.ThemeColorName, _ fyne.ThemeVariant) color.Color {
+ return f.theme.Color(name, f.variant)
+}
+
+func (f *forcedVariant) Font(style fyne.TextStyle) fyne.Resource {
+ return theme.DefaultTheme().Font(style)
+}
+
+func (f *forcedVariant) Icon(name fyne.ThemeIconName) fyne.Resource {
+ return theme.DefaultTheme().Icon(name)
+}
+
+func (f *forcedVariant) Size(name fyne.ThemeSizeName) float32 {
+ return theme.DefaultTheme().Size(name)
+}
diff --git a/internal/controller/convertor.go b/internal/controller/convertor.go
new file mode 100644
index 0000000..445a32d
--- /dev/null
+++ b/internal/controller/convertor.go
@@ -0,0 +1,111 @@
+package controller
+
+import (
+ "errors"
+ "fyne.io/fyne/v2/lang"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/download/service"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils"
+)
+
+func (c *controller) convertor() {
+ formats, err := c.app.GetConvertorService().GetSupportFormats()
+ if err != nil {
+ c.startWithError(err)
+ return
+ }
+
+ content := view.Convertor(
+ c.window,
+ c.addFileForConversion,
+ c.app.GetSetting().GetDirectoryForSaving(),
+ c.setDirectoryForSaving,
+ formats,
+ c.addToConversion,
+ )
+ c.window.SetContent(content)
+}
+
+func (c *controller) addFileForConversion(file ffmpeg.File) {
+ c.app.GetItemsToConvert().Add(&file)
+ c.window.GetLayout().GetRContainer().SelectAddedFilesTab()
+}
+
+func (c *controller) setDirectoryForSaving(path string) {
+ c.app.GetSetting().SetDirectoryForSaving(path)
+}
+
+func (c *controller) addToConversion(convertSetting view.ConvertSetting) error {
+ if len(c.app.GetItemsToConvert().GetItems()) == 0 {
+ return errors.New(lang.L("errorNoFilesAddedForConversion"))
+ }
+ c.window.GetLayout().GetRContainer().SelectFileQueueTab()
+ for _, item := range c.app.GetItemsToConvert().GetItems() {
+ file := item.GetFile()
+ if file == nil {
+ continue
+ }
+
+ c.app.GetQueueService().Add(&ffmpeg.ConvertSetting{
+ FileInput: *file,
+ FileOut: ffmpeg.File{
+ Path: convertSetting.DirectoryForSave + utils.PathSeparator() + file.Name + "." + convertSetting.Format,
+ Name: file.Name,
+ Ext: "." + convertSetting.Format,
+ },
+ OverwriteOutputFiles: convertSetting.OverwriteOutputFiles,
+ Encoder: convertSetting.Encoder,
+ })
+ }
+ c.app.GetItemsToConvert().AfterAddingQueue()
+
+ return nil
+}
+
+func (c *controller) settingConvertor(isAllowCancellation bool) {
+ ffmpegPath := c.app.GetFFmpegService().GetFFmpegPath()
+ ffprobePath := c.app.GetFFmpegService().GetFFprobePath()
+ ffplayPath := c.app.GetFFmpegService().GetFFplayPath()
+
+ var cancel func()
+ cancel = nil
+ if isAllowCancellation {
+ cancel = func() {
+ c.convertor()
+ }
+ }
+
+ content := view.ConfiguringFFmpegUtilities(
+ c.window,
+ ffmpegPath,
+ ffprobePath,
+ ffplayPath,
+ c.saveSettingConvertor,
+ cancel,
+ service.DownloadFFmpeg(c.app, c.saveSettingConvertor),
+ )
+ c.window.SetContent(content)
+}
+
+func (c *controller) saveSettingConvertor(ffmpegPath string, ffprobePath string, ffplayPath string) error {
+ var err error
+
+ err = c.app.GetFFmpegService().ChangeFFmpeg(ffmpegPath)
+ if err != nil {
+ return err
+ }
+
+ c.app.GetFFmpegService().ChangeFFprobe(ffprobePath)
+ if err != nil {
+ return err
+ }
+
+ c.app.GetFFmpegService().ChangeFFplay(ffplayPath)
+ if err != nil {
+ return err
+ }
+
+ c.convertor()
+ return nil
+}
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..e6f0e75
--- /dev/null
+++ b/internal/controller/main.go
@@ -0,0 +1,96 @@
+package controller
+
+import (
+ "fyne.io/fyne/v2"
+ "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/menu"
+ "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.WindowContract
+}
+
+func NewController(app application.AppContract) ControllerContract {
+ fyneWindow := app.FyneApp().NewWindow("GUI for FFmpeg")
+ fyneWindow.SetMaster()
+ queueLayout := window.NewQueueLayout(app.GetFFmpegService())
+ app.GetQueueService().AddListener(queueLayout)
+
+ return &controller{
+ app: app,
+ window: window.NewMainWindow(
+ fyneWindow,
+ app.GetProgressBarService(),
+ app.GetItemsToConvert(),
+ queueLayout,
+ ),
+ }
+}
+
+func (c *controller) Start() {
+ isDefault, err := c.initLanguage()
+ if err != nil {
+ c.startWithError(err)
+ c.window.Show()
+ return
+ }
+
+ c.app.GetSetting().ThemeInit()
+
+ 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.initLayout()
+ c.verificareaFFmpeg()
+ })
+ c.window.SetContent(content)
+ c.window.Show()
+ return
+ }
+
+ c.initLayout()
+ c.verificareaFFmpeg()
+ c.window.Show()
+}
+
+func (c *controller) verificareaFFmpeg() {
+ if !c.app.GetFFmpegService().UtilityCheck() {
+ c.settingConvertor(false)
+ return
+ }
+
+ c.convertor()
+}
+
+func (c *controller) initLanguage() (isDefault bool, err error) {
+ lang, isDefault := c.app.GetSetting().GetCurrentLangOrDefaultLang()
+ err = setting.ChangeLang(lang)
+ return isDefault, err
+}
+
+func (c *controller) initLayout() {
+ c.window.SetMainMenu(fyne.NewMainMenu(
+ menu.MainMenuSettings(
+ c.actionMainSettings,
+ c.actionSettingConvertor,
+ ),
+ menu.MainMenuHelp(
+ c.actionAbout,
+ c.actionHelpFFplay,
+ ),
+ ))
+ c.window.InitLayout()
+}
diff --git a/internal/controller/menu.go b/internal/controller/menu.go
new file mode 100644
index 0000000..71e45ca
--- /dev/null
+++ b/internal/controller/menu.go
@@ -0,0 +1,67 @@
+package controller
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/lang"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view"
+)
+
+func (c *controller) actionSettingConvertor() {
+ c.settingConvertor(true)
+}
+
+func (c *controller) actionMainSettings() {
+ currentLang, _ := c.app.GetSetting().GetCurrentLangOrDefaultLang()
+ content := view.MainSettings(
+ currentLang,
+ c.app.GetSetting().GetLanguages(),
+
+ c.app.GetSetting().GetTheme(),
+ c.app.GetSetting().GetThemes(),
+
+ c.actionMainSettingsSave,
+ c.convertor,
+ )
+ c.window.SetContent(content)
+}
+
+func (c *controller) actionMainSettingsSave(setting *view.MainSettingForm) error {
+ err := c.app.GetSetting().SetLang(setting.Language)
+ if err != nil {
+ return err
+ }
+ c.app.GetSetting().SetTheme(setting.ThemeInfo)
+ c.initLayout()
+
+ c.convertor()
+ return nil
+}
+
+func (c *controller) actionAbout() {
+ ffmpegVersion := c.app.GetFFmpegService().GetFFmpegVersion()
+ ffprobeVersion := c.app.GetFFmpegService().GetFFprobeVersion()
+ ffplayVersion := c.app.GetFFmpegService().GetFFplayVersion()
+ appVersion := c.app.FyneApp().Metadata().Version
+
+ window := c.app.FyneApp().NewWindow(lang.L("about"))
+ window.Resize(fyne.Size{Width: 793, Height: 550})
+ window.SetFixedSize(true)
+
+ content := view.About(appVersion, ffmpegVersion, ffprobeVersion, ffplayVersion)
+
+ window.SetContent(content)
+ window.CenterOnScreen()
+ window.Show()
+}
+
+func (c *controller) actionHelpFFplay() {
+ window := c.app.FyneApp().NewWindow(lang.L("helpFFplay"))
+ window.Resize(fyne.Size{Width: 800, Height: 550})
+ window.SetFixedSize(true)
+
+ content := view.HelpFFplay()
+
+ window.SetContent(content)
+ window.CenterOnScreen()
+ window.Show()
+}
diff --git a/internal/ffmpeg/download/gui/download_anyos.go b/internal/ffmpeg/download/gui/download_anyos.go
new file mode 100644
index 0000000..6957f9d
--- /dev/null
+++ b/internal/ffmpeg/download/gui/download_anyos.go
@@ -0,0 +1,14 @@
+//go:build !windows && !linux
+// +build !windows,!linux
+
+package gui
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/canvas"
+ "fyne.io/fyne/v2/widget"
+)
+
+func DownloadFFmpeg(donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error) fyne.CanvasObject {
+ return container.NewVBox()
+}
diff --git a/convertor/view_setting_button_download_ffmpeg_linux.go b/internal/ffmpeg/download/gui/download_linux.go
similarity index 66%
rename from convertor/view_setting_button_download_ffmpeg_linux.go
rename to internal/ffmpeg/download/gui/download_linux.go
index aa462d3..4884408 100644
--- a/convertor/view_setting_button_download_ffmpeg_linux.go
+++ b/internal/ffmpeg/download/gui/download_linux.go
@@ -1,22 +1,19 @@
//go:build linux
// +build linux
-package convertor
+package gui
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/widget"
- "github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/image/colornames"
"image/color"
)
-func (v View) blockDownloadFFmpeg(
- donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error,
-) *fyne.Container {
-
+func DownloadFFmpeg(donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error) fyne.CanvasObject {
errorDownloadFFmpegMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
errorDownloadFFmpegMessage.TextSize = 16
errorDownloadFFmpegMessage.TextStyle = fyne.TextStyle{Bold: true}
@@ -29,9 +26,7 @@ func (v View) blockDownloadFFmpeg(
var buttonDownloadFFmpeg *widget.Button
- buttonDownloadFFmpeg = widget.NewButton(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "download",
- }), func() {
+ buttonDownloadFFmpeg = widget.NewButton(lang.L("download"), func() {
fyne.Do(func() {
buttonDownloadFFmpeg.Disable()
})
@@ -47,20 +42,16 @@ func (v View) blockDownloadFFmpeg(
})
- downloadFFmpegFromSiteMessage := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "downloadFFmpegFromSite",
- })
+ downloadFFmpegFromSiteMessage := lang.L("downloadFFmpegFromSite")
return container.NewVBox(
canvas.NewLine(colornames.Darkgreen),
- widget.NewCard(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "buttonDownloadFFmpeg",
- }), "", container.NewVBox(
+ widget.NewCard(lang.L("buttonDownloadFFmpeg"), "", container.NewVBox(
widget.NewRichTextFromMarkdown(
downloadFFmpegFromSiteMessage+" [https://github.com/BtbN/FFmpeg-Builds/releases](https://github.com/BtbN/FFmpeg-Builds/releases)",
),
buttonDownloadFFmpeg,
- errorDownloadFFmpegMessage,
+ container.NewHScroll(errorDownloadFFmpegMessage),
progressDownloadFFmpegMessage,
progressBar,
)),
diff --git a/convertor/view_setting_button_download_ffmpeg_windows.go b/internal/ffmpeg/download/gui/download_windows.go
similarity index 66%
rename from convertor/view_setting_button_download_ffmpeg_windows.go
rename to internal/ffmpeg/download/gui/download_windows.go
index 5b706b6..1841311 100644
--- a/convertor/view_setting_button_download_ffmpeg_windows.go
+++ b/internal/ffmpeg/download/gui/download_windows.go
@@ -1,22 +1,19 @@
//go:build windows
// +build windows
-package convertor
+package gui
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/widget"
- "github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/image/colornames"
"image/color"
)
-func (v View) blockDownloadFFmpeg(
- donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error,
-) *fyne.Container {
-
+func DownloadFFmpeg(donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error) fyne.CanvasObject {
errorDownloadFFmpegMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
errorDownloadFFmpegMessage.TextSize = 16
errorDownloadFFmpegMessage.TextStyle = fyne.TextStyle{Bold: true}
@@ -29,9 +26,7 @@ func (v View) blockDownloadFFmpeg(
var buttonDownloadFFmpeg *widget.Button
- buttonDownloadFFmpeg = widget.NewButton(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "download",
- }), func() {
+ buttonDownloadFFmpeg = widget.NewButton(lang.L("download"), func() {
go func() {
fyne.Do(func() {
@@ -47,20 +42,16 @@ func (v View) blockDownloadFFmpeg(
}()
})
- downloadFFmpegFromSiteMessage := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "downloadFFmpegFromSite",
- })
+ downloadFFmpegFromSiteMessage := lang.L("downloadFFmpegFromSite")
return container.NewVBox(
canvas.NewLine(colornames.Darkgreen),
- widget.NewCard(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "buttonDownloadFFmpeg",
- }), "", container.NewVBox(
+ widget.NewCard(lang.L("buttonDownloadFFmpeg"), "", container.NewVBox(
widget.NewRichTextFromMarkdown(
downloadFFmpegFromSiteMessage+" [https://github.com/BtbN/FFmpeg-Builds/releases](https://github.com/BtbN/FFmpeg-Builds/releases)",
),
buttonDownloadFFmpeg,
- errorDownloadFFmpegMessage,
+ container.NewHScroll(errorDownloadFFmpegMessage),
progressDownloadFFmpegMessage,
progressBar,
)),
diff --git a/internal/ffmpeg/download/service/download.go b/internal/ffmpeg/download/service/download.go
new file mode 100644
index 0000000..f0a8438
--- /dev/null
+++ b/internal/ffmpeg/download/service/download.go
@@ -0,0 +1,21 @@
+package service
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/canvas"
+ "fyne.io/fyne/v2/widget"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/download/gui"
+)
+
+func DownloadFFmpeg(app application.AppContract, save func(ffmpegPath string, ffprobePath string, ffplayPath string) error) fyne.CanvasObject {
+ return gui.DownloadFFmpeg(func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error {
+ var err error
+ err = startDownload(app, progressBar, progressMessage, save)
+ if err != nil {
+ return err
+ }
+
+ return nil
+ })
+}
diff --git a/internal/ffmpeg/download/service/download_anyos.go b/internal/ffmpeg/download/service/download_anyos.go
new file mode 100644
index 0000000..edee036
--- /dev/null
+++ b/internal/ffmpeg/download/service/download_anyos.go
@@ -0,0 +1,15 @@
+//go:build !windows && !linux
+// +build !windows,!linux
+
+package service
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/canvas"
+ "fyne.io/fyne/v2/widget"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application"
+)
+
+func startDownload(app application.AppContract, progressBar *widget.ProgressBar, progressMessage *canvas.Text, save func(ffmpegPath string, ffprobePath string, ffplayPath string) error) error {
+ return nil
+}
diff --git a/handler/convertor_linux.go b/internal/ffmpeg/download/service/download_linux.go
similarity index 67%
rename from handler/convertor_linux.go
rename to internal/ffmpeg/download/service/download_linux.go
index c1a032a..32d0af0 100644
--- a/handler/convertor_linux.go
+++ b/internal/ffmpeg/download/service/download_linux.go
@@ -1,16 +1,16 @@
//go:build linux
// +build linux
-package handler
+package service
import (
"archive/tar"
"errors"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
+ "fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/widget"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "github.com/nicksnyder/go-i18n/v2/i18n"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application"
"github.com/ulikunitz/xz"
"io"
"net/http"
@@ -18,67 +18,72 @@ import (
"path/filepath"
)
-func getPathsToFF() []kernel.FFPathUtilities {
- return []kernel.FFPathUtilities{{FFmpeg: "ffmpeg/bin/ffmpeg", FFprobe: "ffmpeg/bin/ffprobe", FFplay: "ffmpeg/bin/ffplay"}, {FFmpeg: "ffmpeg", FFprobe: "ffprobe", FFplay: "ffplay"}}
-}
+func startDownload(app application.AppContract, progressBar *widget.ProgressBar, progressMessage *canvas.Text, save func(ffmpegPath string, ffprobePath string, ffplayPath string) error) error {
+ var err error
-func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) {
- isDirectoryFFmpeg := isDirectory("ffmpeg")
- if isDirectoryFFmpeg == false {
- err = os.Mkdir("ffmpeg", 0777)
- if err != nil {
- return err
- }
+ dir, err := localSharePath()
+ if err != nil {
+ return err
}
- progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "downloadRun",
- })
- fyne.Do(func() {
- progressMessage.Refresh()
- })
- err = downloadFile("ffmpeg/ffmpeg.tar.xz", "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linux64-gpl.tar.xz", progressBar)
+ dir = filepath.Join(dir, "fyne", app.FyneApp().UniqueID())
+ err = os.MkdirAll(dir, 0755)
if err != nil {
return err
}
- progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "unzipRun",
- })
fyne.Do(func() {
+ progressMessage.Text = lang.L("downloadRun")
progressMessage.Refresh()
})
- err = unTarXz("ffmpeg/ffmpeg.tar.xz", "ffmpeg", progressBar)
+ err = downloadFile(dir+"/ffmpeg.tar.xz", "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linux64-gpl.tar.xz", progressBar)
if err != nil {
return err
}
- _ = os.Remove("ffmpeg/ffmpeg.tar.xz")
- progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "testFF",
- })
fyne.Do(func() {
+ progressMessage.Text = lang.L("unzipRun")
+ progressMessage.Refresh()
+ })
+ err = unTarXz(dir+"/ffmpeg.tar.xz", dir, progressBar)
+ if err != nil {
+ return err
+ }
+ _ = os.Remove(dir + "/ffmpeg.tar.xz")
+
+ fyne.Do(func() {
+ progressMessage.Text = lang.L("testFF")
progressMessage.Refresh()
})
- err = h.saveSettingFFPath(
- "ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/ffmpeg",
- "ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/ffprobe",
- "ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/ffplay",
+ err = save(
+ dir+"/ffmpeg-master-latest-linux64-gpl/bin/ffmpeg",
+ dir+"/ffmpeg-master-latest-linux64-gpl/bin/ffprobe",
+ dir+"/ffmpeg-master-latest-linux64-gpl/bin/ffplay",
)
if err != nil {
return err
}
- progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "completedQueue",
- })
fyne.Do(func() {
+ progressMessage.Text = lang.L("completedQueue")
progressMessage.Refresh()
})
return nil
}
+func localSharePath() (string, error) {
+ xdgDataHome := os.Getenv("XDG_DATA_HOME")
+ if xdgDataHome != "" {
+ return xdgDataHome, nil
+ }
+ homeDir, err := os.UserHomeDir()
+ if err != nil {
+ return "", err
+ }
+ return filepath.Join(homeDir, ".local", "share"), nil
+}
+
func downloadFile(filepath string, url string, progressBar *widget.ProgressBar) (err error) {
progressBar.Value = 0
progressBar.Max = 100
@@ -229,12 +234,3 @@ func unTarXz(fileTar string, directory string, progressBar *widget.ProgressBar)
return nil
}
-
-func isDirectory(path string) bool {
- fileInfo, err := os.Stat(path)
- if err != nil {
- return false
- }
-
- return fileInfo.IsDir()
-}
diff --git a/handler/convertor_windows.go b/internal/ffmpeg/download/service/download_windows.go
similarity index 62%
rename from handler/convertor_windows.go
rename to internal/ffmpeg/download/service/download_windows.go
index fb08d87..f3bc33f 100644
--- a/handler/convertor_windows.go
+++ b/internal/ffmpeg/download/service/download_windows.go
@@ -1,16 +1,16 @@
//go:build windows
// +build windows
-package handler
+package service
import (
"archive/zip"
"errors"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
+ "fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/widget"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "github.com/nicksnyder/go-i18n/v2/i18n"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application"
"io"
"net/http"
"os"
@@ -18,60 +18,50 @@ import (
"strings"
)
-func getPathsToFF() []kernel.FFPathUtilities {
- return []kernel.FFPathUtilities{{FFmpeg: "ffmpeg\\bin\\ffmpeg.exe", FFprobe: "ffmpeg\\bin\\ffprobe.exe", FFplay: "ffmpeg\\bin\\ffplay.exe"}}
-}
+func startDownload(app application.AppContract, progressBar *widget.ProgressBar, progressMessage *canvas.Text, save func(ffmpegPath string, ffprobePath string, ffplayPath string) error) error {
+ var err error
-func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) {
- isDirectoryFFmpeg := isDirectory("ffmpeg")
- if isDirectoryFFmpeg == false {
- err = os.Mkdir("ffmpeg", 0777)
- if err != nil {
- return err
- }
- }
- progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "downloadRun",
- })
- fyne.Do(func() {
- progressMessage.Refresh()
- })
- err = downloadFile("ffmpeg/ffmpeg.zip", "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip", progressBar)
+ dir := os.Getenv("APPDATA")
+ dir = filepath.Join(dir, "fyne", app.FyneApp().UniqueID())
+ err = os.MkdirAll(dir, 0755)
if err != nil {
return err
}
- progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "unzipRun",
- })
fyne.Do(func() {
+ progressMessage.Text = lang.L("downloadRun")
progressMessage.Refresh()
})
- err = unZip("ffmpeg/ffmpeg.zip", "ffmpeg", progressBar)
+ err = downloadFile(dir+"/ffmpeg.zip", "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip", progressBar)
if err != nil {
return err
}
- _ = os.Remove("ffmpeg/ffmpeg.zip")
- progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "testFF",
- })
fyne.Do(func() {
+ progressMessage.Text = lang.L("unzipRun")
progressMessage.Refresh()
})
- err = h.saveSettingFFPath(
- "ffmpeg/ffmpeg-master-latest-win64-gpl/bin/ffmpeg.exe",
- "ffmpeg/ffmpeg-master-latest-win64-gpl/bin/ffprobe.exe",
- "ffmpeg/ffmpeg-master-latest-win64-gpl/bin/ffplay.exe",
+ err = unZip(dir+"/ffmpeg.zip", dir, progressBar)
+ if err != nil {
+ return err
+ }
+ _ = os.Remove(dir + "/ffmpeg.zip")
+
+ fyne.Do(func() {
+ progressMessage.Text = lang.L("testFF")
+ progressMessage.Refresh()
+ })
+ err = save(
+ dir+"/ffmpeg-master-latest-win64-gpl/bin/ffmpeg.exe",
+ dir+"/ffmpeg-master-latest-win64-gpl/bin/ffprobe.exe",
+ dir+"/ffmpeg-master-latest-win64-gpl/bin/ffplay.exe",
)
if err != nil {
return err
}
- progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "completedQueue",
- })
fyne.Do(func() {
+ progressMessage.Text = lang.L("completedQueue")
progressMessage.Refresh()
})
@@ -183,12 +173,3 @@ func unZip(fileZip string, directory string, progressBar *widget.ProgressBar) er
return nil
}
-
-func isDirectory(path string) bool {
- fileInfo, err := os.Stat(path)
- if err != nil {
- return false
- }
-
- return fileInfo.IsDir()
-}
diff --git a/internal/ffmpeg/encoder/apng/encoder.go b/internal/ffmpeg/encoder/apng/encoder.go
new file mode 100644
index 0000000..8aad4f9
--- /dev/null
+++ b/internal/ffmpeg/encoder/apng/encoder.go
@@ -0,0 +1,21 @@
+package apng
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "apng"}
+ }
+
+ return encoder.NewEncoder("apng", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "apng"
+ formats := []string{"apng"}
+ fileType := encoder.FileType(encoder.Image)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/bmp/encoder.go b/internal/ffmpeg/encoder/bmp/encoder.go
new file mode 100644
index 0000000..2d12f86
--- /dev/null
+++ b/internal/ffmpeg/encoder/bmp/encoder.go
@@ -0,0 +1,21 @@
+package bmp
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "bmp"}
+ }
+
+ return encoder.NewEncoder("bmp", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "bmp"
+ formats := []string{"bmp"}
+ fileType := encoder.FileType(encoder.Image)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/encoder/encoder.go b/internal/ffmpeg/encoder/encoder.go
similarity index 73%
rename from encoder/encoder.go
rename to internal/ffmpeg/encoder/encoder.go
index 7aedf47..a3eb0ed 100644
--- a/encoder/encoder.go
+++ b/internal/ffmpeg/encoder/encoder.go
@@ -24,15 +24,15 @@ type EncoderDataContract interface {
NewEncoder() EncoderContract
}
-type Data struct {
+type data struct {
title string
formats []string
fileType FileTypeContract
encoder func() EncoderContract
}
-func NewData(title string, formats []string, fileType FileTypeContract, encoder func() EncoderContract) *Data {
- return &Data{
+func NewData(title string, formats []string, fileType FileTypeContract, encoder func() EncoderContract) EncoderDataContract {
+ return &data{
title: title,
formats: formats,
fileType: fileType,
@@ -40,19 +40,19 @@ func NewData(title string, formats []string, fileType FileTypeContract, encoder
}
}
-func (data Data) GetTitle() string {
+func (data *data) GetTitle() string {
return data.title
}
-func (data Data) GetFormats() []string {
+func (data *data) GetFormats() []string {
return data.formats
}
-func (data Data) NewEncoder() EncoderContract {
+func (data *data) NewEncoder() EncoderContract {
return data.encoder()
}
-func (data Data) GetFileType() FileTypeContract {
+func (data *data) GetFileType() FileTypeContract {
return data.fileType
}
@@ -91,29 +91,29 @@ func GetListFileType() []FileTypeContract {
}
}
-type Encoder struct {
+type encoder struct {
name string
parameters map[string]ParameterContract
getParams func(parameters map[string]ParameterContract) []string
}
-func NewEncoder(name string, parameters map[string]ParameterContract, getParams func(parameters map[string]ParameterContract) []string) *Encoder {
- return &Encoder{
+func NewEncoder(name string, parameters map[string]ParameterContract, getParams func(parameters map[string]ParameterContract) []string) EncoderContract {
+ return &encoder{
name: name,
parameters: parameters,
getParams: getParams,
}
}
-func (e *Encoder) GetName() string {
+func (e *encoder) GetName() string {
return e.name
}
-func (e *Encoder) GetParams() []string {
+func (e *encoder) GetParams() []string {
return e.getParams(e.parameters)
}
-func (e *Encoder) GetParameter(name string) (ParameterContract, error) {
+func (e *encoder) GetParameter(name string) (ParameterContract, error) {
if e.parameters[name] == nil {
return nil, errors.New("parameter not found")
}
@@ -121,15 +121,15 @@ func (e *Encoder) GetParameter(name string) (ParameterContract, error) {
return e.parameters[name], nil
}
-type Parameter struct {
+type parameter struct {
name string
isEnabled bool
parameter string
setParameter func(string) (string, error)
}
-func NewParameter(name string, isEnabled bool, defaultParameter string, setParameter func(string) (string, error)) *Parameter {
- return &Parameter{
+func NewParameter(name string, isEnabled bool, defaultParameter string, setParameter func(string) (string, error)) ParameterContract {
+ return ¶meter{
name: name,
isEnabled: isEnabled,
parameter: defaultParameter,
@@ -137,11 +137,11 @@ func NewParameter(name string, isEnabled bool, defaultParameter string, setParam
}
}
-func (p *Parameter) GetName() string {
+func (p *parameter) GetName() string {
return p.name
}
-func (p *Parameter) Set(s string) (err error) {
+func (p *parameter) Set(s string) (err error) {
if p.setParameter != nil {
s, err = p.setParameter(s)
if err != nil {
@@ -152,18 +152,18 @@ func (p *Parameter) Set(s string) (err error) {
return nil
}
-func (p *Parameter) Get() string {
+func (p *parameter) Get() string {
return p.parameter
}
-func (p *Parameter) IsEnabled() bool {
+func (p *parameter) IsEnabled() bool {
return p.isEnabled
}
-func (p *Parameter) SetEnable() {
+func (p *parameter) SetEnable() {
p.isEnabled = true
}
-func (p *Parameter) SetDisable() {
+func (p *parameter) SetDisable() {
p.isEnabled = false
}
diff --git a/internal/ffmpeg/encoder/flv/encoder.go b/internal/ffmpeg/encoder/flv/encoder.go
new file mode 100644
index 0000000..5a2fa14
--- /dev/null
+++ b/internal/ffmpeg/encoder/flv/encoder.go
@@ -0,0 +1,21 @@
+package flv
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "flv"}
+ }
+
+ return encoder.NewEncoder("flv", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "flv"
+ formats := []string{"flv"}
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/gif/encoder.go b/internal/ffmpeg/encoder/gif/encoder.go
new file mode 100644
index 0000000..98ae1e9
--- /dev/null
+++ b/internal/ffmpeg/encoder/gif/encoder.go
@@ -0,0 +1,21 @@
+package gif
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "gif"}
+ }
+
+ return encoder.NewEncoder("gif", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "gif"
+ formats := []string{"gif"}
+ fileType := encoder.FileType(encoder.Image)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/encoder/h264_nvenc/encoder.go b/internal/ffmpeg/encoder/h264_nvenc/encoder.go
similarity index 53%
rename from encoder/h264_nvenc/encoder.go
rename to internal/ffmpeg/encoder/h264_nvenc/encoder.go
index b064975..f52e3f5 100644
--- a/encoder/h264_nvenc/encoder.go
+++ b/internal/ffmpeg/encoder/h264_nvenc/encoder.go
@@ -2,7 +2,7 @@ package h264_nvenc
import (
"errors"
- encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
)
var Presets = []string{
@@ -20,11 +20,11 @@ var Presets = []string{
"losslesshp",
}
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{
"preset": newParameterPreset(),
}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
params := []string{"-c:v", "h264_nvenc"}
if parameters["preset"] != nil && parameters["preset"].IsEnabled() {
@@ -34,17 +34,17 @@ func NewEncoder() encoder2.EncoderContract {
return params
}
- return encoder2.NewEncoder("h264_nvenc", parameters, getParams)
+ return encoder.NewEncoder("h264_nvenc", parameters, getParams)
}
-func NewData() encoder2.EncoderDataContract {
+func NewData() encoder.EncoderDataContract {
title := "h264_nvenc"
formats := []string{"mp4"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
}
-func newParameterPreset() encoder2.ParameterContract {
+func newParameterPreset() encoder.ParameterContract {
setParameter := func(s string) (string, error) {
for _, value := range Presets {
if value == s {
@@ -54,5 +54,5 @@ func newParameterPreset() encoder2.ParameterContract {
return "", errors.New("preset not found")
}
- return encoder2.NewParameter("preset", false, "default", setParameter)
+ return encoder.NewParameter("preset", false, "default", setParameter)
}
diff --git a/internal/ffmpeg/encoder/libmp3lame/encoder.go b/internal/ffmpeg/encoder/libmp3lame/encoder.go
new file mode 100644
index 0000000..86112cb
--- /dev/null
+++ b/internal/ffmpeg/encoder/libmp3lame/encoder.go
@@ -0,0 +1,21 @@
+package libmp3lame
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:a", "libmp3lame"}
+ }
+
+ return encoder.NewEncoder("libmp3lame", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "libmp3lame"
+ formats := []string{"mp3"}
+ fileType := encoder.FileType(encoder.Audio)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/libshine/encoder.go b/internal/ffmpeg/encoder/libshine/encoder.go
new file mode 100644
index 0000000..87df433
--- /dev/null
+++ b/internal/ffmpeg/encoder/libshine/encoder.go
@@ -0,0 +1,21 @@
+package libshine
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:a", "libshine"}
+ }
+
+ return encoder.NewEncoder("libshine", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "libshine"
+ formats := []string{"mp3"}
+ fileType := encoder.FileType(encoder.Audio)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/libtwolame/encoder.go b/internal/ffmpeg/encoder/libtwolame/encoder.go
new file mode 100644
index 0000000..9e6623e
--- /dev/null
+++ b/internal/ffmpeg/encoder/libtwolame/encoder.go
@@ -0,0 +1,21 @@
+package libtwolame
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:a", "libtwolame"}
+ }
+
+ return encoder.NewEncoder("libtwolame", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "libtwolame"
+ formats := []string{"mp2"}
+ fileType := encoder.FileType(encoder.Audio)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/libvpx/encoder.go b/internal/ffmpeg/encoder/libvpx/encoder.go
new file mode 100644
index 0000000..42bd1f2
--- /dev/null
+++ b/internal/ffmpeg/encoder/libvpx/encoder.go
@@ -0,0 +1,21 @@
+package libvpx
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "libvpx"}
+ }
+
+ return encoder.NewEncoder("libvpx", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "libvpx"
+ formats := []string{"webm", "mkv"}
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/libvpx_vp9/encoder.go b/internal/ffmpeg/encoder/libvpx_vp9/encoder.go
new file mode 100644
index 0000000..717eb56
--- /dev/null
+++ b/internal/ffmpeg/encoder/libvpx_vp9/encoder.go
@@ -0,0 +1,21 @@
+package libvpx_vp9
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "libvpx-vp9"}
+ }
+
+ return encoder.NewEncoder("libvpx_vp9", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "libvpx-vp9"
+ formats := []string{"webm", "mkv"}
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/libwebp/encoder.go b/internal/ffmpeg/encoder/libwebp/encoder.go
new file mode 100644
index 0000000..5418bbc
--- /dev/null
+++ b/internal/ffmpeg/encoder/libwebp/encoder.go
@@ -0,0 +1,21 @@
+package libwebp
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "libwebp"}
+ }
+
+ return encoder.NewEncoder("libwebp", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "libwebp"
+ formats := []string{"webp"}
+ fileType := encoder.FileType(encoder.Image)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/libwebp_anim/encoder.go b/internal/ffmpeg/encoder/libwebp_anim/encoder.go
new file mode 100644
index 0000000..549e589
--- /dev/null
+++ b/internal/ffmpeg/encoder/libwebp_anim/encoder.go
@@ -0,0 +1,21 @@
+package libwebp_anim
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "libwebp_anim"}
+ }
+
+ return encoder.NewEncoder("libwebp_anim", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "libwebp_anim"
+ formats := []string{"webp"}
+ fileType := encoder.FileType(encoder.Image)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/encoder/libx264/encoder.go b/internal/ffmpeg/encoder/libx264/encoder.go
similarity index 53%
rename from encoder/libx264/encoder.go
rename to internal/ffmpeg/encoder/libx264/encoder.go
index 5543570..0a3070f 100644
--- a/encoder/libx264/encoder.go
+++ b/internal/ffmpeg/encoder/libx264/encoder.go
@@ -2,7 +2,7 @@ package libx264
import (
"errors"
- encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
)
var Presets = []string{
@@ -18,11 +18,11 @@ var Presets = []string{
"placebo",
}
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{
"preset": newParameterPreset(),
}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
params := []string{"-c:v", "libx264"}
if parameters["preset"] != nil && parameters["preset"].IsEnabled() {
@@ -32,17 +32,17 @@ func NewEncoder() encoder2.EncoderContract {
return params
}
- return encoder2.NewEncoder("libx264", parameters, getParams)
+ return encoder.NewEncoder("libx264", parameters, getParams)
}
-func NewData() encoder2.EncoderDataContract {
+func NewData() encoder.EncoderDataContract {
title := "libx264"
formats := []string{"mp4"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
}
-func newParameterPreset() encoder2.ParameterContract {
+func newParameterPreset() encoder.ParameterContract {
setParameter := func(s string) (string, error) {
for _, value := range Presets {
if value == s {
@@ -52,5 +52,5 @@ func newParameterPreset() encoder2.ParameterContract {
return "", errors.New("preset not found")
}
- return encoder2.NewParameter("preset", false, "medium", setParameter)
+ return encoder.NewParameter("preset", false, "medium", setParameter)
}
diff --git a/encoder/libx265/encoder.go b/internal/ffmpeg/encoder/libx265/encoder.go
similarity index 53%
rename from encoder/libx265/encoder.go
rename to internal/ffmpeg/encoder/libx265/encoder.go
index 1d4a1f3..0d4dbc3 100644
--- a/encoder/libx265/encoder.go
+++ b/internal/ffmpeg/encoder/libx265/encoder.go
@@ -2,7 +2,7 @@ package libx265
import (
"errors"
- encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
)
var Presets = []string{
@@ -18,11 +18,11 @@ var Presets = []string{
"placebo",
}
-func NewEncoder() encoder2.EncoderContract {
- parameters := map[string]encoder2.ParameterContract{
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{
"preset": newParameterPreset(),
}
- getParams := func(parameters map[string]encoder2.ParameterContract) []string {
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
params := []string{"-c:v", "libx265"}
if parameters["preset"] != nil && parameters["preset"].IsEnabled() {
@@ -32,17 +32,17 @@ func NewEncoder() encoder2.EncoderContract {
return params
}
- return encoder2.NewEncoder("libx265", parameters, getParams)
+ return encoder.NewEncoder("libx265", parameters, getParams)
}
-func NewData() encoder2.EncoderDataContract {
+func NewData() encoder.EncoderDataContract {
title := "libx265"
formats := []string{"mp4"}
- fileType := encoder2.FileType(encoder2.Video)
- return encoder2.NewData(title, formats, fileType, NewEncoder)
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
}
-func newParameterPreset() encoder2.ParameterContract {
+func newParameterPreset() encoder.ParameterContract {
setParameter := func(s string) (string, error) {
for _, value := range Presets {
if value == s {
@@ -52,5 +52,5 @@ func newParameterPreset() encoder2.ParameterContract {
return "", errors.New("preset not found")
}
- return encoder2.NewParameter("preset", false, "medium", setParameter)
+ return encoder.NewParameter("preset", false, "medium", setParameter)
}
diff --git a/internal/ffmpeg/encoder/libxvid/encoder.go b/internal/ffmpeg/encoder/libxvid/encoder.go
new file mode 100644
index 0000000..6f09a1e
--- /dev/null
+++ b/internal/ffmpeg/encoder/libxvid/encoder.go
@@ -0,0 +1,21 @@
+package libxvid
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "libxvid"}
+ }
+
+ return encoder.NewEncoder("libxvid", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "libxvid"
+ formats := []string{"avi"}
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/mjpeg/encoder.go b/internal/ffmpeg/encoder/mjpeg/encoder.go
new file mode 100644
index 0000000..3252837
--- /dev/null
+++ b/internal/ffmpeg/encoder/mjpeg/encoder.go
@@ -0,0 +1,21 @@
+package mjpeg
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "mjpeg"}
+ }
+
+ return encoder.NewEncoder("mjpeg", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "mjpeg"
+ formats := []string{"jpg"}
+ fileType := encoder.FileType(encoder.Image)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/mp2/encoder.go b/internal/ffmpeg/encoder/mp2/encoder.go
new file mode 100644
index 0000000..da4221d
--- /dev/null
+++ b/internal/ffmpeg/encoder/mp2/encoder.go
@@ -0,0 +1,21 @@
+package mp2
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:a", "mp2"}
+ }
+
+ return encoder.NewEncoder("mp2", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "mp2"
+ formats := []string{"mp2"}
+ fileType := encoder.FileType(encoder.Audio)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/mp2fixed/encoder.go b/internal/ffmpeg/encoder/mp2fixed/encoder.go
new file mode 100644
index 0000000..79cb7c7
--- /dev/null
+++ b/internal/ffmpeg/encoder/mp2fixed/encoder.go
@@ -0,0 +1,21 @@
+package mp2fixed
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:a", "mp2fixed"}
+ }
+
+ return encoder.NewEncoder("mp2fixed", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "mp2fixed"
+ formats := []string{"mp2"}
+ fileType := encoder.FileType(encoder.Audio)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/mpeg1video/encoder.go b/internal/ffmpeg/encoder/mpeg1video/encoder.go
new file mode 100644
index 0000000..18e7753
--- /dev/null
+++ b/internal/ffmpeg/encoder/mpeg1video/encoder.go
@@ -0,0 +1,21 @@
+package mpeg1video
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "mpeg1video"}
+ }
+
+ return encoder.NewEncoder("mpeg1video", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "mpeg1video"
+ formats := []string{"mpg", "mpeg"}
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/mpeg2video/encoder.go b/internal/ffmpeg/encoder/mpeg2video/encoder.go
new file mode 100644
index 0000000..a27bb0c
--- /dev/null
+++ b/internal/ffmpeg/encoder/mpeg2video/encoder.go
@@ -0,0 +1,21 @@
+package mpeg2video
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "mpeg2video"}
+ }
+
+ return encoder.NewEncoder("mpeg2video", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "mpeg2video"
+ formats := []string{"mpg", "mpeg"}
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/mpeg4/encoder.go b/internal/ffmpeg/encoder/mpeg4/encoder.go
new file mode 100644
index 0000000..6f22876
--- /dev/null
+++ b/internal/ffmpeg/encoder/mpeg4/encoder.go
@@ -0,0 +1,21 @@
+package mpeg4
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "mpeg4"}
+ }
+
+ return encoder.NewEncoder("mpeg4", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "mpeg4"
+ formats := []string{"avi"}
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/msmpeg4/encoder.go b/internal/ffmpeg/encoder/msmpeg4/encoder.go
new file mode 100644
index 0000000..3bcf5d8
--- /dev/null
+++ b/internal/ffmpeg/encoder/msmpeg4/encoder.go
@@ -0,0 +1,21 @@
+package msmpeg4
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "msmpeg4"}
+ }
+
+ return encoder.NewEncoder("msmpeg4", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "msmpeg4"
+ formats := []string{"avi"}
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/msmpeg4v2/encoder.go b/internal/ffmpeg/encoder/msmpeg4v2/encoder.go
new file mode 100644
index 0000000..296730f
--- /dev/null
+++ b/internal/ffmpeg/encoder/msmpeg4v2/encoder.go
@@ -0,0 +1,21 @@
+package msmpeg4v2
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "msmpeg4v2"}
+ }
+
+ return encoder.NewEncoder("msmpeg4v2", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "msmpeg4v2"
+ formats := []string{"avi"}
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/msvideo1/encoder.go b/internal/ffmpeg/encoder/msvideo1/encoder.go
new file mode 100644
index 0000000..d9e22ca
--- /dev/null
+++ b/internal/ffmpeg/encoder/msvideo1/encoder.go
@@ -0,0 +1,21 @@
+package msvideo1
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "msvideo1"}
+ }
+
+ return encoder.NewEncoder("msvideo1", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "msvideo1"
+ formats := []string{"avi"}
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/png/encoder.go b/internal/ffmpeg/encoder/png/encoder.go
new file mode 100644
index 0000000..06bac92
--- /dev/null
+++ b/internal/ffmpeg/encoder/png/encoder.go
@@ -0,0 +1,21 @@
+package png
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "png"}
+ }
+
+ return encoder.NewEncoder("png", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "png"
+ formats := []string{"png"}
+ fileType := encoder.FileType(encoder.Image)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/qtrle/encoder.go b/internal/ffmpeg/encoder/qtrle/encoder.go
new file mode 100644
index 0000000..0641480
--- /dev/null
+++ b/internal/ffmpeg/encoder/qtrle/encoder.go
@@ -0,0 +1,21 @@
+package qtrle
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "qtrle"}
+ }
+
+ return encoder.NewEncoder("qtrle", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "qtrle"
+ formats := []string{"mov"}
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/sgi/encoder.go b/internal/ffmpeg/encoder/sgi/encoder.go
new file mode 100644
index 0000000..3d49a3c
--- /dev/null
+++ b/internal/ffmpeg/encoder/sgi/encoder.go
@@ -0,0 +1,21 @@
+package sgi
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "sgi"}
+ }
+
+ return encoder.NewEncoder("sgi", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "sgi"
+ formats := []string{"sgi"}
+ fileType := encoder.FileType(encoder.Image)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/tiff/encoder.go b/internal/ffmpeg/encoder/tiff/encoder.go
new file mode 100644
index 0000000..ad43a9d
--- /dev/null
+++ b/internal/ffmpeg/encoder/tiff/encoder.go
@@ -0,0 +1,21 @@
+package tiff
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "tiff"}
+ }
+
+ return encoder.NewEncoder("tiff", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "tiff"
+ formats := []string{"tiff"}
+ fileType := encoder.FileType(encoder.Image)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/wmav1/encoder.go b/internal/ffmpeg/encoder/wmav1/encoder.go
new file mode 100644
index 0000000..2aa5af1
--- /dev/null
+++ b/internal/ffmpeg/encoder/wmav1/encoder.go
@@ -0,0 +1,21 @@
+package wmav1
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:a", "wmav1"}
+ }
+
+ return encoder.NewEncoder("wmav1", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "wmav1"
+ formats := []string{"wma"}
+ fileType := encoder.FileType(encoder.Audio)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/wmav2/encoder.go b/internal/ffmpeg/encoder/wmav2/encoder.go
new file mode 100644
index 0000000..61e2cb5
--- /dev/null
+++ b/internal/ffmpeg/encoder/wmav2/encoder.go
@@ -0,0 +1,21 @@
+package wmav2
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:a", "wmav2"}
+ }
+
+ return encoder.NewEncoder("wmav2", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "wmav2"
+ formats := []string{"wma"}
+ fileType := encoder.FileType(encoder.Audio)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/wmv1/encoder.go b/internal/ffmpeg/encoder/wmv1/encoder.go
new file mode 100644
index 0000000..cab9f49
--- /dev/null
+++ b/internal/ffmpeg/encoder/wmv1/encoder.go
@@ -0,0 +1,21 @@
+package wmv1
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "wmv1"}
+ }
+
+ return encoder.NewEncoder("wmv1", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "wmv1"
+ formats := []string{"wmv"}
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/wmv2/encoder.go b/internal/ffmpeg/encoder/wmv2/encoder.go
new file mode 100644
index 0000000..092ea88
--- /dev/null
+++ b/internal/ffmpeg/encoder/wmv2/encoder.go
@@ -0,0 +1,21 @@
+package wmv2
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "wmv2"}
+ }
+
+ return encoder.NewEncoder("wmv2", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "wmv2"
+ formats := []string{"wmv"}
+ fileType := encoder.FileType(encoder.Video)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/encoder/xbm/encoder.go b/internal/ffmpeg/encoder/xbm/encoder.go
new file mode 100644
index 0000000..bc2e612
--- /dev/null
+++ b/internal/ffmpeg/encoder/xbm/encoder.go
@@ -0,0 +1,21 @@
+package xbm
+
+import (
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+func NewEncoder() encoder.EncoderContract {
+ parameters := map[string]encoder.ParameterContract{}
+ getParams := func(parameters map[string]encoder.ParameterContract) []string {
+ return []string{"-c:v", "xbm"}
+ }
+
+ return encoder.NewEncoder("xbm", parameters, getParams)
+}
+
+func NewData() encoder.EncoderDataContract {
+ title := "xbm"
+ formats := []string{"xbm"}
+ fileType := encoder.FileType(encoder.Image)
+ return encoder.NewData(title, formats, fileType, NewEncoder)
+}
diff --git a/internal/ffmpeg/ffmpeg.go b/internal/ffmpeg/ffmpeg.go
new file mode 100644
index 0000000..e4046d1
--- /dev/null
+++ b/internal/ffmpeg/ffmpeg.go
@@ -0,0 +1,139 @@
+package ffmpeg
+
+import (
+ "bufio"
+ "errors"
+ "fyne.io/fyne/v2/lang"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils"
+ "io"
+ "os/exec"
+ "regexp"
+ "strings"
+)
+
+type ProgressContract interface {
+ GetProtocole() string
+ Run(stdOut io.ReadCloser, stdErr io.ReadCloser) error
+}
+
+type FFmpegContract interface {
+ GetPath() string
+ GetVersion() (string, error)
+ GetEncoders(scanner func(scanner *bufio.Reader)) error
+ RunConvert(setting ConvertSetting, progress ProgressContract, beforeWait func(cmd *exec.Cmd), afterWait func(cmd *exec.Cmd)) error
+}
+
+type ffmpeg struct {
+ path string
+}
+
+func newFFmpeg(path string) (FFmpegContract, error) {
+ if path == "" {
+ return nil, errors.New(lang.L("errorFFmpeg"))
+ }
+
+ isCheck, err := checkFFmpegPath(path)
+ if err != nil {
+ return nil, err
+ }
+ if isCheck == false {
+ return nil, errors.New(lang.L("errorFFmpeg"))
+ }
+
+ return &ffmpeg{
+ path: path,
+ }, nil
+}
+
+func (f *ffmpeg) GetPath() string {
+ return f.path
+}
+
+func (f *ffmpeg) GetVersion() (string, error) {
+ cmd := exec.Command(f.path, "-version")
+ utils.PrepareBackgroundCommand(cmd)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ return "", err
+ }
+ text := regexp.MustCompile("\r?\n").Split(strings.TrimSpace(string(out)), -1)
+ return text[0], nil
+}
+
+func (f *ffmpeg) RunConvert(setting ConvertSetting, progress ProgressContract, beforeWait func(cmd *exec.Cmd), afterWait func(cmd *exec.Cmd)) error {
+ overwriteOutputFiles := "-n"
+ if setting.OverwriteOutputFiles == true {
+ overwriteOutputFiles = "-y"
+ }
+ args := []string{overwriteOutputFiles, "-i", setting.FileInput.Path}
+ args = append(args, setting.Encoder.GetParams()...)
+ args = append(args, "-progress", progress.GetProtocole(), setting.FileOut.Path)
+ cmd := exec.Command(f.path, args...)
+ utils.PrepareBackgroundCommand(cmd)
+
+ stdOut, err := cmd.StdoutPipe()
+ if err != nil {
+ return err
+ }
+ stdErr, err := cmd.StderrPipe()
+ if err != nil {
+ return err
+ }
+
+ err = cmd.Start()
+ if err != nil {
+ return err
+ }
+
+ if beforeWait != nil {
+ beforeWait(cmd)
+ }
+
+ errProgress := progress.Run(stdOut, stdErr)
+
+ err = cmd.Wait()
+ if afterWait != nil {
+ afterWait(cmd)
+ }
+ if errProgress != nil {
+ return errProgress
+ }
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (f *ffmpeg) GetEncoders(scanner func(scanner *bufio.Reader)) error {
+ cmd := exec.Command(f.path, "-encoders")
+ utils.PrepareBackgroundCommand(cmd)
+
+ stdOut, err := cmd.StdoutPipe()
+ if err != nil {
+ return err
+ }
+
+ err = cmd.Start()
+ if err != nil {
+ return err
+ }
+
+ scannerErr := bufio.NewReader(stdOut)
+ scanner(scannerErr)
+
+ return cmd.Wait()
+}
+
+func checkFFmpegPath(path string) (bool, error) {
+ cmd := exec.Command(path, "-version")
+ utils.PrepareBackgroundCommand(cmd)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ return false, err
+ }
+ if strings.Contains(strings.TrimSpace(string(out)), "ffmpeg") == false {
+ return false, nil
+ }
+ return true, nil
+}
diff --git a/internal/ffmpeg/ffplay.go b/internal/ffmpeg/ffplay.go
new file mode 100644
index 0000000..bb6454d
--- /dev/null
+++ b/internal/ffmpeg/ffplay.go
@@ -0,0 +1,73 @@
+package ffmpeg
+
+import (
+ "errors"
+ "fyne.io/fyne/v2/lang"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils"
+ "os/exec"
+ "regexp"
+ "strings"
+)
+
+type FFplayContract interface {
+ GetPath() string
+ GetVersion() (string, error)
+ Play(file *File) error
+}
+
+type ffplay struct {
+ path string
+}
+
+func newFFplay(path string) (FFplayContract, error) {
+ if path == "" {
+ return nil, errors.New(lang.L("errorFFplay"))
+ }
+
+ isCheck, err := checkFFplayPath(path)
+ if err != nil {
+ return nil, err
+ }
+ if isCheck == false {
+ return nil, errors.New(lang.L("errorFFplay"))
+ }
+
+ return &ffplay{
+ path: path,
+ }, nil
+}
+
+func (f *ffplay) GetPath() string {
+ return f.path
+}
+
+func (f *ffplay) GetVersion() (string, error) {
+ cmd := exec.Command(f.path, "-version")
+ utils.PrepareBackgroundCommand(cmd)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ return "", err
+ }
+ text := regexp.MustCompile("\r?\n").Split(strings.TrimSpace(string(out)), -1)
+ return text[0], nil
+}
+
+func (f *ffplay) Play(file *File) error {
+ args := []string{file.Path}
+ cmd := exec.Command(f.GetPath(), args...)
+
+ return cmd.Run()
+}
+
+func checkFFplayPath(path string) (bool, error) {
+ cmd := exec.Command(path, "-version")
+ utils.PrepareBackgroundCommand(cmd)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ return false, err
+ }
+ if strings.Contains(strings.TrimSpace(string(out)), "ffplay") == false {
+ return false, nil
+ }
+ return true, nil
+}
diff --git a/internal/ffmpeg/ffprobe.go b/internal/ffmpeg/ffprobe.go
new file mode 100644
index 0000000..e56299d
--- /dev/null
+++ b/internal/ffmpeg/ffprobe.go
@@ -0,0 +1,124 @@
+package ffmpeg
+
+import (
+ "errors"
+ "fyne.io/fyne/v2/lang"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils"
+ "os/exec"
+ "regexp"
+ "strconv"
+ "strings"
+ "unicode"
+)
+
+type FFprobeContract interface {
+ GetPath() string
+ GetVersion() (string, error)
+ GetTotalDuration(file *File) (float64, error)
+}
+
+type ffprobe struct {
+ path string
+}
+
+func newFFprobe(path string) (FFprobeContract, error) {
+ if path == "" {
+ return nil, errors.New(lang.L("errorFFprobe"))
+ }
+
+ isCheck, err := checkFFprobePath(path)
+ if err != nil {
+ return nil, err
+ }
+ if isCheck == false {
+ return nil, errors.New(lang.L("errorFFprobe"))
+ }
+
+ return &ffprobe{
+ path: path,
+ }, nil
+}
+
+func (f *ffprobe) GetPath() string {
+ return f.path
+}
+
+func (f *ffprobe) GetVersion() (string, error) {
+ cmd := exec.Command(f.path, "-version")
+ utils.PrepareBackgroundCommand(cmd)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ return "", err
+ }
+ text := regexp.MustCompile("\r?\n").Split(strings.TrimSpace(string(out)), -1)
+ return text[0], nil
+}
+
+func (f *ffprobe) GetTotalDuration(file *File) (duration float64, err error) {
+ args := []string{"-v", "error", "-select_streams", "v:0", "-count_packets", "-show_entries", "stream=nb_read_packets", "-of", "csv=p=0", file.Path}
+ cmd := exec.Command(f.path, args...)
+ utils.PrepareBackgroundCommand(cmd)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ errString := strings.TrimSpace(string(out))
+ if len(errString) > 1 {
+ return 0, errors.New(errString)
+ }
+ return 0, err
+ }
+ frames := strings.TrimSpace(string(out))
+ if len(frames) == 0 {
+ return f.getAlternativeTotalDuration(file)
+ }
+
+ duration, err = strconv.ParseFloat(frames, 64)
+ if err != nil {
+ // fix .mts duration
+ return strconv.ParseFloat(getFirstDigits(frames), 64)
+ }
+ return duration, err
+}
+
+func (f *ffprobe) getAlternativeTotalDuration(file *File) (duration float64, err error) {
+ args := []string{"-v", "error", "-select_streams", "a:0", "-count_packets", "-show_entries", "stream=nb_read_packets", "-of", "csv=p=0", file.Path}
+ cmd := exec.Command(f.path, args...)
+ utils.PrepareBackgroundCommand(cmd)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ errString := strings.TrimSpace(string(out))
+ if len(errString) > 1 {
+ return 0, errors.New(errString)
+ }
+ return 0, err
+ }
+ frames := strings.TrimSpace(string(out))
+ if len(frames) == 0 {
+ return 0, errors.New("error getting number of frames")
+ }
+ return strconv.ParseFloat(frames, 64)
+}
+
+func checkFFprobePath(path string) (bool, error) {
+ cmd := exec.Command(path, "-version")
+ utils.PrepareBackgroundCommand(cmd)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ return false, err
+ }
+ if strings.Contains(strings.TrimSpace(string(out)), "ffprobe") == false {
+ return false, nil
+ }
+ return true, nil
+}
+
+func getFirstDigits(s string) string {
+ result := ""
+ for _, r := range s {
+ if unicode.IsDigit(r) {
+ result += string(r)
+ } else {
+ break
+ }
+ }
+ return result
+}
diff --git a/internal/ffmpeg/utilities.go b/internal/ffmpeg/utilities.go
new file mode 100644
index 0000000..06dae49
--- /dev/null
+++ b/internal/ffmpeg/utilities.go
@@ -0,0 +1,221 @@
+package ffmpeg
+
+import (
+ "errors"
+ "fyne.io/fyne/v2/lang"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/setting"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+)
+
+type File struct {
+ Path string
+ Name string
+ Ext string
+}
+
+type ConvertSetting struct {
+ FileInput File
+ FileOut File
+ OverwriteOutputFiles bool
+ Encoder encoder.EncoderContract
+}
+
+type UtilitiesContract interface {
+ UtilityCheck() bool
+
+ GetFFmpeg() (FFmpegContract, error)
+ GetFFmpegVersion() string
+ GetFFmpegPath() string
+ ChangeFFmpeg(path string) error
+
+ GetFFprobe() (FFprobeContract, error)
+ GetFFprobeVersion() string
+ GetFFprobePath() string
+ ChangeFFprobe(path string) error
+
+ GetFFplay() (FFplayContract, error)
+ GetFFplayVersion() string
+ GetFFplayPath() string
+ ChangeFFplay(path string) error
+}
+
+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) UtilityCheck() bool {
+ var err error
+
+ _, err = u.GetFFmpeg()
+ if err != nil {
+ return false
+ }
+
+ _, err = u.GetFFprobe()
+ if err != nil {
+ return false
+ }
+
+ _, err = u.GetFFplay()
+ if err != nil {
+ return false
+ }
+
+ return true
+}
+
+func (u *utilities) GetFFmpeg() (FFmpegContract, error) {
+ if u.ffmpeg == nil {
+ createFFmpeg, err := newFFmpeg(u.setting.GetFFmpegPath())
+ if err != nil {
+ return nil, err
+ }
+ u.ffmpeg = createFFmpeg
+ }
+
+ return u.ffmpeg, nil
+}
+
+func (u *utilities) GetFFmpegVersion() string {
+ ffmpegService, err := u.GetFFmpeg()
+ if err != nil {
+ return lang.L("errorFFmpegVersion")
+ }
+
+ version, err := ffmpegService.GetVersion()
+ if err != nil {
+ return lang.L("errorFFmpegVersion")
+ }
+ return version
+}
+
+func (u *utilities) GetFFmpegPath() string {
+ ffmpegService, err := u.GetFFmpeg()
+ if err != nil {
+ return ""
+ }
+ return ffmpegService.GetPath()
+}
+
+func (u *utilities) ChangeFFmpeg(path string) error {
+ if path == "" {
+ return errors.New(lang.L("errorFFmpeg"))
+ }
+
+ createFFmpeg, err := newFFmpeg(path)
+ if err != nil {
+ return err
+ }
+
+ u.ffmpeg = createFFmpeg
+ u.setting.SetFFmpegPath(path)
+
+ return nil
+}
+
+func (u *utilities) GetFFprobe() (FFprobeContract, error) {
+ if u.ffprobe == nil {
+ createFFprobe, err := newFFprobe(u.setting.GetFFprobePath())
+ if err != nil {
+ return nil, err
+ }
+ u.ffprobe = createFFprobe
+ }
+
+ return u.ffprobe, nil
+}
+
+func (u *utilities) GetFFprobeVersion() string {
+ ffprobeService, err := u.GetFFprobe()
+ if err != nil {
+ return lang.L("errorFFprobeVersion")
+ }
+
+ ffprobeVersion, err := ffprobeService.GetVersion()
+ if err != nil {
+ return lang.L("errorFFprobeVersion")
+ }
+ return ffprobeVersion
+}
+
+func (u *utilities) GetFFprobePath() string {
+ ffprobeService, err := u.GetFFprobe()
+ if err != nil {
+ return ""
+ }
+ return ffprobeService.GetPath()
+}
+
+func (u *utilities) ChangeFFprobe(path string) error {
+ if path == "" {
+ return errors.New(lang.L("errorFFprobe"))
+ }
+
+ createFFprobe, err := newFFprobe(path)
+ if err != nil {
+ return err
+ }
+
+ u.ffprobe = createFFprobe
+ u.setting.SetFFprobePath(path)
+
+ return nil
+}
+
+func (u *utilities) GetFFplay() (FFplayContract, error) {
+ if u.ffplay == nil {
+ createFFplay, err := newFFplay(u.setting.GetFFplayPath())
+ if err != nil {
+ return nil, err
+ }
+ u.ffplay = createFFplay
+ }
+
+ return u.ffplay, nil
+}
+
+func (u *utilities) GetFFplayVersion() string {
+ ffplayService, err := u.GetFFplay()
+ if err != nil {
+ return lang.L("errorFFplayVersion")
+ }
+
+ ffplayVersion, err := ffplayService.GetVersion()
+ if err != nil {
+ return lang.L("errorFFplayVersion")
+ }
+ return ffplayVersion
+}
+
+func (u *utilities) GetFFplayPath() string {
+ ffplayService, err := u.GetFFplay()
+ if err != nil {
+ return ""
+ }
+ return ffplayService.GetPath()
+}
+
+func (u *utilities) ChangeFFplay(path string) error {
+ if path == "" {
+ return errors.New(lang.L("errorFFplay"))
+ }
+
+ createFFplay, err := newFFplay(path)
+ if err != nil {
+ return err
+ }
+
+ u.ffplay = createFFplay
+ u.setting.SetFFplayPath(path)
+
+ return nil
+}
diff --git a/internal/gui/menu/main.go b/internal/gui/menu/main.go
new file mode 100644
index 0000000..6afe023
--- /dev/null
+++ b/internal/gui/menu/main.go
@@ -0,0 +1,29 @@
+package menu
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/lang"
+)
+
+func MainMenuSettings(
+ actionMainSettings func(),
+ actionFFPathSelection func(),
+) *fyne.Menu {
+ quit := fyne.NewMenuItem(lang.L("exit"), nil)
+ quit.IsQuit = true
+
+ settingsSelection := fyne.NewMenuItem(lang.L("settings"), actionMainSettings)
+ ffPathSelection := fyne.NewMenuItem(lang.L("changeFFPath"), actionFFPathSelection)
+
+ return fyne.NewMenu(lang.L("settings"), settingsSelection, ffPathSelection, quit)
+}
+
+func MainMenuHelp(
+ actionAbout func(),
+ actionHelpFFplay func(),
+) *fyne.Menu {
+ about := fyne.NewMenuItem(lang.L("about"), actionAbout)
+ helpFFplay := fyne.NewMenuItem(lang.L("helpFFplay"), actionHelpFFplay)
+
+ return fyne.NewMenu(lang.L("help"), helpFFplay, about)
+}
diff --git a/menu/view.go b/internal/gui/view/about.go
similarity index 63%
rename from menu/view.go
rename to internal/gui/view/about.go
index 324b012..a92fe73 100644
--- a/menu/view.go
+++ b/internal/gui/view/about.go
@@ -1,316 +1,97 @@
-package menu
+package view
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
- "fyne.io/fyne/v2/theme"
+ "fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/widget"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "github.com/nicksnyder/go-i18n/v2/i18n"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/resources"
"golang.org/x/image/colornames"
"net/url"
)
-type ViewContract interface {
- About(ffmpegVersion string, ffprobeVersion string, ffplayVersion string)
- Gratitude()
- HelpFFplay()
-}
-
-type View struct {
- app kernel.AppContract
-}
-
-func NewView(app kernel.AppContract) *View {
- return &View{
- app: app,
- }
-}
-
-func (v View) Gratitude() {
- view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "gratitude",
- }))
- view.Resize(fyne.Size{Width: 500, Height: 400})
- view.SetFixedSize(true)
-
- image := canvas.NewImageFromFile("icon.png")
- image.SetMinSize(fyne.Size{Width: 100, Height: 100})
- image.FillMode = canvas.ImageFillContain
-
- gratitude := canvas.NewText(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "gratitude",
- }), colornames.Darkgreen)
- gratitude.TextStyle = fyne.TextStyle{Bold: true}
- gratitude.TextSize = 20
-
- view.SetContent(
- container.NewScroll(container.NewVBox(
- container.NewBorder(nil, nil, container.NewVBox(image), nil, container.NewVBox(
- gratitude,
- widget.NewLabel(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "gratitudeText",
- })),
- widget.NewLabel("Екатерина"),
- widget.NewLabel("Евгений"),
- ),
- ))),
- )
-
- view.CenterOnScreen()
- view.Show()
-}
-
-func (v View) About(ffmpegVersion string, ffprobeVersion string, ffplayVersion string) {
- view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "about",
- }))
- view.Resize(fyne.Size{Width: 793, Height: 550})
- view.SetFixedSize(true)
-
+func About(appVersion string, ffmpegVersion string, ffprobeVersion string, ffplayVersion string) fyne.CanvasObject {
programmName := canvas.NewText(" GUI for FFmpeg", colornames.Darkgreen)
programmName.TextStyle = fyne.TextStyle{Bold: true}
programmName.TextSize = 20
- programmLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "programmLink",
- }), &url.URL{
- Scheme: "https",
- Host: "gui-for-ffmpeg.projects.kor-elf.net",
- Path: "/",
- })
-
- licenseLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "licenseLink",
- }), &url.URL{
- Scheme: "https",
- Host: "git.kor-elf.net",
- Path: "kor-elf/gui-for-ffmpeg/src/branch/main/LICENSE",
- })
-
- licenseLinkOther := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "licenseLinkOther",
- }), &url.URL{
- Scheme: "https",
- Host: "git.kor-elf.net",
- Path: "kor-elf/gui-for-ffmpeg/src/branch/main/LICENSE-3RD-PARTY.txt",
- })
-
- programmVersion := widget.NewRichTextFromMarkdown(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "programmVersion",
- TemplateData: map[string]string{
- "Version": v.app.GetAppFyne().Metadata().Version,
+ programmLink := widget.NewHyperlink(
+ lang.L("programmLink"),
+ &url.URL{
+ Scheme: "https",
+ Host: "gui-for-ffmpeg.projects.kor-elf.net",
+ Path: "/",
},
- }))
+ )
+
+ licenseLink := widget.NewHyperlink(
+ lang.L("licenseLink"),
+ &url.URL{
+ Scheme: "https",
+ Host: "git.kor-elf.net",
+ Path: "kor-elf/gui-for-ffmpeg/src/branch/main/LICENSE",
+ },
+ )
+
+ licenseLinkOther := widget.NewHyperlink(
+ lang.L("licenseLinkOther"),
+ &url.URL{
+ Scheme: "https",
+ Host: "git.kor-elf.net",
+ Path: "kor-elf/gui-for-ffmpeg/src/branch/main/LICENSE-3RD-PARTY.txt",
+ },
+ )
+
+ programmVersion := widget.NewRichTextFromMarkdown(
+ lang.L(
+ "programmVersion",
+ map[string]any{"Version": appVersion},
+ ),
+ )
aboutText := widget.NewRichText(
&widget.TextSegment{
- Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "aboutText",
- }),
+ Text: lang.L("aboutText"),
},
)
- image := canvas.NewImageFromFile("icon.png")
+ image := canvas.NewImageFromResource(resources.IconAppLogoResource())
image.SetMinSize(fyne.Size{Width: 100, Height: 100})
image.FillMode = canvas.ImageFillContain
- ffmpegTrademark := widget.NewRichTextFromMarkdown(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "ffmpegTrademark",
- }))
- ffmpegLGPL := widget.NewRichTextFromMarkdown(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "ffmpegLGPL",
- }))
+ ffmpegTrademark := widget.NewRichTextFromMarkdown(lang.L("ffmpegTrademark"))
+ ffmpegLGPL := widget.NewRichTextFromMarkdown(lang.L("ffmpegLGPL"))
- view.SetContent(
- container.NewScroll(container.NewVBox(
- container.NewBorder(nil, nil, container.NewVBox(image), nil, container.NewVBox(
- programmName,
- programmVersion,
- aboutText,
- ffmpegTrademark,
- ffmpegLGPL,
- v.getCopyright(),
- container.NewHBox(programmLink, licenseLink),
- container.NewHBox(licenseLinkOther),
- )),
- v.getAboutFfmpeg(ffmpegVersion),
- v.getAboutFfprobe(ffprobeVersion),
- v.getAboutFfplay(ffplayVersion),
- widget.NewCard(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "AlsoUsedProgram",
- }), "", v.getOther()),
+ return container.NewScroll(container.NewVBox(
+ container.NewBorder(nil, nil, container.NewVBox(image), nil, container.NewVBox(
+ programmName,
+ programmVersion,
+ aboutText,
+ ffmpegTrademark,
+ ffmpegLGPL,
+ widget.NewRichTextFromMarkdown("Copyright (c) 2024 **[Leonid Nikitin (kor-elf)](https://git.kor-elf.net/kor-elf/)**."),
+ container.NewHBox(programmLink, licenseLink),
+ container.NewHBox(licenseLinkOther),
)),
- )
- view.CenterOnScreen()
- view.Show()
+ aboutFFmpeg(ffmpegVersion),
+ aboutFFprobe(ffprobeVersion),
+ aboutFFplay(ffplayVersion),
+ widget.NewCard(lang.L("AlsoUsedProgram"), "", license3RDParty()),
+ ))
}
-func (v View) HelpFFplay() {
- view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplay",
- }))
- view.Resize(fyne.Size{Width: 800, Height: 550})
- view.SetFixedSize(true)
-
- data := [][]string{
- []string{
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayKeys",
- }),
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayDescription",
- }),
- },
- []string{
- "Q, ESC",
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayQuit",
- }),
- },
- []string{
- "F, " + v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayDoubleClickLeftMouseButton",
- }),
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayToggleFullScreen",
- }),
- },
- []string{
- "P, " +
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayKeySpace",
- }),
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayPause",
- }),
- },
- []string{
- "M",
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayToggleMute",
- }),
- },
- []string{
- "9, /",
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayDecreaseVolume",
- }),
- },
- []string{
- "0, *",
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayIncreaseVolume",
- }),
- },
- []string{
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayKeyLeft",
- }),
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplaySeekBackward10Seconds",
- }),
- },
- []string{
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayKeyRight",
- }),
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplaySeekForward10Seconds",
- }),
- },
- []string{
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayKeyDown",
- }),
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplaySeekBackward1Minute",
- }),
- },
- []string{
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayKeyUp",
- }),
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplaySeekBForward1Minute",
- }),
- },
- []string{
- "Page Down",
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplaySeekBackward10Minutes",
- }),
- },
- []string{
- "Page Up",
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplaySeekBForward10Minutes",
- }),
- },
- []string{
- "S, " + v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayKeyHoldS",
- }),
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayActivateFrameStepMode",
- }),
- },
- []string{
- "W",
- v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "helpFFplayCycleVideoFiltersOrShowModes",
- }),
- },
- }
-
- list := widget.NewTable(
- func() (int, int) {
- return len(data), len(data[0])
- },
- func() fyne.CanvasObject {
- return widget.NewLabel("")
- },
- func(i widget.TableCellID, o fyne.CanvasObject) {
- if i.Row == 0 {
- o.(*widget.Label).TextStyle.Bold = true
- o.(*widget.Label).SizeName = theme.SizeNameSubHeadingText
- }
- if i.Col == 0 {
- o.(*widget.Label).TextStyle.Bold = true
- }
- o.(*widget.Label).SetText(data[i.Row][i.Col])
- })
- list.SetRowHeight(0, 40)
- list.SetColumnWidth(0, 200)
- list.SetColumnWidth(1, 585)
- list.SetRowHeight(2, 55)
- view.SetContent(
- container.NewScroll(list),
- )
- view.CenterOnScreen()
- view.Show()
-}
-
-func (v View) getCopyright() *widget.RichText {
- return widget.NewRichTextFromMarkdown("Copyright (c) 2024 **[Leonid Nikitin (kor-elf)](https://git.kor-elf.net/kor-elf/)**.")
-}
-
-func (v View) getAboutFfmpeg(version string) *fyne.Container {
+func aboutFFmpeg(version string) *fyne.Container {
programmName := canvas.NewText(" FFmpeg", colornames.Darkgreen)
programmName.TextStyle = fyne.TextStyle{Bold: true}
programmName.TextSize = 20
- programmLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "programmLink",
- }), &url.URL{
+ programmLink := widget.NewHyperlink(lang.L("programmLink"), &url.URL{
Scheme: "https",
Host: "ffmpeg.org",
Path: "",
})
- licenseLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "licenseLink",
- }), &url.URL{
+ licenseLink := widget.NewHyperlink(lang.L("licenseLink"), &url.URL{
Scheme: "https",
Host: "ffmpeg.org",
Path: "legal.html",
@@ -319,28 +100,24 @@ func (v View) getAboutFfmpeg(version string) *fyne.Container {
return container.NewVBox(
programmName,
widget.NewLabel(version),
- widget.NewRichTextFromMarkdown("**FFmpeg** is a trademark of **[Fabrice Bellard](http://bellard.org/)**, originator of the **[FFmpeg](https://ffmpeg.org/about.html)** project."),
- widget.NewRichTextFromMarkdown("This software uses libraries from the **FFmpeg** project under the **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**."),
+ widget.NewRichTextFromMarkdown("**FFmpeg** is a trademark of **[Fabrice Bellard](https://bellard.org/)**, originator of the **[FFmpeg](https://ffmpeg.org/about.html)** project."),
+ widget.NewRichTextFromMarkdown("This software uses libraries from the **FFmpeg** project under the **[LGPLv2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**."),
container.NewHBox(programmLink, licenseLink),
)
}
-func (v View) getAboutFfprobe(version string) *fyne.Container {
+func aboutFFprobe(version string) *fyne.Container {
programmName := canvas.NewText(" FFprobe", colornames.Darkgreen)
programmName.TextStyle = fyne.TextStyle{Bold: true}
programmName.TextSize = 20
- programmLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "programmLink",
- }), &url.URL{
+ programmLink := widget.NewHyperlink(lang.L("programmLink"), &url.URL{
Scheme: "https",
Host: "ffmpeg.org",
Path: "ffprobe.html",
})
- licenseLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "licenseLink",
- }), &url.URL{
+ licenseLink := widget.NewHyperlink(lang.L("licenseLink"), &url.URL{
Scheme: "https",
Host: "ffmpeg.org",
Path: "legal.html",
@@ -349,28 +126,24 @@ func (v View) getAboutFfprobe(version string) *fyne.Container {
return container.NewVBox(
programmName,
widget.NewLabel(version),
- widget.NewRichTextFromMarkdown("**FFmpeg** is a trademark of **[Fabrice Bellard](http://bellard.org/)**, originator of the **[FFmpeg](https://ffmpeg.org/about.html)** project."),
- widget.NewRichTextFromMarkdown("This software uses libraries from the **FFmpeg** project under the **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**."),
+ widget.NewRichTextFromMarkdown("**FFmpeg** is a trademark of **[Fabrice Bellard](https://bellard.org/)**, originator of the **[FFmpeg](https://ffmpeg.org/about.html)** project."),
+ widget.NewRichTextFromMarkdown("This software uses libraries from the **FFmpeg** project under the **[LGPLv2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**."),
container.NewHBox(programmLink, licenseLink),
)
}
-func (v View) getAboutFfplay(version string) *fyne.Container {
+func aboutFFplay(version string) *fyne.Container {
programmName := canvas.NewText(" FFplay", colornames.Darkgreen)
programmName.TextStyle = fyne.TextStyle{Bold: true}
programmName.TextSize = 20
- programmLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "programmLink",
- }), &url.URL{
+ programmLink := widget.NewHyperlink(lang.L("programmLink"), &url.URL{
Scheme: "https",
Host: "ffmpeg.org",
Path: "ffplay.html",
})
- licenseLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "licenseLink",
- }), &url.URL{
+ licenseLink := widget.NewHyperlink(lang.L("licenseLink"), &url.URL{
Scheme: "https",
Host: "ffmpeg.org",
Path: "legal.html",
@@ -379,13 +152,13 @@ func (v View) getAboutFfplay(version string) *fyne.Container {
return container.NewVBox(
programmName,
widget.NewLabel(version),
- widget.NewRichTextFromMarkdown("**FFmpeg** is a trademark of **[Fabrice Bellard](http://bellard.org/)**, originator of the **[FFmpeg](https://ffmpeg.org/about.html)** project."),
- widget.NewRichTextFromMarkdown("This software uses libraries from the **FFmpeg** project under the **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**."),
+ widget.NewRichTextFromMarkdown("**FFmpeg** is a trademark of **[Fabrice Bellard](https://bellard.org/)**, originator of the **[FFmpeg](https://ffmpeg.org/about.html)** project."),
+ widget.NewRichTextFromMarkdown("This software uses libraries from the **FFmpeg** project under the **[LGPLv2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**."),
container.NewHBox(programmLink, licenseLink),
)
}
-func (v View) getOther() *fyne.Container {
+func license3RDParty() *fyne.Container {
return container.NewVBox(
canvas.NewLine(colornames.Darkgreen),
@@ -751,19 +524,6 @@ func (v View) getOther() *fyne.Container {
widget.NewLabel("Copyright (c) 2019 Yusuke Inuzuka"),
canvas.NewLine(colornames.Darkgreen),
- container.NewHBox(widget.NewHyperlink("go.etcd.io/bbolt", &url.URL{
- Scheme: "https",
- Host: "pkg.go.dev",
- Path: "go.etcd.io/bbolt",
- })),
- container.NewHBox(widget.NewHyperlink("MIT License", &url.URL{
- Scheme: "https",
- Host: "github.com",
- Path: "etcd-io/bbolt/blob/main/LICENSE",
- })),
- widget.NewLabel("Copyright (c) 2013 Ben Johnson"),
- canvas.NewLine(colornames.Darkgreen),
-
container.NewHBox(widget.NewHyperlink("golang.org/x/image", &url.URL{
Scheme: "https",
Host: "pkg.go.dev",
diff --git a/internal/gui/view/configuring_ffmpeg_utilities.go b/internal/gui/view/configuring_ffmpeg_utilities.go
new file mode 100644
index 0000000..11d8d80
--- /dev/null
+++ b/internal/gui/view/configuring_ffmpeg_utilities.go
@@ -0,0 +1,129 @@
+package view
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/canvas"
+ "fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/lang"
+ "fyne.io/fyne/v2/storage"
+ "fyne.io/fyne/v2/widget"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/window"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils"
+ "image/color"
+ "net/url"
+ "path/filepath"
+)
+
+func ConfiguringFFmpegUtilities(
+ window window.WindowContract,
+ currentPathFFmpeg string,
+ currentPathFFprobe string,
+ currentPathFFplay string,
+ save func(ffmpegPath string, ffprobePath string, ffplayPath string) error,
+ cancel func(),
+ donwloadFFmpeg fyne.CanvasObject,
+) fyne.CanvasObject {
+ errorMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
+ errorMessage.TextSize = 16
+ errorMessage.TextStyle = fyne.TextStyle{Bold: true}
+
+ link := widget.NewHyperlink("https://ffmpeg.org/download.html", &url.URL{
+ Scheme: "https",
+ Host: "ffmpeg.org",
+ Path: "download.html",
+ })
+
+ ffmpegPath, buttonFFmpeg, buttonFFmpegMessage := configuringFFmpegUtilitiesButtonSelectFile(window, currentPathFFmpeg)
+ ffprobePath, buttonFFprobe, buttonFFprobeMessage := configuringFFmpegUtilitiesButtonSelectFile(window, currentPathFFprobe)
+ ffplayPath, buttonFFplay, buttonFFplayMessage := configuringFFmpegUtilitiesButtonSelectFile(window, currentPathFFplay)
+
+ form := &widget.Form{
+ Items: []*widget.FormItem{
+ {
+ Text: lang.L("titleDownloadLink"),
+ Widget: link,
+ },
+ {
+ Text: lang.L("pathToFfmpeg"),
+ Widget: buttonFFmpeg,
+ },
+ {
+ Widget: container.NewHScroll(buttonFFmpegMessage),
+ },
+ {
+ Text: lang.L("pathToFfprobe"),
+ Widget: buttonFFprobe,
+ },
+ {
+ Widget: container.NewHScroll(buttonFFprobeMessage),
+ },
+ {
+ Text: lang.L("pathToFfplay"),
+ Widget: buttonFFplay,
+ },
+ {
+ Widget: container.NewHScroll(buttonFFplayMessage),
+ },
+ {
+ Widget: container.NewHScroll(errorMessage),
+ },
+ },
+ SubmitText: lang.L("save"),
+ OnSubmit: func() {
+ err := save(*ffmpegPath, *ffprobePath, *ffplayPath)
+ if err != nil {
+ errorMessage.Text = err.Error()
+ }
+ },
+ }
+ if cancel != nil {
+ form.OnCancel = cancel
+ form.CancelText = lang.L("cancel")
+ }
+
+ selectFFPathTitle := lang.L("selectFFPathTitle")
+
+ return widget.NewCard(selectFFPathTitle, "", container.NewVBox(
+ form,
+ donwloadFFmpeg,
+ ))
+}
+
+func configuringFFmpegUtilitiesButtonSelectFile(window window.WindowContract, path string) (filePath *string, button *widget.Button, buttonMessage *canvas.Text) {
+ filePath = &path
+
+ buttonMessage = canvas.NewText(path, color.RGBA{R: 49, G: 127, B: 114, A: 255})
+ buttonMessage.TextSize = 16
+ buttonMessage.TextStyle = fyne.TextStyle{Bold: true}
+
+ buttonTitle := lang.L("choose")
+
+ var locationURI fyne.ListableURI
+ if len(path) > 0 {
+ listableURI := storage.NewFileURI(filepath.Dir(path))
+ locationURI, _ = storage.ListerForURI(listableURI)
+ }
+
+ button = widget.NewButton(buttonTitle, func() {
+ window.NewFileOpen(func(r fyne.URIReadCloser, err error) {
+ if err != nil {
+ buttonMessage.Text = err.Error()
+ utils.SetStringErrorStyle(buttonMessage)
+ return
+ }
+ if r == nil {
+ return
+ }
+
+ path = r.URI().Path()
+
+ buttonMessage.Text = r.URI().Path()
+ utils.SetStringSuccessStyle(buttonMessage)
+
+ listableURI := storage.NewFileURI(filepath.Dir(r.URI().Path()))
+ locationURI, _ = storage.ListerForURI(listableURI)
+ }, locationURI)
+ })
+
+ return filePath, button, buttonMessage
+}
diff --git a/internal/gui/view/convertor.go b/internal/gui/view/convertor.go
new file mode 100644
index 0000000..cac1bc2
--- /dev/null
+++ b/internal/gui/view/convertor.go
@@ -0,0 +1,414 @@
+package view
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/canvas"
+ "fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/lang"
+ "fyne.io/fyne/v2/storage"
+ "fyne.io/fyne/v2/widget"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/convertor/encoder"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg"
+ encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view/convertor/encoders"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/window"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils"
+ "image/color"
+ "os"
+ "path/filepath"
+)
+
+type ConvertSetting struct {
+ DirectoryForSave string
+ OverwriteOutputFiles bool
+ Format string
+ Encoder encoder2.EncoderContract
+}
+
+func Convertor(
+ window window.WindowContract,
+ addFileForConversion func(file ffmpeg.File),
+ directoryForSavingPath string,
+ directoryForSaving func(path string),
+ formats encoder.ConvertorFormatsContract,
+ addToConversion func(convertSetting ConvertSetting) error,
+) fyne.CanvasObject {
+ conversionMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
+ conversionMessage.TextSize = 16
+ conversionMessage.TextStyle = fyne.TextStyle{Bold: true}
+
+ form := newFormConvertor(
+ window,
+ addFileForConversion,
+ directoryForSavingPath,
+ directoryForSaving,
+ formats,
+ addToConversion,
+ conversionMessage,
+ )
+
+ converterVideoFilesTitle := lang.L("converterVideoFilesTitle")
+ return widget.NewCard(converterVideoFilesTitle, "", container.NewVScroll(form.getForm()))
+}
+
+type formConvertor struct {
+ form *widget.Form
+ items []*widget.FormItem
+ conversionMessage *canvas.Text
+
+ window window.WindowContract
+ addFileForConversion func(file ffmpeg.File)
+ directoryForSaving func(path string)
+}
+
+func newFormConvertor(
+ window window.WindowContract,
+ addFileForConversion func(file ffmpeg.File),
+ directoryForSavingPath string,
+ directoryForSaving func(path string),
+ formats encoder.ConvertorFormatsContract,
+ addToConversion func(convertSetting ConvertSetting) error,
+ conversionMessage *canvas.Text,
+) *formConvertor {
+ f := widget.NewForm()
+ f.SubmitText = lang.L("converterVideoFilesSubmitTitle")
+
+ formConvertor := &formConvertor{
+ form: f,
+ window: window,
+ addFileForConversion: addFileForConversion,
+ directoryForSaving: directoryForSaving,
+ conversionMessage: conversionMessage,
+ }
+
+ fileForConversion := formConvertor.newFileForConversion()
+ directoryForSavingButton := formConvertor.newDirectoryForSaving(directoryForSavingPath)
+ isOverwriteOutputFiles := false
+ checkboxOverwriteOutputFiles := widget.NewCheck(lang.L("checkboxOverwriteOutputFilesTitle"), func(b bool) {
+ isOverwriteOutputFiles = b
+ })
+ checkboxOverwriteOutputFiles.SetChecked(isOverwriteOutputFiles)
+ selectEncoder := formConvertor.newSelectEncoder(formats)
+
+ items := []*widget.FormItem{
+ {
+ Text: lang.L("fileForConversionTitle"),
+ Widget: fileForConversion.button,
+ },
+ {
+ Widget: container.NewHScroll(fileForConversion.message),
+ },
+
+ {
+ Text: lang.L("buttonForSelectedDirTitle"),
+ Widget: directoryForSavingButton.button,
+ },
+ {
+ Widget: container.NewHScroll(directoryForSavingButton.message),
+ },
+
+ {
+ Widget: checkboxOverwriteOutputFiles,
+ },
+ {
+ Widget: selectEncoder.SelectFileType,
+ },
+ {
+ Text: lang.L("selectFormat"),
+ Widget: selectEncoder.SelectFormat,
+ },
+ {
+ Text: lang.L("selectEncoder"),
+ Widget: selectEncoder.SelectEncoder,
+ },
+ }
+ formConvertor.form.Items = items
+ formConvertor.items = items
+ formConvertor.changeEncoder(selectEncoder.Encoder)
+ selectEncoder.ChangeEncoder = formConvertor.changeEncoder
+
+ formConvertor.form.OnSubmit = func() {
+ formConvertor.conversionMessage.Text = ""
+ if len(directoryForSavingButton.path) == 0 {
+ formConvertor.conversionMessage.Text = lang.L("errorSelectedFolderSave")
+ return
+ }
+
+ if len(selectEncoder.SelectFormat.Selected) == 0 {
+ formConvertor.conversionMessage.Text = lang.L("errorSelectedFormat")
+ return
+ }
+
+ if selectEncoder.Encoder == nil {
+ formConvertor.conversionMessage.Text = lang.L("errorSelectedEncoder")
+ return
+ }
+
+ fileForConversion.button.Disable()
+ directoryForSavingButton.button.Disable()
+ formConvertor.form.Disable()
+
+ fyne.Do(func() {
+ err := addToConversion(ConvertSetting{
+ DirectoryForSave: directoryForSavingButton.path,
+ OverwriteOutputFiles: isOverwriteOutputFiles,
+ Format: selectEncoder.SelectFormat.Selected,
+ Encoder: selectEncoder.Encoder,
+ })
+ if err != nil {
+ formConvertor.conversionMessage.Text = err.Error()
+ }
+ fileForConversion.button.Enable()
+ directoryForSavingButton.button.Enable()
+ formConvertor.form.Enable()
+ })
+ }
+
+ return formConvertor
+}
+
+func (f *formConvertor) getForm() fyne.CanvasObject {
+ return container.NewVBox(
+ f.form,
+ container.NewHScroll(f.conversionMessage),
+ )
+}
+
+type fileForConversion struct {
+ button *widget.Button
+ message *canvas.Text
+ file *ffmpeg.File
+}
+
+func (f *formConvertor) newFileForConversion() *fileForConversion {
+ message := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
+ fileForConversion := &fileForConversion{
+ message: message,
+ }
+
+ buttonTitle := lang.L("choose") + "\n" +
+ lang.L("or") + "\n" +
+ lang.L("dragAndDropFiles")
+
+ var locationURI fyne.ListableURI
+
+ fileForConversion.button = widget.NewButton(buttonTitle, func() {
+ f.window.NewFileOpen(func(r fyne.URIReadCloser, err error) {
+ fyne.Do(func() {
+ fileForConversion.message.Text = ""
+ fileForConversion.message.Refresh()
+ })
+
+ if err != nil {
+ fyne.Do(func() {
+ fileForConversion.message.Text = err.Error()
+ fileForConversion.message.Refresh()
+ })
+ return
+ }
+ if r == nil {
+ return
+ }
+
+ f.addFileForConversion(ffmpeg.File{
+ Path: r.URI().Path(),
+ Name: r.URI().Name(),
+ Ext: r.URI().Extension(),
+ })
+
+ listableURI := storage.NewFileURI(filepath.Dir(r.URI().Path()))
+ locationURI, _ = storage.ListerForURI(listableURI)
+ }, locationURI)
+ })
+
+ f.window.SetOnDropped(func(position fyne.Position, uris []fyne.URI) {
+ if len(uris) == 0 {
+ return
+ }
+
+ isError := false
+ for _, uri := range uris {
+ info, err := os.Stat(uri.Path())
+ if err != nil {
+ isError = true
+ continue
+ }
+ if info.IsDir() {
+ isError = true
+ continue
+ }
+
+ f.addFileForConversion(ffmpeg.File{
+ Path: uri.Path(),
+ Name: uri.Name(),
+ Ext: uri.Extension(),
+ })
+
+ listableURI := storage.NewFileURI(filepath.Dir(uri.Path()))
+ locationURI, _ = storage.ListerForURI(listableURI)
+ }
+
+ if isError {
+ fileForConversion.message.Text = lang.L("errorDragAndDropFile")
+ utils.SetStringErrorStyle(fileForConversion.message)
+ } else {
+ fyne.Do(func() {
+ fileForConversion.message.Text = ""
+ fileForConversion.message.Refresh()
+ })
+ }
+ })
+
+ return fileForConversion
+}
+
+type directoryForSaving struct {
+ button *widget.Button
+ message *canvas.Text
+ path string
+}
+
+func (f *formConvertor) newDirectoryForSaving(directoryForSavingPath string) *directoryForSaving {
+ directoryForSaving := &directoryForSaving{
+ path: "",
+ }
+
+ directoryForSaving.message = canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
+ directoryForSaving.message.TextSize = 16
+ directoryForSaving.message.TextStyle = fyne.TextStyle{Bold: true}
+
+ buttonTitle := lang.L("choose")
+
+ locationURI, err := utils.PathToListableURI(directoryForSavingPath)
+ if err == nil {
+ directoryForSaving.path = locationURI.Path()
+ directoryForSaving.message.Text = locationURI.Path()
+ utils.SetStringSuccessStyle(directoryForSaving.message)
+ }
+
+ directoryForSaving.button = widget.NewButton(buttonTitle, func() {
+ f.window.NewFolderOpen(func(r fyne.ListableURI, err error) {
+ if err != nil {
+ directoryForSaving.message.Text = err.Error()
+ utils.SetStringErrorStyle(directoryForSaving.message)
+ return
+ }
+ if r == nil {
+ return
+ }
+
+ directoryForSaving.path = r.Path()
+
+ directoryForSaving.message.Text = r.Path()
+ utils.SetStringSuccessStyle(directoryForSaving.message)
+ locationURI, err = storage.ListerForURI(r)
+
+ if err == nil {
+ f.directoryForSaving(locationURI.Path())
+ }
+
+ }, locationURI)
+ })
+
+ return directoryForSaving
+}
+
+type selectEncoder struct {
+ SelectFileType *widget.RadioGroup
+ SelectFormat *widget.Select
+ SelectEncoder *widget.Select
+ Encoder encoder2.EncoderContract
+
+ ChangeEncoder func(encoder encoder2.EncoderContract)
+}
+
+func (f *formConvertor) newSelectEncoder(formats encoder.ConvertorFormatsContract) *selectEncoder {
+ selectEncoder := &selectEncoder{}
+
+ encoderMap := map[int]encoder2.EncoderDataContract{}
+ selectEncoder.SelectEncoder = widget.NewSelect([]string{}, func(s string) {
+ if encoderMap[selectEncoder.SelectEncoder.SelectedIndex()] == nil {
+ return
+ }
+ selectEncoderData := encoderMap[selectEncoder.SelectEncoder.SelectedIndex()]
+ selectEncoder.Encoder = selectEncoderData.NewEncoder()
+ if selectEncoder.ChangeEncoder != nil {
+ selectEncoder.ChangeEncoder(selectEncoder.Encoder)
+ }
+ })
+
+ formatSelected := ""
+ selectEncoder.SelectFormat = widget.NewSelect([]string{}, func(s string) {
+ if formatSelected == s {
+ return
+ }
+ formatSelected = s
+ format, err := formats.GetFormat(s)
+ if err != nil {
+ return
+ }
+ var encoderOptions []string
+ encoderMap = map[int]encoder2.EncoderDataContract{}
+ for _, e := range format.GetEncoders() {
+ encoderMap[len(encoderMap)] = e
+ encoderOptions = append(encoderOptions, lang.L("encoder_"+e.GetTitle()))
+ }
+ selectEncoder.SelectEncoder.SetOptions(encoderOptions)
+ selectEncoder.SelectEncoder.SetSelectedIndex(0)
+ })
+
+ var fileTypeOptions []string
+ for _, fileType := range encoder2.GetListFileType() {
+ fileTypeOptions = append(fileTypeOptions, fileType.Name())
+ }
+
+ encoderGroupVideo := lang.L("encoderGroupVideo")
+ encoderGroupAudio := lang.L("encoderGroupAudio")
+ encoderGroupImage := lang.L("encoderGroupImage")
+ encoderGroup := map[string]string{
+ encoderGroupVideo: "video",
+ encoderGroupAudio: "audio",
+ encoderGroupImage: "image",
+ }
+ selectEncoder.SelectFileType = widget.NewRadioGroup([]string{encoderGroupVideo, encoderGroupAudio, encoderGroupImage}, func(s string) {
+ groupCode := encoderGroup[s]
+
+ var formatOptions []string
+ for _, f := range formats.GetFormats() {
+ if groupCode != f.GetFileType().Name() {
+ continue
+ }
+ formatOptions = append(formatOptions, f.GetTitle())
+ }
+ selectEncoder.SelectFormat.SetOptions(formatOptions)
+ if groupCode == encoder2.FileType(encoder2.Video).Name() {
+ selectEncoder.SelectFormat.SetSelected("mp4")
+ } else {
+ selectEncoder.SelectFormat.SetSelectedIndex(0)
+ }
+ })
+ selectEncoder.SelectFileType.Horizontal = true
+ selectEncoder.SelectFileType.Required = true
+ selectEncoder.SelectFileType.SetSelected(encoderGroupVideo)
+
+ return selectEncoder
+}
+
+func (f *formConvertor) changeEncoder(encoder encoder2.EncoderContract) {
+ var items []*widget.FormItem
+
+ if encoders.Views[encoder.GetName()] != nil {
+ items = encoders.Views[encoder.GetName()](encoder)
+ }
+
+ f.changeItems(items)
+}
+
+func (f *formConvertor) changeItems(items []*widget.FormItem) {
+ fyne.Do(func() {
+ f.form.Items = f.items
+ f.form.Refresh()
+ f.form.Items = append(f.form.Items, items...)
+ f.form.Refresh()
+ })
+}
diff --git a/internal/gui/view/convertor/encoders/encoders.go b/internal/gui/view/convertor/encoders/encoders.go
new file mode 100644
index 0000000..ddbf806
--- /dev/null
+++ b/internal/gui/view/convertor/encoders/encoders.go
@@ -0,0 +1,15 @@
+package encoders
+
+import (
+ "fyne.io/fyne/v2/widget"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view/convertor/encoders/h264_nvenc"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view/convertor/encoders/libx264"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view/convertor/encoders/libx265"
+)
+
+var Views = map[string]func(encoder encoder.EncoderContract) []*widget.FormItem{
+ "libx264": libx264.View,
+ "h264_nvenc": h264_nvenc.View,
+ "libx265": libx265.View,
+}
diff --git a/convertor/view/form_items/h264_nvenc/view.go b/internal/gui/view/convertor/encoders/h264_nvenc/view.go
similarity index 60%
rename from convertor/view/form_items/h264_nvenc/view.go
rename to internal/gui/view/convertor/encoders/h264_nvenc/view.go
index 81b3c15..a506a12 100644
--- a/convertor/view/form_items/h264_nvenc/view.go
+++ b/internal/gui/view/convertor/encoders/h264_nvenc/view.go
@@ -2,22 +2,21 @@ package h264_nvenc
import (
"fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/widget"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/h264_nvenc"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "github.com/nicksnyder/go-i18n/v2/i18n"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/h264_nvenc"
)
-func View(encoder encoder.EncoderContract, app kernel.AppContract) []*widget.FormItem {
+func View(encoder encoder.EncoderContract) []*widget.FormItem {
items := []*widget.FormItem{}
- items = append(items, presetParameter(encoder, app)...)
+ items = append(items, presetParameter(encoder)...)
return items
}
-func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []*widget.FormItem {
+func presetParameter(encoder encoder.EncoderContract) []*widget.FormItem {
parameter, err := encoder.GetParameter("preset")
if err != nil {
return nil
@@ -45,7 +44,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
elementSelect.SetSelected(presetDefault)
elementSelect.Hide()
- checkboxTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "parameterCheckbox"})
+ checkboxTitle := lang.L("parameterCheckbox")
elementCheckbox := widget.NewCheck(checkboxTitle, func(b bool) {
if b == true {
parameter.SetEnable()
@@ -58,7 +57,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
return []*widget.FormItem{
{
- Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "formPreset"}),
+ Text: lang.L("formPreset"),
Widget: container.NewVBox(elementCheckbox, elementSelect),
},
}
diff --git a/convertor/view/form_items/libx264/view.go b/internal/gui/view/convertor/encoders/libx264/view.go
similarity index 57%
rename from convertor/view/form_items/libx264/view.go
rename to internal/gui/view/convertor/encoders/libx264/view.go
index f552c66..8457d94 100644
--- a/convertor/view/form_items/libx264/view.go
+++ b/internal/gui/view/convertor/encoders/libx264/view.go
@@ -2,22 +2,21 @@ package libx264
import (
"fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/widget"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libx264"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "github.com/nicksnyder/go-i18n/v2/i18n"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libx264"
)
-func View(encoder encoder.EncoderContract, app kernel.AppContract) []*widget.FormItem {
+func View(encoder encoder.EncoderContract) []*widget.FormItem {
items := []*widget.FormItem{}
- items = append(items, presetParameter(encoder, app)...)
+ items = append(items, presetParameter(encoder)...)
return items
}
-func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []*widget.FormItem {
+func presetParameter(encoder encoder.EncoderContract) []*widget.FormItem {
parameter, err := encoder.GetParameter("preset")
if err != nil {
return nil
@@ -28,7 +27,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
presetDefault := ""
for _, name := range libx264.Presets {
- title := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "preset_" + name})
+ title := lang.L("preset_" + name)
presetsForSelect = append(presetsForSelect, title)
presets[title] = name
if name == parameter.Get() {
@@ -45,7 +44,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
elementSelect.SetSelected(presetDefault)
elementSelect.Hide()
- checkboxTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "parameterCheckbox"})
+ checkboxTitle := lang.L("parameterCheckbox")
elementCheckbox := widget.NewCheck(checkboxTitle, func(b bool) {
if b == true {
parameter.SetEnable()
@@ -58,7 +57,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
return []*widget.FormItem{
{
- Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "formPreset"}),
+ Text: lang.L("formPreset"),
Widget: container.NewVBox(elementCheckbox, elementSelect),
},
}
diff --git a/convertor/view/form_items/libx265/view.go b/internal/gui/view/convertor/encoders/libx265/view.go
similarity index 57%
rename from convertor/view/form_items/libx265/view.go
rename to internal/gui/view/convertor/encoders/libx265/view.go
index 434defd..f0fccf0 100644
--- a/convertor/view/form_items/libx265/view.go
+++ b/internal/gui/view/convertor/encoders/libx265/view.go
@@ -2,22 +2,21 @@ package libx265
import (
"fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/widget"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libx265"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "github.com/nicksnyder/go-i18n/v2/i18n"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libx265"
)
-func View(encoder encoder.EncoderContract, app kernel.AppContract) []*widget.FormItem {
+func View(encoder encoder.EncoderContract) []*widget.FormItem {
items := []*widget.FormItem{}
- items = append(items, presetParameter(encoder, app)...)
+ items = append(items, presetParameter(encoder)...)
return items
}
-func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []*widget.FormItem {
+func presetParameter(encoder encoder.EncoderContract) []*widget.FormItem {
parameter, err := encoder.GetParameter("preset")
if err != nil {
return nil
@@ -28,7 +27,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
presetDefault := ""
for _, name := range libx265.Presets {
- title := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "preset_" + name})
+ title := lang.L("preset_" + name)
presetsForSelect = append(presetsForSelect, title)
presets[title] = name
if name == parameter.Get() {
@@ -45,7 +44,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
elementSelect.SetSelected(presetDefault)
elementSelect.Hide()
- checkboxTitle := app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "parameterCheckbox"})
+ checkboxTitle := lang.L("parameterCheckbox")
elementCheckbox := widget.NewCheck(checkboxTitle, func(b bool) {
if b == true {
parameter.SetEnable()
@@ -58,7 +57,7 @@ func presetParameter(encoder encoder.EncoderContract, app kernel.AppContract) []
return []*widget.FormItem{
{
- Text: app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "formPreset"}),
+ Text: lang.L("formPreset"),
Widget: container.NewVBox(elementCheckbox, elementSelect),
},
}
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/help_ffplay.go b/internal/gui/view/help_ffplay.go
new file mode 100644
index 0000000..07fbcd0
--- /dev/null
+++ b/internal/gui/view/help_ffplay.go
@@ -0,0 +1,98 @@
+package view
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/lang"
+ "fyne.io/fyne/v2/theme"
+ "fyne.io/fyne/v2/widget"
+)
+
+func HelpFFplay() fyne.CanvasObject {
+ data := [][]string{
+ {
+ lang.L("helpFFplayKeys"),
+ lang.L("helpFFplayDescription"),
+ },
+ {
+ "Q, ESC",
+ lang.L("helpFFplayQuit"),
+ },
+ {
+ "F, " + lang.L("helpFFplayDoubleClickLeftMouseButton"),
+ lang.L("helpFFplayToggleFullScreen"),
+ },
+ {
+ "P, " + lang.L("helpFFplayKeySpace"),
+ lang.L("helpFFplayPause"),
+ },
+ {
+ "M",
+ lang.L("helpFFplayToggleMute"),
+ },
+ {
+ "9, /",
+ lang.L("helpFFplayDecreaseVolume"),
+ },
+ {
+ "0, *",
+ lang.L("helpFFplayIncreaseVolume"),
+ },
+ {
+ lang.L("helpFFplayKeyLeft"),
+ lang.L("helpFFplaySeekBackward10Seconds"),
+ },
+ {
+ lang.L("helpFFplayKeyRight"),
+ lang.L("helpFFplaySeekForward10Seconds"),
+ },
+ {
+ lang.L("helpFFplayKeyDown"),
+ lang.L("helpFFplaySeekBackward1Minute"),
+ },
+ {
+ lang.L("helpFFplayKeyUp"),
+ lang.L("helpFFplaySeekBForward1Minute"),
+ },
+ {
+ "Page Down",
+ lang.L("helpFFplaySeekBackward10Minutes"),
+ },
+ {
+ "Page Up",
+ lang.L("helpFFplaySeekBForward10Minutes"),
+ },
+ {
+ "S, " + lang.L("helpFFplayKeyHoldS"),
+ lang.L("helpFFplayActivateFrameStepMode"),
+ },
+ {
+ "W",
+ lang.L("helpFFplayCycleVideoFiltersOrShowModes"),
+ },
+ }
+
+ list := widget.NewTable(
+ func() (int, int) {
+ return len(data), len(data[0])
+ },
+ func() fyne.CanvasObject {
+ return widget.NewLabel("")
+ },
+ func(i widget.TableCellID, o fyne.CanvasObject) {
+ if i.Row == 0 {
+ o.(*widget.Label).TextStyle.Bold = true
+ o.(*widget.Label).SizeName = theme.SizeNameSubHeadingText
+ }
+ if i.Col == 0 {
+ o.(*widget.Label).TextStyle.Bold = true
+ }
+ o.(*widget.Label).SetText(data[i.Row][i.Col])
+ })
+ list.SetRowHeight(0, 40)
+ list.SetColumnWidth(0, 200)
+ list.SetColumnWidth(1, 585)
+ list.SetRowHeight(2, 55)
+
+ return container.NewScroll(list)
+}
diff --git a/internal/gui/view/mainSettings.go b/internal/gui/view/mainSettings.go
new file mode 100644
index 0000000..b9e19e7
--- /dev/null
+++ b/internal/gui/view/mainSettings.go
@@ -0,0 +1,92 @@
+package view
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/canvas"
+ "fyne.io/fyne/v2/lang"
+ "fyne.io/fyne/v2/widget"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/setting"
+ "image/color"
+)
+
+type MainSettingForm struct {
+ Language setting.Lang
+ ThemeInfo setting.ThemeInfoContract
+}
+
+func MainSettings(
+ currentLang setting.Lang,
+ langList []setting.Lang,
+
+ themeInfo setting.ThemeInfoContract,
+ themeList map[string]setting.ThemeInfoContract,
+
+ save func(form *MainSettingForm) error,
+ cancel func(),
+) fyne.CanvasObject {
+
+ errorMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
+ errorMessage.TextSize = 16
+ errorMessage.TextStyle = fyne.TextStyle{Bold: true}
+
+ viewSettingForm := &MainSettingForm{
+ Language: currentLang,
+ ThemeInfo: themeInfo,
+ }
+
+ var languageItems []string
+ langByTitle := map[string]setting.Lang{}
+ for _, language := range langList {
+ languageItems = append(languageItems, language.Title)
+ langByTitle[language.Title] = language
+ }
+ selectLanguage := widget.NewSelect(languageItems, func(s string) {
+ if lang, ok := langByTitle[s]; ok {
+ viewSettingForm.Language = lang
+ }
+ })
+ selectLanguage.Selected = currentLang.Title
+
+ var themeItems []string
+ themeByTitle := map[string]setting.ThemeInfoContract{}
+ for _, themeInfo := range themeList {
+ themeItems = append(themeItems, themeInfo.GetTitle())
+ themeByTitle[themeInfo.GetTitle()] = themeInfo
+ }
+ selectTheme := widget.NewSelect(themeItems, func(s string) {
+ if themeInfo, ok := themeByTitle[s]; ok {
+ viewSettingForm.ThemeInfo = themeInfo
+ }
+ })
+ selectTheme.Selected = themeInfo.GetTitle()
+
+ form := &widget.Form{
+ Items: []*widget.FormItem{
+ {
+ Text: lang.L("menuSettingsLanguage"),
+ Widget: selectLanguage,
+ },
+ {
+ Text: lang.L("menuSettingsTheme"),
+ Widget: selectTheme,
+ },
+ {
+ Widget: errorMessage,
+ },
+ },
+ SubmitText: lang.L("save"),
+ OnSubmit: func() {
+ err := save(viewSettingForm)
+ if err != nil {
+ errorMessage.Text = err.Error()
+ }
+ },
+ }
+ if cancel != nil {
+ form.OnCancel = cancel
+ form.CancelText = lang.L("cancel")
+ }
+
+ messageHead := lang.L("settings")
+ return widget.NewCard(messageHead, "", form)
+}
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/layout.go b/internal/gui/window/layout.go
new file mode 100644
index 0000000..33e4b25
--- /dev/null
+++ b/internal/gui/window/layout.go
@@ -0,0 +1,172 @@
+package window
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/canvas"
+ "fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/lang"
+ "fyne.io/fyne/v2/theme"
+ "fyne.io/fyne/v2/widget"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/convertor"
+)
+
+type LayoutContract interface {
+ SetContent(content fyne.CanvasObject) fyne.CanvasObject
+ GetRContainer() RightMainContainerContract
+}
+
+type layout struct {
+ layoutContainer *fyne.Container
+ rContainer RightMainContainerContract
+}
+
+func NewLayout(progressBarService convertor.ProgressBarContract, itemsToConvert convertor.ItemsToConvertContract, queueLayout QueueLayoutContract) LayoutContract {
+ rContainer := newRightContainer(progressBarService.GetContainer(), itemsToConvert, queueLayout)
+ layoutContainer := container.NewAdaptiveGrid(2, widget.NewLabel(""), rContainer.GetCanvasObject())
+
+ return &layout{
+ layoutContainer: layoutContainer,
+ rContainer: rContainer,
+ }
+}
+
+func (l *layout) SetContent(content fyne.CanvasObject) fyne.CanvasObject {
+ l.layoutContainer.Objects[0] = content
+ return l.layoutContainer
+}
+
+func (l *layout) GetRContainer() RightMainContainerContract {
+ return l.rContainer
+}
+
+type RightMainContainerContract interface {
+ GetCanvasObject() fyne.CanvasObject
+ GetTabs() *container.AppTabs
+ SelectFileQueueTab()
+ SelectAddedFilesTab()
+}
+
+type rightMainContainer struct {
+ container fyne.CanvasObject
+ tabs *container.AppTabs
+ addedFilesTab *container.TabItem
+ fileQueueTab *container.TabItem
+}
+
+func newRightContainer(blockProgressbar *fyne.Container, itemsToConvert convertor.ItemsToConvertContract, queueLayout QueueLayoutContract) RightMainContainerContract {
+ addedFilesTab := container.NewTabItem(lang.L("addedFilesTitle"), addedFilesContainer(itemsToConvert))
+ fileQueueTab := container.NewTabItem(lang.L("fileQueueTitle"), fileQueueContainer(queueLayout))
+
+ tabs := container.NewAppTabs(
+ addedFilesTab,
+ fileQueueTab,
+ )
+
+ rightContainer := container.NewBorder(
+ container.NewVBox(
+ blockProgressbar,
+ widget.NewSeparator(),
+ ),
+ nil,
+ nil,
+ nil,
+ tabs,
+ )
+
+ return &rightMainContainer{
+ container: rightContainer,
+ tabs: tabs,
+ addedFilesTab: addedFilesTab,
+ fileQueueTab: fileQueueTab,
+ }
+}
+
+func (r *rightMainContainer) GetCanvasObject() fyne.CanvasObject {
+ return r.container
+}
+
+func (r *rightMainContainer) GetTabs() *container.AppTabs {
+ return r.tabs
+}
+
+func (r *rightMainContainer) SelectFileQueueTab() {
+ fyne.Do(func() {
+ r.tabs.Select(r.fileQueueTab)
+ })
+}
+
+func (r *rightMainContainer) SelectAddedFilesTab() {
+ fyne.Do(func() {
+ r.tabs.Select(r.addedFilesTab)
+ })
+}
+
+func addedFilesContainer(itemsToConvert convertor.ItemsToConvertContract) *fyne.Container {
+ line := canvas.NewLine(theme.Color(theme.ColorNameFocus))
+ line.StrokeWidth = 5
+ checkboxAutoRemove := widget.NewCheck(
+ lang.L("autoClearAfterAddingToQueue"),
+ func(checked bool) {
+ itemsToConvert.SetIsAutoRemove(checked)
+ },
+ )
+ checkboxAutoRemove.SetChecked(itemsToConvert.GetIsAutoRemove())
+
+ buttonClear := widget.NewButton(
+ lang.L("clearAll"),
+ func() {
+ itemsToConvert.Clear()
+ },
+ )
+ buttonClear.Importance = widget.DangerImportance
+ return container.NewBorder(
+ container.NewVBox(
+ container.NewPadded(),
+ container.NewBorder(nil, nil, nil, buttonClear, container.NewHScroll(checkboxAutoRemove)),
+ container.NewPadded(),
+ line,
+ ), nil, nil, nil,
+ container.NewVScroll(
+ container.NewBorder(
+ nil, nil, nil, container.NewPadded(),
+ container.NewVBox(
+ container.NewPadded(),
+ itemsToConvert.GetItemsContainer(),
+ ),
+ ),
+ ),
+ )
+}
+
+func fileQueueContainer(queueLayout QueueLayoutContract) *fyne.Container {
+ title := widget.NewLabel(lang.L("queue"))
+ title.TextStyle.Bold = true
+
+ line := canvas.NewLine(theme.Color(theme.ColorNameFocus))
+ line.StrokeWidth = 5
+
+ queueLayout.GetQueueStatistics().GetWaiting().SetTitle(lang.L("waitingQueue"))
+ queueLayout.GetQueueStatistics().GetInProgress().SetTitle(lang.L("inProgressQueue"))
+ queueLayout.GetQueueStatistics().GetCompleted().SetTitle(lang.L("completedQueue"))
+ queueLayout.GetQueueStatistics().GetError().SetTitle(lang.L("errorQueue"))
+ queueLayout.GetQueueStatistics().GetTotal().SetTitle(lang.L("total"))
+
+ return container.NewBorder(
+ container.NewVBox(
+ container.NewPadded(),
+ container.NewHBox(title, queueLayout.GetQueueStatistics().GetCompleted().GetCheckbox(), queueLayout.GetQueueStatistics().GetError().GetCheckbox()),
+ container.NewHBox(queueLayout.GetQueueStatistics().GetInProgress().GetCheckbox(), queueLayout.GetQueueStatistics().GetWaiting().GetCheckbox(), queueLayout.GetQueueStatistics().GetTotal().GetCheckbox()),
+ container.NewPadded(),
+ line,
+ ), nil, nil, nil,
+ container.NewVScroll(
+ container.NewBorder(
+ nil, nil, nil, container.NewPadded(),
+ container.NewVBox(
+ container.NewPadded(),
+ queueLayout.GetItemsContainer(),
+ ),
+ ),
+ ),
+ )
+}
diff --git a/internal/gui/window/main.go b/internal/gui/window/main.go
new file mode 100644
index 0000000..4fcb823
--- /dev/null
+++ b/internal/gui/window/main.go
@@ -0,0 +1,101 @@
+package window
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/dialog"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/convertor"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils"
+)
+
+type WindowContract interface {
+ SetContent(content fyne.CanvasObject)
+ SetMainMenu(menu *fyne.MainMenu)
+ Show()
+ InitLayout()
+ NewFileOpen(callback func(fyne.URIReadCloser, error), location fyne.ListableURI) *dialog.FileDialog
+ NewFolderOpen(callback func(fyne.ListableURI, error), location fyne.ListableURI) *dialog.FileDialog
+ SetOnDropped(callback func(position fyne.Position, uris []fyne.URI))
+ GetLayout() LayoutContract
+}
+
+type mainWindow struct {
+ fyneWindow fyne.Window
+ layout LayoutContract
+ itemsToConvert convertor.ItemsToConvertContract
+ progressBarService convertor.ProgressBarContract
+ queueLayout QueueLayoutContract
+}
+
+func NewMainWindow(
+ fyneWindow fyne.Window,
+ progressBarService convertor.ProgressBarContract,
+ itemsToConvert convertor.ItemsToConvertContract,
+ queueLayout QueueLayoutContract,
+) WindowContract {
+ fyneWindow.Resize(fyne.Size{Width: 1039, Height: 599})
+ fyneWindow.CenterOnScreen()
+
+ return &mainWindow{
+ fyneWindow: fyneWindow,
+ progressBarService: progressBarService,
+ itemsToConvert: itemsToConvert,
+ queueLayout: queueLayout,
+ }
+}
+
+func (w *mainWindow) SetMainMenu(menu *fyne.MainMenu) {
+ fyne.Do(func() {
+ w.fyneWindow.SetMainMenu(menu)
+ })
+}
+
+func (w *mainWindow) InitLayout() {
+ fyne.Do(func() {
+ w.layout = NewLayout(w.progressBarService, w.itemsToConvert, w.queueLayout)
+ })
+}
+
+func (w *mainWindow) GetLayout() LayoutContract {
+ return w.layout
+}
+
+func (w *mainWindow) NewFileOpen(callback func(fyne.URIReadCloser, error), location fyne.ListableURI) *dialog.FileDialog {
+ fileDialog := dialog.NewFileOpen(callback, w.fyneWindow)
+ utils.FileDialogResize(fileDialog, w.fyneWindow)
+ fileDialog.Show()
+ if location != nil {
+ fileDialog.SetLocation(location)
+ }
+ return fileDialog
+}
+
+func (w *mainWindow) NewFolderOpen(callback func(fyne.ListableURI, error), location fyne.ListableURI) *dialog.FileDialog {
+ fileDialog := dialog.NewFolderOpen(callback, w.fyneWindow)
+ utils.FileDialogResize(fileDialog, w.fyneWindow)
+ fileDialog.Show()
+ if location != nil {
+ fileDialog.SetLocation(location)
+ }
+ return fileDialog
+}
+
+func (w *mainWindow) SetContent(content fyne.CanvasObject) {
+ fyne.Do(func() {
+ if w.layout == nil {
+ w.fyneWindow.SetContent(content)
+ return
+ }
+
+ w.fyneWindow.SetContent(w.layout.SetContent(content))
+ })
+}
+
+func (w *mainWindow) Show() {
+ w.fyneWindow.Show()
+}
+
+func (w *mainWindow) SetOnDropped(callback func(position fyne.Position, uris []fyne.URI)) {
+ fyne.Do(func() {
+ w.fyneWindow.SetOnDropped(callback)
+ })
+}
diff --git a/internal/gui/window/queue.go b/internal/gui/window/queue.go
new file mode 100644
index 0000000..c801c1e
--- /dev/null
+++ b/internal/gui/window/queue.go
@@ -0,0 +1,459 @@
+package window
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/canvas"
+ "fyne.io/fyne/v2/container"
+ "fyne.io/fyne/v2/lang"
+ "fyne.io/fyne/v2/theme"
+ "fyne.io/fyne/v2/widget"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/convertor"
+ "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg"
+ "image/color"
+ "strconv"
+ "strings"
+)
+
+type QueueLayoutContract interface {
+ GetItemsContainer() *fyne.Container
+ GetQueueStatistics() QueueStatisticsAllContract
+
+ AddQueue(key int, queue *convertor.Queue)
+ ChangeQueue(key int, queue *convertor.Queue)
+ RemoveQueue(key int, status convertor.StatusContract)
+}
+
+type queueLayout struct {
+ itemsContainer *fyne.Container
+ queueAllStatistics QueueStatisticsAllContract
+ items map[int]queueLayoutItem
+ ffmpegService ffmpeg.UtilitiesContract
+}
+
+func NewQueueLayout(ffmpegService ffmpeg.UtilitiesContract) QueueLayoutContract {
+ items := map[int]queueLayoutItem{}
+
+ return &queueLayout{
+ itemsContainer: container.NewVBox(),
+ queueAllStatistics: newQueueAllStatistics(&items),
+ items: items,
+ ffmpegService: ffmpegService,
+ }
+}
+
+func (l *queueLayout) GetItemsContainer() *fyne.Container {
+ return l.itemsContainer
+}
+
+func (l *queueLayout) GetQueueStatistics() QueueStatisticsAllContract {
+ return l.queueAllStatistics
+}
+
+func (l *queueLayout) AddQueue(queueID int, queue *convertor.Queue) {
+
+ statusMessage := canvas.NewText(l.getStatusTitle(queue.Status), theme.Color(theme.ColorNamePrimary))
+ messageError := canvas.NewText("", theme.Color(theme.ColorNameError))
+ buttonPlay := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
+
+ })
+ buttonPlay.Hide()
+ blockMessageError := container.NewHScroll(messageError)
+ blockMessageError.Hide()
+
+ content := container.NewVBox(
+ container.NewHScroll(widget.NewLabel(queue.Setting.FileInput.Name)),
+ container.NewHBox(
+ buttonPlay,
+ statusMessage,
+ ),
+ blockMessageError,
+ container.NewPadded(),
+ canvas.NewLine(theme.Color(theme.ColorNameFocus)),
+ container.NewPadded(),
+ )
+
+ l.addQueueStatistics()
+ if l.GetQueueStatistics().IsChecked(queue.Status) == false {
+ content.Hide()
+ }
+
+ l.items[queueID] = queueLayoutItem{
+ CanvasObject: content,
+ StatusMessage: statusMessage,
+ BlockMessageError: blockMessageError,
+ MessageError: messageError,
+ buttonPlay: buttonPlay,
+ status: &queue.Status,
+ }
+ l.itemsContainer.Add(content)
+}
+
+func (l *queueLayout) ChangeQueue(queueID int, queue *convertor.Queue) {
+ if item, ok := l.items[queueID]; ok {
+ statusColor := l.getStatusColor(queue.Status)
+ fyne.Do(func() {
+ item.StatusMessage.Text = l.getStatusTitle(queue.Status)
+ item.StatusMessage.Color = statusColor
+ item.StatusMessage.Refresh()
+ })
+ if queue.Error != nil {
+ fyne.Do(func() {
+ item.MessageError.Text = queue.Error.Error()
+ item.MessageError.Color = statusColor
+ item.BlockMessageError.Show()
+ item.MessageError.Refresh()
+ })
+ }
+ if queue.Status == convertor.StatusType(convertor.Completed) {
+ item.buttonPlay.Show()
+ item.buttonPlay.OnTapped = func() {
+ item.buttonPlay.Disable()
+ go func() {
+ ffplay, err := l.ffmpegService.GetFFplay()
+ if err == nil {
+ _ = ffplay.Play(&queue.Setting.FileOut)
+ }
+ fyne.Do(func() {
+ item.buttonPlay.Enable()
+ })
+ }()
+ }
+ }
+ if l.GetQueueStatistics().IsChecked(queue.Status) == false && item.CanvasObject.Visible() == true {
+ item.CanvasObject.Hide()
+ }
+
+ if l.GetQueueStatistics().IsChecked(queue.Status) == true && item.CanvasObject.Visible() == false {
+ item.CanvasObject.Show()
+ }
+
+ l.changeQueueStatistics(queue.Status)
+ }
+}
+
+func (l *queueLayout) RemoveQueue(queueID int, status convertor.StatusContract) {
+ if item, ok := l.items[queueID]; ok {
+ l.itemsContainer.Remove(item.CanvasObject)
+ l.removeQueueStatistics(status)
+ l.items[queueID] = queueLayoutItem{}
+ }
+}
+
+func (l *queueLayout) addQueueStatistics() {
+ l.GetQueueStatistics().GetWaiting().Add()
+ l.GetQueueStatistics().GetTotal().Add()
+}
+
+func (l *queueLayout) changeQueueStatistics(status convertor.StatusContract) {
+ if status == convertor.StatusType(convertor.InProgress) {
+ l.GetQueueStatistics().GetWaiting().Remove()
+ l.GetQueueStatistics().GetInProgress().Add()
+ return
+ }
+
+ if status == convertor.StatusType(convertor.Completed) {
+ l.GetQueueStatistics().GetInProgress().Remove()
+ l.GetQueueStatistics().GetCompleted().Add()
+ return
+ }
+
+ if status == convertor.StatusType(convertor.Error) {
+ l.GetQueueStatistics().GetInProgress().Remove()
+ l.GetQueueStatistics().GetError().Add()
+ return
+ }
+}
+
+func (l *queueLayout) removeQueueStatistics(status convertor.StatusContract) {
+ l.GetQueueStatistics().GetTotal().Remove()
+
+ if status == convertor.StatusType(convertor.Completed) {
+ l.GetQueueStatistics().GetCompleted().Remove()
+ return
+ }
+
+ if status == convertor.StatusType(convertor.Error) {
+ l.GetQueueStatistics().GetError().Remove()
+ return
+ }
+
+ if status == convertor.StatusType(convertor.InProgress) {
+ l.GetQueueStatistics().GetInProgress().Remove()
+ return
+ }
+
+ if status == convertor.StatusType(convertor.Waiting) {
+ l.GetQueueStatistics().GetWaiting().Remove()
+ return
+ }
+}
+
+func (l *queueLayout) getStatusTitle(status convertor.StatusContract) string {
+ return lang.L(status.Name() + "Queue")
+}
+
+func (l *queueLayout) getStatusColor(status convertor.StatusContract) color.Color {
+ if status == convertor.StatusType(convertor.Error) {
+ return theme.Color(theme.ColorNameError)
+ }
+
+ if status == convertor.StatusType(convertor.Completed) {
+ return color.RGBA{R: 49, G: 127, B: 114, A: 255}
+ }
+
+ return theme.Color(theme.ColorNamePrimary)
+}
+
+type QueueStatisticsAllContract interface {
+ GetWaiting() QueueStatisticsContract
+ GetInProgress() QueueStatisticsContract
+ GetCompleted() QueueStatisticsContract
+ GetError() QueueStatisticsContract
+ GetTotal() QueueStatisticsContract
+
+ IsChecked(status convertor.StatusContract) bool
+}
+
+type queueAllStatistics struct {
+ waiting QueueStatisticsContract
+ inProgress QueueStatisticsContract
+ completed QueueStatisticsContract
+ error QueueStatisticsContract
+ total QueueStatisticsContract
+}
+
+func newQueueAllStatistics(queueItems *map[int]queueLayoutItem) QueueStatisticsAllContract {
+ checkboxWaiting := newQueueStatistics()
+ checkboxInProgress := newQueueStatistics()
+ checkboxCompleted := newQueueStatistics()
+ checkboxError := newQueueStatistics()
+ CheckboxTotal := newQueueStatistics()
+
+ queueAllStatistics := &queueAllStatistics{
+ waiting: checkboxWaiting,
+ inProgress: checkboxInProgress,
+ completed: checkboxCompleted,
+ error: checkboxError,
+ total: CheckboxTotal,
+ }
+
+ CheckboxTotal.GetCheckbox().OnChanged = func(b bool) {
+ if b == true {
+ queueAllStatistics.allCheckboxChecked()
+ } else {
+ queueAllStatistics.allUnCheckboxChecked()
+ }
+ queueAllStatistics.redrawingQueueItems(queueItems)
+ }
+
+ checkboxWaiting.GetCheckbox().OnChanged = func(b bool) {
+ if b == true {
+ queueAllStatistics.checkboxChecked()
+ } else {
+ queueAllStatistics.unCheckboxChecked()
+ }
+ queueAllStatistics.redrawingQueueItems(queueItems)
+ }
+
+ checkboxInProgress.GetCheckbox().OnChanged = func(b bool) {
+ if b == true {
+ queueAllStatistics.checkboxChecked()
+ } else {
+ queueAllStatistics.unCheckboxChecked()
+ }
+ queueAllStatistics.redrawingQueueItems(queueItems)
+ }
+
+ checkboxCompleted.GetCheckbox().OnChanged = func(b bool) {
+ if b == true {
+ queueAllStatistics.checkboxChecked()
+ } else {
+ queueAllStatistics.unCheckboxChecked()
+ }
+ queueAllStatistics.redrawingQueueItems(queueItems)
+ }
+
+ checkboxError.GetCheckbox().OnChanged = func(b bool) {
+ if b == true {
+ queueAllStatistics.checkboxChecked()
+ } else {
+ queueAllStatistics.unCheckboxChecked()
+ }
+ queueAllStatistics.redrawingQueueItems(queueItems)
+ }
+
+ return queueAllStatistics
+}
+
+func (s *queueAllStatistics) GetWaiting() QueueStatisticsContract {
+ return s.waiting
+}
+
+func (s *queueAllStatistics) GetInProgress() QueueStatisticsContract {
+ return s.inProgress
+}
+
+func (s *queueAllStatistics) GetCompleted() QueueStatisticsContract {
+ return s.completed
+}
+
+func (s *queueAllStatistics) GetError() QueueStatisticsContract {
+ return s.error
+}
+
+func (s *queueAllStatistics) GetTotal() QueueStatisticsContract {
+ return s.total
+}
+
+func (s *queueAllStatistics) IsChecked(status convertor.StatusContract) bool {
+ if status == convertor.StatusType(convertor.InProgress) {
+ return s.inProgress.GetCheckbox().Checked
+ }
+ if status == convertor.StatusType(convertor.Completed) {
+ return s.completed.GetCheckbox().Checked
+ }
+ if status == convertor.StatusType(convertor.Error) {
+ return s.error.GetCheckbox().Checked
+ }
+ if status == convertor.StatusType(convertor.Waiting) {
+ return s.waiting.GetCheckbox().Checked
+ }
+
+ return true
+}
+
+func (s *queueAllStatistics) redrawingQueueItems(queueItems *map[int]queueLayoutItem) {
+ for _, item := range *queueItems {
+ if s.IsChecked(*item.status) == true && item.CanvasObject.Visible() == false {
+ item.CanvasObject.Show()
+ continue
+ }
+ if s.IsChecked(*item.status) == false && item.CanvasObject.Visible() == true {
+ item.CanvasObject.Hide()
+ }
+ }
+}
+
+func (s *queueAllStatistics) checkboxChecked() {
+ if s.total.GetCheckbox().Checked == true {
+ return
+ }
+
+ if s.waiting.GetCheckbox().Checked == false {
+ return
+ }
+
+ if s.inProgress.GetCheckbox().Checked == false {
+ return
+ }
+
+ if s.completed.GetCheckbox().Checked == false {
+ return
+ }
+
+ if s.error.GetCheckbox().Checked == false {
+ return
+ }
+
+ s.total.GetCheckbox().Checked = true
+ s.total.GetCheckbox().Refresh()
+}
+
+func (s *queueAllStatistics) unCheckboxChecked() {
+ if s.total.GetCheckbox().Checked == false {
+ return
+ }
+
+ s.total.GetCheckbox().Checked = false
+ s.total.GetCheckbox().Refresh()
+}
+
+func (s *queueAllStatistics) allCheckboxChecked() {
+ s.waiting.GetCheckbox().Checked = true
+ s.waiting.GetCheckbox().Refresh()
+
+ s.inProgress.GetCheckbox().Checked = true
+ s.inProgress.GetCheckbox().Refresh()
+
+ s.completed.GetCheckbox().Checked = true
+ s.completed.GetCheckbox().Refresh()
+
+ s.error.GetCheckbox().Checked = true
+ s.error.GetCheckbox().Refresh()
+}
+
+func (s *queueAllStatistics) allUnCheckboxChecked() {
+ s.waiting.GetCheckbox().Checked = false
+ s.waiting.GetCheckbox().Refresh()
+
+ s.inProgress.GetCheckbox().Checked = false
+ s.inProgress.GetCheckbox().Refresh()
+
+ s.completed.GetCheckbox().Checked = false
+ s.completed.GetCheckbox().Refresh()
+
+ s.error.GetCheckbox().Checked = false
+ s.error.GetCheckbox().Refresh()
+}
+
+type QueueStatisticsContract interface {
+ SetTitle(title string)
+ GetCheckbox() *widget.Check
+ Add()
+ Remove()
+}
+
+type queueStatistics struct {
+ checkbox *widget.Check
+ title string
+ count int64
+}
+
+func newQueueStatistics() QueueStatisticsContract {
+ checkbox := widget.NewCheck(": 0", nil)
+ checkbox.Checked = true
+
+ return &queueStatistics{
+ checkbox: checkbox,
+ title: "",
+ count: 0,
+ }
+}
+
+func (s *queueStatistics) SetTitle(title string) {
+ s.title = strings.ToLower(title)
+ s.checkbox.Text = title + ": " + strconv.FormatInt(s.count, 10)
+}
+
+func (s *queueStatistics) GetCheckbox() *widget.Check {
+ return s.checkbox
+}
+
+func (s *queueStatistics) Add() {
+ s.count += 1
+ s.formatText()
+}
+
+func (s *queueStatistics) Remove() {
+ if s.count == 0 {
+ return
+ }
+ s.count -= 1
+ s.formatText()
+}
+
+func (s *queueStatistics) formatText() {
+ fyne.Do(func() {
+ s.checkbox.Text = s.title + ": " + strconv.FormatInt(s.count, 10)
+ s.checkbox.Refresh()
+ })
+}
+
+type queueLayoutItem struct {
+ CanvasObject fyne.CanvasObject
+ BlockMessageError *container.Scroll
+ StatusMessage *canvas.Text
+ MessageError *canvas.Text
+ buttonPlay *widget.Button
+ status *convertor.StatusContract
+}
diff --git a/internal/resources/icon.go b/internal/resources/icon.go
new file mode 100644
index 0000000..003278e
--- /dev/null
+++ b/internal/resources/icon.go
@@ -0,0 +1,13 @@
+package resources
+
+import (
+ _ "embed"
+ "fyne.io/fyne/v2"
+)
+
+//go:embed icons/logo.png
+var iconAppLogo []byte
+
+func IconAppLogoResource() *fyne.StaticResource {
+ return fyne.NewStaticResource("icon.png", iconAppLogo)
+}
diff --git a/internal/resources/icons/logo.png b/internal/resources/icons/logo.png
new file mode 100644
index 0000000..6eaf8f6
Binary files /dev/null and b/internal/resources/icons/logo.png differ
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/helper/helper.go b/internal/utils/dialog.go
similarity index 94%
rename from helper/helper.go
rename to internal/utils/dialog.go
index 682704c..992a68a 100644
--- a/helper/helper.go
+++ b/internal/utils/dialog.go
@@ -1,4 +1,4 @@
-package helper
+package utils
import (
"fyne.io/fyne/v2"
diff --git a/internal/utils/path.go b/internal/utils/path.go
new file mode 100644
index 0000000..4a35d20
--- /dev/null
+++ b/internal/utils/path.go
@@ -0,0 +1,19 @@
+package utils
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/storage"
+)
+
+func PathToListableURI(path string) (fyne.ListableURI, error) {
+ if len(path) > 0 {
+ path = "file://" + path
+ }
+
+ uri, err := storage.ParseURI(path)
+ if err != nil {
+ return nil, err
+ }
+
+ return storage.ListerForURI(uri)
+}
diff --git a/helper/path_separator.go b/internal/utils/path_separator.go
similarity index 85%
rename from helper/path_separator.go
rename to internal/utils/path_separator.go
index 905b935..9fa65cf 100644
--- a/helper/path_separator.go
+++ b/internal/utils/path_separator.go
@@ -1,7 +1,7 @@
//go:build !windows
// +build !windows
-package helper
+package utils
func PathSeparator() string {
return "/"
diff --git a/helper/path_separator_window.go b/internal/utils/path_separator_window.go
similarity index 84%
rename from helper/path_separator_window.go
rename to internal/utils/path_separator_window.go
index 433e550..2acaa53 100644
--- a/helper/path_separator_window.go
+++ b/internal/utils/path_separator_window.go
@@ -1,7 +1,7 @@
//go:build windows
// +build windows
-package helper
+package utils
func PathSeparator() string {
return "\\"
diff --git a/helper/prepare_background_command.go b/internal/utils/prepare_background_command.go
similarity index 88%
rename from helper/prepare_background_command.go
rename to internal/utils/prepare_background_command.go
index f8aab96..da5f9b4 100644
--- a/helper/prepare_background_command.go
+++ b/internal/utils/prepare_background_command.go
@@ -1,7 +1,7 @@
//go:build !windows
// +build !windows
-package helper
+package utils
import (
"os/exec"
diff --git a/helper/prepare_background_command_windows.go b/internal/utils/prepare_background_command_windows.go
similarity index 92%
rename from helper/prepare_background_command_windows.go
rename to internal/utils/prepare_background_command_windows.go
index 3e3ebbc..00af640 100644
--- a/helper/prepare_background_command_windows.go
+++ b/internal/utils/prepare_background_command_windows.go
@@ -1,7 +1,7 @@
//go:build windows
// +build windows
-package helper
+package utils
import (
"os/exec"
diff --git a/internal/utils/text.go b/internal/utils/text.go
new file mode 100644
index 0000000..20104dd
--- /dev/null
+++ b/internal/utils/text.go
@@ -0,0 +1,21 @@
+package utils
+
+import (
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/canvas"
+ "image/color"
+)
+
+func SetStringErrorStyle(text *canvas.Text) {
+ fyne.Do(func() {
+ text.Color = color.RGBA{R: 255, G: 0, B: 0, A: 255}
+ text.Refresh()
+ })
+}
+
+func SetStringSuccessStyle(text *canvas.Text) {
+ fyne.Do(func() {
+ text.Color = color.RGBA{R: 49, G: 127, B: 114, A: 255}
+ text.Refresh()
+ })
+}
diff --git a/kernel/app.go b/kernel/app.go
deleted file mode 100644
index 3babb14..0000000
--- a/kernel/app.go
+++ /dev/null
@@ -1,127 +0,0 @@
-package kernel
-
-import (
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/app"
- "time"
-)
-
-type AppContract interface {
- GetAppFyne() fyne.App
- GetWindow() WindowContract
- GetQueue() QueueListContract
- GetLocalizerService() LocalizerContract
- GetConvertorService() ConvertorContract
- GetFFplayService() FFplayContract
- AfterClosing()
- RunConvertor()
-}
-
-type App struct {
- AppFyne fyne.App
- Window WindowContract
- Queue QueueListContract
-
- localizerService LocalizerContract
- convertorService ConvertorContract
- blockProgressbarService BlockProgressbarContract
- ffplayService FFplayContract
-}
-
-func NewApp(
- metadata *fyne.AppMetadata,
- localizerService LocalizerContract,
- queue QueueListContract,
- ffplayService FFplayContract,
- convertorService ConvertorContract,
-) *App {
- app.SetMetadata(*metadata)
- a := app.New()
-
- statusesText := GetBlockProgressbarStatusesText(localizerService)
- blockProgressbarService := NewBlockProgressbar(statusesText, ffplayService)
- rightTabsService := NewRightTabs(localizerService)
- queueLayoutObject := NewQueueLayoutObject(queue, localizerService, ffplayService, rightTabsService, blockProgressbarService.GetContainer())
-
- return &App{
- AppFyne: a,
- Window: newWindow(a.NewWindow("GUI for FFmpeg"), NewLayout(queueLayoutObject, localizerService, rightTabsService)),
- Queue: queue,
-
- localizerService: localizerService,
- convertorService: convertorService,
- blockProgressbarService: blockProgressbarService,
- ffplayService: ffplayService,
- }
-}
-
-func (a App) GetAppFyne() fyne.App {
- return a.AppFyne
-}
-
-func (a App) GetQueue() QueueListContract {
- return a.Queue
-}
-
-func (a App) GetWindow() WindowContract {
- return a.Window
-}
-
-func (a App) GetLocalizerService() LocalizerContract {
- return a.localizerService
-}
-
-func (a App) GetConvertorService() ConvertorContract {
- return a.convertorService
-}
-
-func (a App) GetFFplayService() FFplayContract {
- return a.ffplayService
-}
-
-func (a App) AfterClosing() {
- for _, cmd := range a.convertorService.GetRunningProcesses() {
- _ = cmd.Process.Kill()
- }
-}
-
-func (a App) RunConvertor() {
- go func() {
- for {
- time.Sleep(time.Millisecond * 3000)
- queueId, queue := a.Queue.Next()
- if queue == nil {
- continue
- }
- queue.Status = StatusType(InProgress)
- a.Window.GetLayout().ChangeQueueStatus(queueId, queue)
- if a.blockProgressbarService.GetContainer().Hidden {
- a.blockProgressbarService.GetContainer().Show()
- }
-
- totalDuration, err := a.convertorService.GetTotalDuration(&queue.Setting.VideoFileInput)
- if err != nil {
- totalDuration = 0
- }
-
- progress := a.blockProgressbarService.GetProgressbar(
- totalDuration,
- queue.Setting.VideoFileInput.Path,
- a.localizerService,
- )
-
- err = a.convertorService.RunConvert(*queue.Setting, progress)
- if err != nil {
- queue.Status = StatusType(Error)
- queue.Error = err
- a.Window.GetLayout().ChangeQueueStatus(queueId, queue)
- a.blockProgressbarService.ProcessEndedWithError(err.Error())
-
- continue
- }
- queue.Status = StatusType(Completed)
- a.Window.GetLayout().ChangeQueueStatus(queueId, queue)
- a.blockProgressbarService.ProcessEndedWithSuccess(queue.Setting.VideoFileOut.Path)
- }
- }()
-}
diff --git a/kernel/convertor.go b/kernel/convertor.go
deleted file mode 100644
index 179cff3..0000000
--- a/kernel/convertor.go
+++ /dev/null
@@ -1,290 +0,0 @@
-package kernel
-
-import (
- "bufio"
- "errors"
- encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/helper"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel/encoder"
- "io"
- "os/exec"
- "regexp"
- "strconv"
- "strings"
- "unicode"
-)
-
-type File struct {
- Path string
- Name string
- Ext string
-}
-
-type ConvertSetting struct {
- VideoFileInput File
- VideoFileOut File
- OverwriteOutputFiles bool
- Encoder encoder2.EncoderContract
-}
-
-type ConvertorContract interface {
- RunConvert(setting ConvertSetting, progress ProgressContract) error
- GetTotalDuration(file *File) (float64, error)
- GetFFmpegVesrion() (string, error)
- GetFFprobeVersion() (string, error)
- GetFFplayVersion() (string, error)
- ChangeFFmpegPath(path string) (bool, error)
- ChangeFFprobePath(path string) (bool, error)
- ChangeFFplayPath(path string) (bool, error)
- GetRunningProcesses() map[int]*exec.Cmd
- GetSupportFormats() (encoder.ConvertorFormatsContract, error)
-}
-
-type ProgressContract interface {
- GetProtocole() string
- Run(stdOut io.ReadCloser, stdErr io.ReadCloser) error
-}
-
-type FFPathUtilities struct {
- FFmpeg string
- FFprobe string
- FFplay string
-}
-
-type runningProcesses struct {
- items map[int]*exec.Cmd
- numberOfStarts int
-}
-
-type Convertor struct {
- ffPathUtilities *FFPathUtilities
- runningProcesses runningProcesses
-}
-
-type ConvertData struct {
- totalDuration float64
-}
-
-func NewService(ffPathUtilities *FFPathUtilities) *Convertor {
- return &Convertor{
- ffPathUtilities: ffPathUtilities,
- runningProcesses: runningProcesses{items: map[int]*exec.Cmd{}, numberOfStarts: 0},
- }
-}
-
-func (s Convertor) RunConvert(setting ConvertSetting, progress ProgressContract) error {
- overwriteOutputFiles := "-n"
- if setting.OverwriteOutputFiles == true {
- overwriteOutputFiles = "-y"
- }
- args := []string{overwriteOutputFiles, "-i", setting.VideoFileInput.Path}
- args = append(args, setting.Encoder.GetParams()...)
- args = append(args, "-progress", progress.GetProtocole(), setting.VideoFileOut.Path)
- cmd := exec.Command(s.ffPathUtilities.FFmpeg, args...)
- helper.PrepareBackgroundCommand(cmd)
-
- stdOut, err := cmd.StdoutPipe()
- if err != nil {
- return err
- }
- stdErr, err := cmd.StderrPipe()
- if err != nil {
- return err
- }
-
- err = cmd.Start()
- if err != nil {
- return err
- }
- index := s.runningProcesses.numberOfStarts
- s.runningProcesses.numberOfStarts++
- s.runningProcesses.items[index] = cmd
-
- errProgress := progress.Run(stdOut, stdErr)
-
- err = cmd.Wait()
- delete(s.runningProcesses.items, index)
- if errProgress != nil {
- return errProgress
- }
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (s Convertor) GetTotalDuration(file *File) (duration float64, err error) {
- args := []string{"-v", "error", "-select_streams", "v:0", "-count_packets", "-show_entries", "stream=nb_read_packets", "-of", "csv=p=0", file.Path}
- cmd := exec.Command(s.ffPathUtilities.FFprobe, args...)
- helper.PrepareBackgroundCommand(cmd)
- out, err := cmd.CombinedOutput()
- if err != nil {
- errString := strings.TrimSpace(string(out))
- if len(errString) > 1 {
- return 0, errors.New(errString)
- }
- return 0, err
- }
- frames := strings.TrimSpace(string(out))
- if len(frames) == 0 {
- return s.getAlternativeTotalDuration(file)
- }
-
- duration, err = strconv.ParseFloat(frames, 64)
- if err != nil {
- // fix .mts duration
- return strconv.ParseFloat(getFirstDigits(frames), 64)
- }
- return duration, err
-}
-
-func (s Convertor) getAlternativeTotalDuration(file *File) (duration float64, err error) {
- args := []string{"-v", "error", "-select_streams", "a:0", "-count_packets", "-show_entries", "stream=nb_read_packets", "-of", "csv=p=0", file.Path}
- cmd := exec.Command(s.ffPathUtilities.FFprobe, args...)
- helper.PrepareBackgroundCommand(cmd)
- out, err := cmd.CombinedOutput()
- if err != nil {
- errString := strings.TrimSpace(string(out))
- if len(errString) > 1 {
- return 0, errors.New(errString)
- }
- return 0, err
- }
- frames := strings.TrimSpace(string(out))
- if len(frames) == 0 {
- return 0, errors.New("error getting number of frames")
- }
- return strconv.ParseFloat(frames, 64)
-}
-
-func (s Convertor) GetFFmpegVesrion() (string, error) {
- cmd := exec.Command(s.ffPathUtilities.FFmpeg, "-version")
- helper.PrepareBackgroundCommand(cmd)
- out, err := cmd.CombinedOutput()
- if err != nil {
- return "", err
- }
- text := regexp.MustCompile("\r?\n").Split(strings.TrimSpace(string(out)), -1)
- return text[0], nil
-}
-
-func (s Convertor) GetFFprobeVersion() (string, error) {
- cmd := exec.Command(s.ffPathUtilities.FFprobe, "-version")
- helper.PrepareBackgroundCommand(cmd)
- out, err := cmd.CombinedOutput()
- if err != nil {
- return "", err
- }
- text := regexp.MustCompile("\r?\n").Split(strings.TrimSpace(string(out)), -1)
- return text[0], nil
-}
-
-func (s Convertor) GetFFplayVersion() (string, error) {
- cmd := exec.Command(s.ffPathUtilities.FFplay, "-version")
- helper.PrepareBackgroundCommand(cmd)
- out, err := cmd.CombinedOutput()
- if err != nil {
- return "", err
- }
- text := regexp.MustCompile("\r?\n").Split(strings.TrimSpace(string(out)), -1)
- return text[0], nil
-}
-
-func (s Convertor) ChangeFFmpegPath(path string) (bool, error) {
- cmd := exec.Command(path, "-version")
- helper.PrepareBackgroundCommand(cmd)
- out, err := cmd.CombinedOutput()
- if err != nil {
- return false, err
- }
- if strings.Contains(strings.TrimSpace(string(out)), "ffmpeg") == false {
- return false, nil
- }
- s.ffPathUtilities.FFmpeg = path
- return true, nil
-}
-
-func (s Convertor) ChangeFFprobePath(path string) (bool, error) {
- cmd := exec.Command(path, "-version")
- helper.PrepareBackgroundCommand(cmd)
- out, err := cmd.CombinedOutput()
- if err != nil {
- return false, err
- }
- if strings.Contains(strings.TrimSpace(string(out)), "ffprobe") == false {
- return false, nil
- }
- s.ffPathUtilities.FFprobe = path
- return true, nil
-}
-
-func (s Convertor) ChangeFFplayPath(path string) (bool, error) {
- cmd := exec.Command(path, "-version")
- helper.PrepareBackgroundCommand(cmd)
- out, err := cmd.CombinedOutput()
- if err != nil {
- return false, err
- }
- if strings.Contains(strings.TrimSpace(string(out)), "ffplay") == false {
- return false, nil
- }
- s.ffPathUtilities.FFplay = path
- return true, nil
-}
-
-func (s Convertor) GetSupportFormats() (encoder.ConvertorFormatsContract, error) {
- formats := encoder.NewConvertorFormats()
- cmd := exec.Command(s.ffPathUtilities.FFmpeg, "-encoders")
- helper.PrepareBackgroundCommand(cmd)
-
- stdOut, err := cmd.StdoutPipe()
- if err != nil {
- return formats, err
- }
-
- err = cmd.Start()
- if err != nil {
- return formats, err
- }
-
- scannerErr := bufio.NewReader(stdOut)
- for {
- line, _, err := scannerErr.ReadLine()
- if err != nil {
- if err == io.EOF {
- break
- }
- continue
- }
- text := strings.Split(strings.TrimSpace(string(line)), " ")
- encoderType := string(text[0][0])
- if len(text) < 2 || (encoderType != "V" && encoderType != "A") {
- continue
- }
- formats.NewEncoder(text[1])
- }
-
- err = cmd.Wait()
- if err != nil {
- return formats, err
- }
-
- return formats, nil
-}
-
-func (s Convertor) GetRunningProcesses() map[int]*exec.Cmd {
- return s.runningProcesses.items
-}
-
-func getFirstDigits(s string) string {
- result := ""
- for _, r := range s {
- if unicode.IsDigit(r) {
- result += string(r)
- } else {
- break
- }
- }
- return result
-}
diff --git a/kernel/encoder/encoders.go b/kernel/encoder/encoders.go
deleted file mode 100644
index d9330f4..0000000
--- a/kernel/encoder/encoders.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package encoder
-
-import (
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/apng"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/bmp"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/flv"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/gif"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/h264_nvenc"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libmp3lame"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libshine"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libtwolame"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libvpx"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libvpx_vp9"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libwebp"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libwebp_anim"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libx264"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libx265"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libxvid"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/mjpeg"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/mp2"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/mp2fixed"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/mpeg1video"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/mpeg2video"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/mpeg4"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/msmpeg4"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/msmpeg4v2"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/msvideo1"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/png"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/qtrle"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/sgi"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/tiff"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/wmav1"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/wmav2"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/wmv1"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/wmv2"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/xbm"
-)
-
-var supportEncoders = map[string]func() encoder.EncoderDataContract{
- "libx264": libx264.NewData,
- "h264_nvenc": h264_nvenc.NewData,
- "libx265": libx265.NewData,
- "png": png.NewData,
- "gif": gif.NewData,
- "flv": flv.NewData,
- "apng": apng.NewData,
- "bmp": bmp.NewData,
- "mjpeg": mjpeg.NewData,
- "mpeg1video": mpeg1video.NewData,
- "mpeg2video": mpeg2video.NewData,
- "mpeg4": mpeg4.NewData,
- "libxvid": libxvid.NewData,
- "msmpeg4v2": msmpeg4v2.NewData,
- "msmpeg4": msmpeg4.NewData,
- "msvideo1": msvideo1.NewData,
- "qtrle": qtrle.NewData,
- "tiff": tiff.NewData,
- "sgi": sgi.NewData,
- "libvpx": libvpx.NewData,
- "libvpx-vp9": libvpx_vp9.NewData,
- "libwebp_anim": libwebp_anim.NewData,
- "libwebp": libwebp.NewData,
- "wmv1": wmv1.NewData,
- "wmv2": wmv2.NewData,
- "xbm": xbm.NewData,
- "mp2": mp2.NewData,
- "mp2fixed": mp2fixed.NewData,
- "libtwolame": libtwolame.NewData,
- "libmp3lame": libmp3lame.NewData,
- "libshine": libshine.NewData,
- "wmav1": wmav1.NewData,
- "wmav2": wmav2.NewData,
-}
diff --git a/kernel/error.go b/kernel/error.go
deleted file mode 100644
index 7f03ea1..0000000
--- a/kernel/error.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package kernel
-
-import (
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/app"
- "fyne.io/fyne/v2/container"
- "fyne.io/fyne/v2/widget"
-)
-
-func PanicErrorLang(err error, metadata *fyne.AppMetadata) {
- app.SetMetadata(*metadata)
- a := app.New()
- window := a.NewWindow("GUI for FFmpeg")
- window.SetContent(container.NewVBox(
- widget.NewLabel("Произошла ошибка!"),
- widget.NewLabel("произошла ошибка при получении языковых переводах. \n\r"+err.Error()),
- ))
- window.ShowAndRun()
- panic(err.Error())
-}
diff --git a/kernel/ffplay.go b/kernel/ffplay.go
deleted file mode 100644
index 0b5538f..0000000
--- a/kernel/ffplay.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package kernel
-
-import (
- "os/exec"
-)
-
-type FFplay struct {
- ffPathUtilities *FFPathUtilities
-}
-
-type FFplaySetting struct {
- PathToFile string
-}
-
-type FFplayContract interface {
- Run(setting FFplaySetting) error
-}
-
-func NewFFplay(ffPathUtilities *FFPathUtilities) *FFplay {
- return &FFplay{ffPathUtilities: ffPathUtilities}
-}
-
-func (ffplay FFplay) Run(setting FFplaySetting) error {
- args := []string{setting.PathToFile}
- cmd := exec.Command(ffplay.ffPathUtilities.FFplay, args...)
-
- return cmd.Start()
-}
diff --git a/kernel/items_to_convert.go b/kernel/items_to_convert.go
deleted file mode 100644
index 0adbc3d..0000000
--- a/kernel/items_to_convert.go
+++ /dev/null
@@ -1,151 +0,0 @@
-package kernel
-
-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"
- "github.com/nicksnyder/go-i18n/v2/i18n"
-)
-
-type ItemsToConvertContract interface {
- Add(file *File)
- GetItems() map[int]ItemToConvertContract
- AfterAddingQueue()
-}
-
-type ItemsToConvert struct {
- nextId int
- items map[int]ItemToConvertContract
- itemsContainer *fyne.Container
- ffplayService FFplayContract
- isAutoRemove bool
-}
-
-func NewItemsToConvert(itemsContainer *fyne.Container, ffplayService FFplayContract, localizerService LocalizerContract) *ItemsToConvert {
- containerForItems := container.NewVBox()
- ItemsToConvert := &ItemsToConvert{
- nextId: 0,
- items: map[int]ItemToConvertContract{},
- itemsContainer: containerForItems,
- ffplayService: ffplayService,
- isAutoRemove: true,
- }
-
- line := canvas.NewLine(theme.Color(theme.ColorNameFocus))
- line.StrokeWidth = 5
- checkboxAutoRemove := widget.NewCheck(localizerService.GetMessage(&i18n.LocalizeConfig{
- MessageID: "autoClearAfterAddingToQueue",
- }), func(checked bool) {
- ItemsToConvert.isAutoRemove = checked
- })
- checkboxAutoRemove.SetChecked(ItemsToConvert.isAutoRemove)
- localizerService.AddChangeCallback("autoClearAfterAddingToQueue", func(text string) {
- checkboxAutoRemove.Text = text
- })
-
- buttonClear := widget.NewButton(localizerService.GetMessage(&i18n.LocalizeConfig{
- MessageID: "clearAll",
- }), func() {
- ItemsToConvert.clear()
- })
- buttonClear.Importance = widget.DangerImportance
- localizerService.AddChangeCallback("clearAll", func(text string) {
- buttonClear.Text = text
- })
-
- itemsContainer.Add(container.NewVBox(
- container.NewPadded(),
- container.NewBorder(nil, nil, nil, buttonClear, container.NewHScroll(checkboxAutoRemove)),
- container.NewPadded(),
- line,
- container.NewPadded(),
- containerForItems,
- ))
-
- return ItemsToConvert
-}
-
-func (items *ItemsToConvert) Add(file *File) {
- nextId := items.nextId
- var content *fyne.Container
- var buttonPlay *widget.Button
-
- buttonPlay = widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
- buttonPlay.Disable()
- go func() {
- _ = items.ffplayService.Run(FFplaySetting{
- PathToFile: file.Path,
- })
- fyne.Do(func() {
- buttonPlay.Enable()
- })
- }()
- })
-
- buttonRemove := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameDelete), func() {
- items.itemsContainer.Remove(content)
- items.itemsContainer.Refresh()
- delete(items.items, nextId)
- })
- buttonRemove.Importance = widget.DangerImportance
-
- content = container.NewVBox(
- container.NewBorder(
- nil,
- nil,
- buttonPlay,
- buttonRemove,
- container.NewHScroll(widget.NewLabel(file.Name)),
- ),
- container.NewHScroll(widget.NewLabel(file.Path)),
- container.NewPadded(),
- canvas.NewLine(theme.Color(theme.ColorNameFocus)),
- container.NewPadded(),
- )
-
- items.itemsContainer.Add(content)
- items.items[nextId] = NewItemToConvert(file, content)
- items.nextId++
-}
-
-func (items *ItemsToConvert) GetItems() map[int]ItemToConvertContract {
- return items.items
-}
-
-func (items *ItemsToConvert) AfterAddingQueue() {
- if items.isAutoRemove {
- items.clear()
- }
-}
-
-func (items *ItemsToConvert) clear() {
- items.itemsContainer.RemoveAll()
- items.items = map[int]ItemToConvertContract{}
-}
-
-type ItemToConvertContract interface {
- GetFile() *File
- GetContent() *fyne.Container
-}
-
-type ItemToConvert struct {
- file *File
- content *fyne.Container
-}
-
-func NewItemToConvert(file *File, content *fyne.Container) *ItemToConvert {
- return &ItemToConvert{
- file: file,
- content: content,
- }
-}
-
-func (item ItemToConvert) GetFile() *File {
- return item.file
-}
-
-func (item ItemToConvert) GetContent() *fyne.Container {
- return item.content
-}
diff --git a/kernel/layout.go b/kernel/layout.go
deleted file mode 100644
index 3d34179..0000000
--- a/kernel/layout.go
+++ /dev/null
@@ -1,482 +0,0 @@
-package kernel
-
-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"
- "github.com/nicksnyder/go-i18n/v2/i18n"
- "image/color"
- "strconv"
- "strings"
-)
-
-type LayoutContract interface {
- SetContent(content fyne.CanvasObject) *fyne.Container
- ChangeQueueStatus(queueId int, queue *Queue)
- GetRightTabs() RightTabsContract
-}
-
-type Layout struct {
- layout *fyne.Container
- queueLayoutObject QueueLayoutObjectContract
- localizerService LocalizerContract
- rightTabsService RightTabsContract
-}
-
-func NewLayout(queueLayoutObject QueueLayoutObjectContract, localizerService LocalizerContract, rightTabsService RightTabsContract) *Layout {
- layout := container.NewAdaptiveGrid(2, widget.NewLabel(""), queueLayoutObject.GetCanvasObject())
-
- return &Layout{
- layout: layout,
- queueLayoutObject: queueLayoutObject,
- localizerService: localizerService,
- rightTabsService: rightTabsService,
- }
-}
-
-func (l Layout) SetContent(content fyne.CanvasObject) *fyne.Container {
- l.layout.Objects[0] = content
- return l.layout
-}
-
-func (l Layout) ChangeQueueStatus(queueId int, queue *Queue) {
- l.queueLayoutObject.ChangeQueueStatus(queueId, queue)
-}
-
-func (l Layout) GetRightTabs() RightTabsContract {
- return l.rightTabsService
-}
-
-type QueueLayoutObjectContract interface {
- GetCanvasObject() fyne.CanvasObject
- ChangeQueueStatus(queueId int, queue *Queue)
-}
-
-type QueueLayoutObject struct {
- QueueListContract QueueListContract
-
- queue QueueListContract
- container *fyne.Container
- containerItems *fyne.Container
- items map[int]QueueLayoutItem
- localizerService LocalizerContract
- queueStatisticsFormat *queueStatisticsFormat
- ffplayService FFplayContract
-}
-
-type QueueLayoutItem struct {
- CanvasObject fyne.CanvasObject
- BlockMessageError *container.Scroll
- StatusMessage *canvas.Text
- MessageError *canvas.Text
- buttonPlay *widget.Button
-
- status *StatusContract
-}
-
-func NewQueueLayoutObject(queue QueueListContract, localizerService LocalizerContract, ffplayService FFplayContract, rightTabsService RightTabsContract, blockProgressbar *fyne.Container) *QueueLayoutObject {
- title := widget.NewLabel(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "queue"}))
- title.TextStyle.Bold = true
-
- localizerService.AddChangeCallback("queue", func(text string) {
- title.Text = text
- title.Refresh()
- })
-
- items := map[int]QueueLayoutItem{}
- queueStatisticsFormat := newQueueStatisticsFormat(localizerService, &items)
-
- line := canvas.NewLine(theme.Color(theme.ColorNameFocus))
- line.StrokeWidth = 5
-
- rightTabsService.GetFileQueueContainer().Add(container.NewVBox(
- container.NewPadded(),
- container.NewHBox(title, queueStatisticsFormat.completed.widget, queueStatisticsFormat.error.widget),
- container.NewHBox(queueStatisticsFormat.inProgress.widget, queueStatisticsFormat.waiting.widget, queueStatisticsFormat.total.widget),
- container.NewPadded(),
- line,
- container.NewPadded(),
- ))
- queueLayoutObject := &QueueLayoutObject{
- queue: queue,
- container: container.NewBorder(
- container.NewVBox(
- blockProgressbar,
- widget.NewSeparator(),
- ),
- nil, nil, nil, container.NewVScroll(rightTabsService.GetTabs()),
- ),
- containerItems: rightTabsService.GetFileQueueContainer(),
- items: items,
- localizerService: localizerService,
- queueStatisticsFormat: queueStatisticsFormat,
- ffplayService: ffplayService,
- }
-
- queue.AddListener(queueLayoutObject)
-
- return queueLayoutObject
-}
-
-func (o QueueLayoutObject) GetCanvasObject() fyne.CanvasObject {
- return o.container
-}
-
-func (o QueueLayoutObject) Add(id int, queue *Queue) {
- statusMessage := canvas.NewText(o.getStatusTitle(queue.Status), theme.Color(theme.ColorNamePrimary))
- messageError := canvas.NewText("", theme.Color(theme.ColorNameError))
- buttonPlay := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
-
- })
- buttonPlay.Hide()
- blockMessageError := container.NewHScroll(messageError)
- blockMessageError.Hide()
-
- content := container.NewVBox(
- container.NewHScroll(widget.NewLabel(queue.Setting.VideoFileInput.Name)),
- container.NewHBox(
- buttonPlay,
- statusMessage,
- ),
- blockMessageError,
- container.NewPadded(),
- canvas.NewLine(theme.Color(theme.ColorNameFocus)),
- container.NewPadded(),
- )
-
- o.queueStatisticsFormat.addQueue()
- if o.queueStatisticsFormat.isChecked(queue.Status) == false {
- content.Hide()
- }
-
- o.items[id] = QueueLayoutItem{
- CanvasObject: content,
- StatusMessage: statusMessage,
- BlockMessageError: blockMessageError,
- MessageError: messageError,
- buttonPlay: buttonPlay,
- status: &queue.Status,
- }
- o.containerItems.Add(content)
-}
-
-func (o QueueLayoutObject) Remove(id int) {
- if item, ok := o.items[id]; ok {
- o.container.Remove(item.CanvasObject)
- o.queueStatisticsFormat.removeQueue(*item.status)
- o.items[id] = QueueLayoutItem{}
- }
-}
-
-func (o QueueLayoutObject) ChangeQueueStatus(queueId int, queue *Queue) {
- if item, ok := o.items[queueId]; ok {
- statusColor := o.getStatusColor(queue.Status)
- item.StatusMessage.Text = o.getStatusTitle(queue.Status)
- item.StatusMessage.Color = statusColor
- fyne.Do(func() {
- item.StatusMessage.Refresh()
- })
- if queue.Error != nil {
- item.MessageError.Text = queue.Error.Error()
- item.MessageError.Color = statusColor
- fyne.Do(func() {
- item.BlockMessageError.Show()
- item.MessageError.Refresh()
- })
- }
- if queue.Status == StatusType(Completed) {
- item.buttonPlay.Show()
- item.buttonPlay.OnTapped = func() {
- item.buttonPlay.Disable()
- go func() {
- _ = o.ffplayService.Run(FFplaySetting{
- PathToFile: queue.Setting.VideoFileOut.Path,
- })
- fyne.Do(func() {
- item.buttonPlay.Enable()
- })
- }()
- }
- }
- if o.queueStatisticsFormat.isChecked(queue.Status) == false && item.CanvasObject.Visible() == true {
- item.CanvasObject.Hide()
- } else if item.CanvasObject.Visible() == false {
- item.CanvasObject.Show()
- }
- o.queueStatisticsFormat.changeQueue(queue.Status)
- }
-}
-
-func (o QueueLayoutObject) getStatusColor(status StatusContract) color.Color {
- if status == StatusType(Error) {
- return theme.Color(theme.ColorNameError)
- }
-
- if status == StatusType(Completed) {
- return color.RGBA{R: 49, G: 127, B: 114, A: 255}
- }
-
- return theme.Color(theme.ColorNamePrimary)
-}
-
-func (o QueueLayoutObject) getStatusTitle(status StatusContract) string {
- return o.localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: status.Name() + "Queue"})
-}
-
-type queueStatistics struct {
- widget *widget.Check
- title string
- count *int64
-}
-type queueStatisticsFormat struct {
- waiting *queueStatistics
- inProgress *queueStatistics
- completed *queueStatistics
- error *queueStatistics
- total *queueStatistics
-}
-
-func newQueueStatisticsFormat(localizerService LocalizerContract, queueItems *map[int]QueueLayoutItem) *queueStatisticsFormat {
- checkWaiting := newQueueStatistics("waitingQueue", localizerService)
- checkInProgress := newQueueStatistics("inProgressQueue", localizerService)
- checkCompleted := newQueueStatistics("completedQueue", localizerService)
- checkError := newQueueStatistics("errorQueue", localizerService)
- checkTotal := newQueueStatistics("total", localizerService)
-
- queueStatisticsFormat := &queueStatisticsFormat{
- waiting: checkWaiting,
- inProgress: checkInProgress,
- completed: checkCompleted,
- error: checkError,
- total: checkTotal,
- }
-
- checkTotal.widget.OnChanged = func(b bool) {
- if b == true {
- queueStatisticsFormat.allCheckboxChecked()
- } else {
- queueStatisticsFormat.allUnCheckboxChecked()
- }
- queueStatisticsFormat.redrawingQueueItems(queueItems)
- }
-
- queueStatisticsFormat.waiting.widget.OnChanged = func(b bool) {
- if b == true {
- queueStatisticsFormat.checkboxChecked()
- } else {
- queueStatisticsFormat.unCheckboxChecked()
- }
- queueStatisticsFormat.redrawingQueueItems(queueItems)
- }
-
- queueStatisticsFormat.inProgress.widget.OnChanged = func(b bool) {
- if b == true {
- queueStatisticsFormat.checkboxChecked()
- } else {
- queueStatisticsFormat.unCheckboxChecked()
- }
- queueStatisticsFormat.redrawingQueueItems(queueItems)
- }
-
- queueStatisticsFormat.completed.widget.OnChanged = func(b bool) {
- if b == true {
- queueStatisticsFormat.checkboxChecked()
- } else {
- queueStatisticsFormat.unCheckboxChecked()
- }
- queueStatisticsFormat.redrawingQueueItems(queueItems)
- }
-
- queueStatisticsFormat.error.widget.OnChanged = func(b bool) {
- if b == true {
- queueStatisticsFormat.checkboxChecked()
- } else {
- queueStatisticsFormat.unCheckboxChecked()
- }
- queueStatisticsFormat.redrawingQueueItems(queueItems)
- }
-
- return queueStatisticsFormat
-}
-
-func (f queueStatisticsFormat) redrawingQueueItems(queueItems *map[int]QueueLayoutItem) {
- for _, item := range *queueItems {
- if f.isChecked(*item.status) == true && item.CanvasObject.Visible() == false {
- item.CanvasObject.Show()
- continue
- }
- if f.isChecked(*item.status) == false && item.CanvasObject.Visible() == true {
- item.CanvasObject.Hide()
- }
- }
-}
-
-func (f queueStatisticsFormat) isChecked(status StatusContract) bool {
- if status == StatusType(InProgress) {
- return f.inProgress.widget.Checked
- }
- if status == StatusType(Completed) {
- return f.completed.widget.Checked
- }
- if status == StatusType(Error) {
- return f.error.widget.Checked
- }
- if status == StatusType(Waiting) {
- return f.waiting.widget.Checked
- }
-
- return true
-}
-
-func (f queueStatisticsFormat) addQueue() {
- f.waiting.add()
- f.total.add()
-}
-
-func (f queueStatisticsFormat) changeQueue(status StatusContract) {
- if status == StatusType(InProgress) {
- f.waiting.remove()
- f.inProgress.add()
- return
- }
-
- if status == StatusType(Completed) {
- f.inProgress.remove()
- f.completed.add()
- return
- }
-
- if status == StatusType(Error) {
- f.inProgress.remove()
- f.error.add()
- return
- }
-}
-
-func (f queueStatisticsFormat) removeQueue(status StatusContract) {
- f.total.remove()
-
- if status == StatusType(Completed) {
- f.completed.remove()
- return
- }
-
- if status == StatusType(Error) {
- f.error.remove()
- return
- }
-
- if status == StatusType(InProgress) {
- f.inProgress.remove()
- return
- }
-
- if status == StatusType(Waiting) {
- f.waiting.remove()
- return
- }
-}
-
-func (f queueStatisticsFormat) checkboxChecked() {
- if f.total.widget.Checked == true {
- return
- }
-
- if f.waiting.widget.Checked == false {
- return
- }
-
- if f.inProgress.widget.Checked == false {
- return
- }
-
- if f.completed.widget.Checked == false {
- return
- }
-
- if f.error.widget.Checked == false {
- return
- }
-
- f.total.widget.Checked = true
- f.total.widget.Refresh()
-}
-
-func (f queueStatisticsFormat) unCheckboxChecked() {
- if f.total.widget.Checked == false {
- return
- }
-
- f.total.widget.Checked = false
- f.total.widget.Refresh()
-}
-
-func (f queueStatisticsFormat) allCheckboxChecked() {
- f.waiting.widget.Checked = true
- f.waiting.widget.Refresh()
- f.inProgress.widget.Checked = true
- f.inProgress.widget.Refresh()
- f.completed.widget.Checked = true
- f.completed.widget.Refresh()
- f.error.widget.Checked = true
- f.error.widget.Refresh()
-}
-
-func (f queueStatisticsFormat) allUnCheckboxChecked() {
- f.waiting.widget.Checked = false
- f.waiting.widget.Refresh()
- f.inProgress.widget.Checked = false
- f.inProgress.widget.Refresh()
- f.completed.widget.Checked = false
- f.completed.widget.Refresh()
- f.error.widget.Checked = false
- f.error.widget.Refresh()
-}
-
-func newQueueStatistics(messaigeID string, localizerService LocalizerContract) *queueStatistics {
- checkbox := widget.NewCheck("", nil)
- checkbox.Checked = true
-
- count := int64(0)
-
- title := localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: messaigeID})
- queueStatistics := &queueStatistics{
- widget: checkbox,
- title: strings.ToLower(title),
- count: &count,
- }
-
- queueStatistics.formatText(false)
-
- localizerService.AddChangeCallback(messaigeID, func(text string) {
- queueStatistics.title = strings.ToLower(text)
- queueStatistics.formatText(true)
- queueStatistics.widget.Refresh()
- })
-
- return queueStatistics
-}
-
-func (s queueStatistics) add() {
- *s.count += 1
- s.formatText(true)
-}
-
-func (s queueStatistics) remove() {
- if *s.count == 0 {
- return
- }
- *s.count -= 1
- s.formatText(true)
-}
-
-func (s queueStatistics) formatText(refresh bool) {
- s.widget.Text = s.title + ": " + strconv.FormatInt(*s.count, 10)
- if refresh == true {
- fyne.Do(func() {
- s.widget.Refresh()
- })
- }
-}
diff --git a/kernel/localizer.go b/kernel/localizer.go
deleted file mode 100644
index 3823c7d..0000000
--- a/kernel/localizer.go
+++ /dev/null
@@ -1,158 +0,0 @@
-package kernel
-
-import (
- "github.com/BurntSushi/toml"
- "github.com/nicksnyder/go-i18n/v2/i18n"
- "golang.org/x/text/cases"
- "golang.org/x/text/language"
- "golang.org/x/text/language/display"
- "path/filepath"
- "sort"
-)
-
-type LocalizerContract interface {
- GetLanguages() []Lang
- GetMessage(localizeConfig *i18n.LocalizeConfig) string
- SetCurrentLanguage(lang Lang) error
- SetCurrentLanguageByCode(code string) error
- GetCurrentLanguage() *CurrentLanguage
- AddChangeCallback(messageID string, callback func(text string))
-}
-
-type Lang struct {
- Code string
- Title string
-}
-
-type CurrentLanguage struct {
- Lang Lang
- localizer *i18n.Localizer
- localizerDefault *i18n.Localizer
-}
-
-type changeCallback struct {
- messageID string
- callback func(text string)
-}
-
-type Localizer struct {
- bundle *i18n.Bundle
- languages []Lang
- currentLanguage *CurrentLanguage
- changeCallbacks map[int]*changeCallback
-}
-
-func NewLocalizer(directory string, languageDefault language.Tag) (*Localizer, error) {
- bundle := i18n.NewBundle(languageDefault)
- bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
-
- languages, err := initLanguages(directory, bundle)
- if err != nil {
- return nil, err
- }
-
- localizerDefault := i18n.NewLocalizer(bundle, languageDefault.String())
-
- return &Localizer{
- bundle: bundle,
- languages: languages,
- currentLanguage: &CurrentLanguage{
- Lang: Lang{
- Code: languageDefault.String(),
- Title: cases.Title(languageDefault).String(display.Self.Name(languageDefault)),
- },
- localizer: localizerDefault,
- localizerDefault: localizerDefault,
- },
- changeCallbacks: map[int]*changeCallback{},
- }, nil
-}
-
-func initLanguages(directory string, bundle *i18n.Bundle) ([]Lang, error) {
- var languages []Lang
-
- files, err := filepath.Glob(directory + "/active.*.toml")
- if err != nil {
- return nil, err
- }
- for _, file := range files {
- lang, err := bundle.LoadMessageFile(file)
- if err != nil {
- return nil, err
- }
- title := cases.Title(lang.Tag).String(display.Self.Name(lang.Tag))
- languages = append(languages, Lang{Code: lang.Tag.String(), Title: title})
- }
-
- sort.Sort(languagesSort(languages))
-
- return languages, nil
-}
-
-func (l Localizer) GetLanguages() []Lang {
- return l.languages
-}
-
-func (l Localizer) GetMessage(localizeConfig *i18n.LocalizeConfig) string {
- message, err := l.GetCurrentLanguage().localizer.Localize(localizeConfig)
- if err != nil {
- message, err = l.GetCurrentLanguage().localizerDefault.Localize(localizeConfig)
- if err != nil {
- return err.Error()
- }
- }
- return message
-}
-
-func (l Localizer) SetCurrentLanguage(lang Lang) error {
- l.currentLanguage.Lang = lang
- l.currentLanguage.localizer = i18n.NewLocalizer(l.bundle, lang.Code)
- l.eventSetCurrentLanguage()
- return nil
-}
-
-func (l Localizer) SetCurrentLanguageByCode(code string) error {
- lang, err := language.Parse(code)
- if err != nil {
- return err
- }
- title := cases.Title(lang).String(display.Self.Name(lang))
- return l.SetCurrentLanguage(Lang{Code: lang.String(), Title: title})
-}
-
-func (l Localizer) GetCurrentLanguage() *CurrentLanguage {
- return l.currentLanguage
-}
-
-func (l Localizer) AddChangeCallback(messageID string, callback func(text string)) {
- l.changeCallbacks[len(l.changeCallbacks)] = &changeCallback{messageID: messageID, callback: callback}
-}
-
-func (l Localizer) eventSetCurrentLanguage() {
- for _, changeCallback := range l.changeCallbacks {
- text := l.GetMessage(&i18n.LocalizeConfig{MessageID: changeCallback.messageID})
- changeCallback.callback(text)
- }
-}
-
-type languagesSort []Lang
-
-func (l languagesSort) Len() int { return len(l) }
-func (l languagesSort) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
-func (l languagesSort) Less(i, j int) bool {
- return languagePriority(l[i]) < languagePriority(l[j])
-}
-func languagePriority(l Lang) int {
- priority := 0
-
- switch l.Code {
- case "ru":
- priority = -3
- case "kk":
- priority = -2
- case "en":
- priority = -1
- }
-
- return priority
-}
diff --git a/kernel/progressbar.go b/kernel/progressbar.go
deleted file mode 100644
index 48b8485..0000000
--- a/kernel/progressbar.go
+++ /dev/null
@@ -1,254 +0,0 @@
-package kernel
-
-import (
- "bufio"
- "errors"
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/canvas"
- "fyne.io/fyne/v2/container"
- "fyne.io/fyne/v2/theme"
- "fyne.io/fyne/v2/widget"
- "github.com/nicksnyder/go-i18n/v2/i18n"
- "image/color"
- "io"
- "regexp"
- "strconv"
- "strings"
-)
-
-type BlockProgressbarContract interface {
- GetContainer() *fyne.Container
- GetProgressbar(totalDuration float64, filePath string, localizerService LocalizerContract) Progress
- ProcessEndedWithError(errorText string)
- ProcessEndedWithSuccess(filePath string)
-}
-
-type BlockProgressbar struct {
- container *fyne.Container
- label *widget.Label
- progressbar *widget.ProgressBar
- errorBlock *container.Scroll
- messageError *canvas.Text
- statusMessage *canvas.Text
- buttonPlay *widget.Button
- statusesText *BlockProgressbarStatusesText
- ffplayService FFplayContract
-}
-
-func NewBlockProgressbar(statusesText *BlockProgressbarStatusesText, ffplayService FFplayContract) *BlockProgressbar {
- 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 &BlockProgressbar{
- container: content,
- label: label,
- progressbar: progressbar,
- errorBlock: errorBlock,
- messageError: messageError,
- statusMessage: statusMessage,
- buttonPlay: buttonPlay,
- statusesText: statusesText,
- ffplayService: ffplayService,
- }
-}
-
-func (block BlockProgressbar) GetContainer() *fyne.Container {
- return block.container
-}
-
-func (block BlockProgressbar) GetProgressbar(totalDuration float64, filePath string, localizerService LocalizerContract) Progress {
- block.label.Text = filePath
- block.statusMessage.Color = theme.Color(theme.ColorNamePrimary)
- block.statusMessage.Text = block.statusesText.inProgress
- block.messageError.Text = ""
- fyne.Do(func() {
- block.buttonPlay.Hide()
- if block.errorBlock.Visible() {
- block.errorBlock.Hide()
- }
- block.statusMessage.Refresh()
- block.container.Refresh()
- block.errorBlock.Refresh()
- })
-
- block.progressbar.Value = 0
- return NewProgress(totalDuration, block.progressbar, localizerService)
-}
-
-func (block BlockProgressbar) ProcessEndedWithError(errorText string) {
- fyne.Do(func() {
- block.statusMessage.Color = theme.Color(theme.ColorNameError)
- block.statusMessage.Text = block.statusesText.error
- block.messageError.Text = errorText
- block.errorBlock.Show()
- })
-}
-
-func (block BlockProgressbar) ProcessEndedWithSuccess(filePath string) {
- fyne.Do(func() {
- block.statusMessage.Color = color.RGBA{R: 49, G: 127, B: 114, A: 255}
- block.statusMessage.Text = block.statusesText.completed
- block.buttonPlay.Show()
- block.buttonPlay.OnTapped = func() {
- block.buttonPlay.Disable()
- go func() {
- _ = block.ffplayService.Run(FFplaySetting{
- PathToFile: filePath,
- })
- fyne.Do(func() {
- block.buttonPlay.Enable()
- })
- }()
- }
- })
-}
-
-type Progress struct {
- totalDuration float64
- progressbar *widget.ProgressBar
- protocol string
- localizerService LocalizerContract
-}
-
-func NewProgress(totalDuration float64, progressbar *widget.ProgressBar, localizerService LocalizerContract) Progress {
- return Progress{
- totalDuration: totalDuration,
- progressbar: progressbar,
- protocol: "pipe:",
- localizerService: localizerService,
- }
-}
-
-func (p Progress) GetProtocole() string {
- return p.protocol
-}
-
-func (p Progress) Run(stdOut io.ReadCloser, stdErr io.ReadCloser) error {
- isProcessCompleted := false
- var errorText string
-
- p.progressbar.Value = 0
- p.progressbar.Max = p.totalDuration
- fyne.Do(func() {
- p.progressbar.Refresh()
- })
- progress := 0.0
-
- go func() {
- scannerErr := bufio.NewReader(stdErr)
- for {
- line, _, err := scannerErr.ReadLine()
- if err != nil {
- if err == io.EOF {
- break
- }
- continue
- }
- data := strings.TrimSpace(string(line))
- errorText = data
- }
- }()
-
- scannerOut := bufio.NewReader(stdOut)
- for {
- line, _, err := scannerOut.ReadLine()
- if err != nil {
- if err == io.EOF {
- break
- }
- continue
- }
- data := strings.TrimSpace(string(line))
- if strings.Contains(data, "progress=end") {
- p.progressbar.Value = p.totalDuration
- fyne.Do(func() {
- p.progressbar.Refresh()
- })
- isProcessCompleted = true
- break
- }
-
- re := regexp.MustCompile(`frame=(\d+)`)
- a := re.FindAllStringSubmatch(data, -1)
-
- if len(a) > 0 && len(a[len(a)-1]) > 0 {
- c, err := strconv.Atoi(a[len(a)-1][len(a[len(a)-1])-1])
- if err != nil {
- continue
- }
- progress = float64(c)
- }
- if p.progressbar.Value != progress {
- p.progressbar.Value = progress
- fyne.Do(func() {
- p.progressbar.Refresh()
- })
- }
- }
-
- if isProcessCompleted == false {
- if len(errorText) == 0 {
- errorText = p.localizerService.GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorConverter",
- })
- }
- return errors.New(errorText)
- }
-
- return nil
-}
-
-type BlockProgressbarStatusesText struct {
- inProgress string
- completed string
- error string
-}
-
-func GetBlockProgressbarStatusesText(localizerService LocalizerContract) *BlockProgressbarStatusesText {
- statusesText := &BlockProgressbarStatusesText{
- inProgress: localizerService.GetMessage(&i18n.LocalizeConfig{
- MessageID: "inProgressQueue",
- }),
- completed: localizerService.GetMessage(&i18n.LocalizeConfig{
- MessageID: "completedQueue",
- }),
- error: localizerService.GetMessage(&i18n.LocalizeConfig{
- MessageID: "errorQueue",
- }),
- }
-
- localizerService.AddChangeCallback("inProgressQueue", func(text string) {
- statusesText.inProgress = text
- })
-
- localizerService.AddChangeCallback("completedQueue", func(text string) {
- statusesText.completed = text
- })
-
- localizerService.AddChangeCallback("errorQueue", func(text string) {
- statusesText.error = text
- })
-
- return statusesText
-}
diff --git a/kernel/queue.go b/kernel/queue.go
deleted file mode 100644
index 6d2f6c4..0000000
--- a/kernel/queue.go
+++ /dev/null
@@ -1,125 +0,0 @@
-package kernel
-
-import (
- "errors"
-)
-
-type Queue struct {
- Setting *ConvertSetting
- Status StatusContract
- Error error
-}
-
-type StatusContract interface {
- Name() string
- Ordinal() int
-}
-
-const (
- Waiting = iota
- InProgress
- Completed
- Error
-)
-
-type StatusType uint
-
-var statusTypeStrings = []string{
- "waiting",
- "inProgress",
- "completed",
- "error",
-}
-
-func (status StatusType) Name() string {
- return statusTypeStrings[status]
-}
-
-func (status StatusType) Ordinal() int {
- return int(status)
-}
-
-type QueueListenerContract interface {
- Add(key int, queue *Queue)
- Remove(key int)
-}
-
-type QueueListContract interface {
- AddListener(queueListener QueueListenerContract)
- GetItems() map[int]*Queue
- Add(setting *ConvertSetting)
- Remove(key int)
- GetItem(key int) (*Queue, error)
- Next() (key int, queue *Queue)
-}
-
-type QueueList struct {
- currentKey *int
- items map[int]*Queue
- queueListener map[int]QueueListenerContract
-}
-
-func NewQueueList() *QueueList {
- currentKey := 0
- return &QueueList{
- currentKey: ¤tKey,
- items: map[int]*Queue{},
- queueListener: map[int]QueueListenerContract{},
- }
-}
-
-func (l QueueList) GetItems() map[int]*Queue {
- return l.items
-}
-
-func (l QueueList) Add(setting *ConvertSetting) {
- queue := Queue{
- Setting: setting,
- Status: StatusType(Waiting),
- }
-
- *l.currentKey += 1
- l.items[*l.currentKey] = &queue
- l.eventAdd(*l.currentKey, &queue)
-}
-
-func (l QueueList) Remove(key int) {
- if _, ok := l.items[key]; ok {
- delete(l.items, key)
- l.eventRemove(key)
- }
-}
-
-func (l QueueList) GetItem(key int) (*Queue, error) {
- if item, ok := l.items[key]; ok {
- return item, nil
- }
-
- return nil, errors.New("key not found")
-}
-
-func (l QueueList) AddListener(queueListener QueueListenerContract) {
- l.queueListener[len(l.queueListener)] = queueListener
-}
-
-func (l QueueList) eventAdd(key int, queue *Queue) {
- for _, listener := range l.queueListener {
- listener.Add(key, queue)
- }
-}
-
-func (l QueueList) eventRemove(key int) {
- for _, listener := range l.queueListener {
- listener.Remove(key)
- }
-}
-
-func (l QueueList) Next() (key int, queue *Queue) {
- statusWaiting := StatusType(Waiting)
- for key, item := range l.items {
- if item.Status == statusWaiting {
- return key, item
- }
- }
- return -1, nil
-}
diff --git a/kernel/right_tabs.go b/kernel/right_tabs.go
deleted file mode 100644
index 16f8de1..0000000
--- a/kernel/right_tabs.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package kernel
-
-import (
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/container"
- "github.com/nicksnyder/go-i18n/v2/i18n"
-)
-
-type RightTabsContract interface {
- GetTabs() *container.AppTabs
- GetAddedFilesContainer() *fyne.Container
- GetFileQueueContainer() *fyne.Container
- SelectFileQueueTab()
- SelectAddedFilesTab()
-}
-
-type RightTabs struct {
- tabs *container.AppTabs
-
- addedFilesContainer *fyne.Container
- addedFilesTab *container.TabItem
-
- fileQueueContainer *fyne.Container
- fileQueueTab *container.TabItem
-}
-
-func NewRightTabs(localizerService LocalizerContract) *RightTabs {
- addedFilesContainer := container.NewVBox()
- addedFilesTab := container.NewTabItem(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "addedFilesTitle"}), addedFilesContainer)
- localizerService.AddChangeCallback("addedFilesTitle", func(text string) {
- addedFilesTab.Text = text
- })
-
- fileQueueContainer := container.NewVBox()
- fileQueueTab := container.NewTabItem(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "fileQueueTitle"}), fileQueueContainer)
- localizerService.AddChangeCallback("fileQueueTitle", func(text string) {
- fileQueueTab.Text = text
- })
-
- tabs := container.NewAppTabs(
- addedFilesTab,
- fileQueueTab,
- )
-
- return &RightTabs{
- tabs: tabs,
- addedFilesContainer: addedFilesContainer,
- addedFilesTab: addedFilesTab,
- fileQueueContainer: fileQueueContainer,
- fileQueueTab: fileQueueTab,
- }
-}
-
-func (t RightTabs) GetTabs() *container.AppTabs {
- return t.tabs
-}
-
-func (t RightTabs) GetAddedFilesContainer() *fyne.Container {
- return t.addedFilesContainer
-}
-
-func (t RightTabs) GetFileQueueContainer() *fyne.Container {
- return t.fileQueueContainer
-}
-
-func (t RightTabs) SelectFileQueueTab() {
- fyne.Do(func() {
- t.tabs.Select(t.fileQueueTab)
- })
-}
-
-func (t RightTabs) SelectAddedFilesTab() {
- fyne.Do(func() {
- t.tabs.Select(t.addedFilesTab)
- })
-}
diff --git a/kernel/window.go b/kernel/window.go
deleted file mode 100644
index cec7b5b..0000000
--- a/kernel/window.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package kernel
-
-import (
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/dialog"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/helper"
- "time"
-)
-
-type WindowContract interface {
- SetContent(content fyne.CanvasObject)
- SetMainMenu(menu *fyne.MainMenu)
- NewFileOpen(callback func(fyne.URIReadCloser, error), location fyne.ListableURI) *dialog.FileDialog
- NewFolderOpen(callback func(fyne.ListableURI, error), location fyne.ListableURI) *dialog.FileDialog
- SetOnDropped(callback func(position fyne.Position, uris []fyne.URI))
- ShowAndRun()
- GetLayout() LayoutContract
-}
-
-type Window struct {
- windowFyne fyne.Window
- layout LayoutContract
-}
-
-func newWindow(w fyne.Window, layout LayoutContract) Window {
- windowSize := fyne.Size{Width: 1039, Height: 599}
- w.Resize(windowSize)
- w.CenterOnScreen()
-
- fyne.Do(func() {
- /**
- * Bug fixed.
- * When starting the program, sometimes the window was displayed incorrectly.
- */
- windowSize.Width += 1
- windowSize.Height += 1
- time.Sleep(time.Millisecond * 500)
- w.Resize(windowSize)
- })
-
- return Window{
- windowFyne: w,
- layout: layout,
- }
-}
-
-func (w Window) SetContent(content fyne.CanvasObject) {
- fyne.Do(func() {
- w.windowFyne.SetContent(w.layout.SetContent(content))
- })
-}
-
-func (w Window) NewFileOpen(callback func(fyne.URIReadCloser, error), location fyne.ListableURI) *dialog.FileDialog {
- fileDialog := dialog.NewFileOpen(callback, w.windowFyne)
- helper.FileDialogResize(fileDialog, w.windowFyne)
- fileDialog.Show()
- if location != nil {
- fileDialog.SetLocation(location)
- }
- return fileDialog
-}
-
-func (w Window) NewFolderOpen(callback func(fyne.ListableURI, error), location fyne.ListableURI) *dialog.FileDialog {
- fileDialog := dialog.NewFolderOpen(callback, w.windowFyne)
- helper.FileDialogResize(fileDialog, w.windowFyne)
- fileDialog.Show()
- if location != nil {
- fileDialog.SetLocation(location)
- }
- return fileDialog
-}
-
-func (w Window) SetMainMenu(menu *fyne.MainMenu) {
- w.windowFyne.SetMainMenu(menu)
-}
-
-func (w Window) ShowAndRun() {
- w.windowFyne.ShowAndRun()
-}
-
-func (w Window) GetLayout() LayoutContract {
- return w.layout
-}
-
-func (w Window) SetOnDropped(callback func(position fyne.Position, uris []fyne.URI)) {
- fyne.Do(func() {
- w.windowFyne.SetOnDropped(callback)
- })
-}
diff --git a/languages/.gitignore b/languages/.gitignore
deleted file mode 100644
index bc8acef..0000000
--- a/languages/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-translate.*.toml
diff --git a/languages/active.en.toml b/languages/active.en.toml
deleted file mode 100644
index c5c158d..0000000
--- a/languages/active.en.toml
+++ /dev/null
@@ -1,571 +0,0 @@
-[AlsoUsedProgram]
-hash = "sha1-a72be72e7808bb8a0144ed7a93acb29c568b1ed4"
-other = "The program also uses:"
-
-[about]
-hash = "sha1-3da0b9ef719fd707f443ac00404447f29445976f"
-other = "About"
-
-[aboutText]
-hash = "sha1-8bd565814118ba8b90c40eb5b62acf8d2676e7d6"
-other = "A simple interface for the FFmpeg console utility. \nBut I am not the author of the FFmpeg utility itself."
-
-[addedFilesTitle]
-hash = "sha1-8ba0f6e477b0d78df2cc06f1d8b41b888623b851"
-other = "Added files"
-
-[autoClearAfterAddingToQueue]
-hash = "sha1-b3781695a4c35380d2cd075bb52f27a2a6d8f19c"
-other = "Auto-clear after adding to queue"
-
-[buttonDownloadFFmpeg]
-hash = "sha1-c223c2e15171156192bc3146aee91e6094bb475b"
-other = "Download FFmpeg automatically"
-
-[buttonForSelectedDirTitle]
-hash = "sha1-8cbe5c67bcf89e4624635a79cbea104227faedda"
-other = "Save to folder:"
-
-[cancel]
-hash = "sha1-0ec753be8df955a117404fb634b01b45eb386e2a"
-other = "Cancel"
-
-[changeFFPath]
-hash = "sha1-1f704de0560f8135eb6924cd232ed919ca2e5af0"
-other = "FFmpeg, FFprobe and FFplay"
-
-[changeLanguage]
-hash = "sha1-8b276eaf378d485c769fb3d5dcc06dfc25b0c01b"
-other = "Change language"
-
-[checkboxOverwriteOutputFilesTitle]
-hash = "sha1-5860124bb781e7ef680f573fa93977e96328d4e7"
-other = "Allow file to be overwritten"
-
-[choose]
-hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94"
-other = "choose"
-
-[clearAll]
-hash = "sha1-f32702d79ac206432400ac6b041695d020f6fa77"
-other = "Clear List"
-
-[completedQueue]
-hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe"
-other = "Completed"
-
-[converterVideoFilesSubmitTitle]
-hash = "sha1-7ac460f3c24c9952082f2db6e4d62f752598709c"
-other = "Convert"
-
-[converterVideoFilesTitle]
-hash = "sha1-1ab29597cc9dfefab08e54ea5442e7ffa15f0394"
-other = "Video, audio and picture converter"
-
-[download]
-hash = "sha1-fe8f79f29da457de2f6bc9531de6e536e0c426ad"
-other = "Download"
-
-[downloadFFmpegFromSite]
-hash = "sha1-0889c95aa3a8659d8d903b4dab7097699c4d8aa4"
-other = "Will be downloaded from the site:"
-
-[downloadRun]
-hash = "sha1-55f87f114628fa2d5d8e67d1e1cda22c0e4f9271"
-other = "Downloading..."
-
-[dragAndDropFiles]
-hash = "sha1-07bb747cc7590d7a51cdf96dff49a74139097766"
-other = "drag and drop files"
-
-[encoderGroupAudio]
-hash = "sha1-24321cb5400df96be8f3e2131918bebdb3a01bba"
-other = "Audio"
-
-[encoderGroupImage]
-hash = "sha1-a7e528bc7ac9538aec87d1593c38b80be95d4745"
-other = "Images"
-
-[encoderGroupVideo]
-hash = "sha1-8e7b9894c7ef0f57ac0bf910f6a8aac1c8a53683"
-other = "Video"
-
-[encoder_apng]
-hash = "sha1-1cbd9abfef96d5614a7e569161b41bd6ad87bbaf"
-other = "APNG image"
-
-[encoder_bmp]
-hash = "sha1-e0b9c16b016961a5abdc2217e8ffd1ba7ddebc40"
-other = "BMP image"
-
-[encoder_flv]
-hash = "sha1-3602bbf1cc90e48254f81975c7879b5fc0c4d602"
-other = "FLV"
-
-[encoder_gif]
-hash = "sha1-d092a779172291b5215aa095390a5b11659128a4"
-other = "GIF image"
-
-[encoder_h264_nvenc]
-hash = "sha1-169389f8c4a2518410159c363378ab5c978c32e5"
-other = "H.264 with NVIDIA support"
-
-[encoder_libmp3lame]
-hash = "sha1-cd2c8d6f246c8bc18554b7105cb50b78d3cb2b98"
-other = "libmp3lame MP3 (MPEG audio layer 3)"
-
-[encoder_libshine]
-hash = "sha1-891d56c85857e5d83ef5a1fe077c1f1540788f49"
-other = "libshine MP3 (MPEG audio layer 3)"
-
-[encoder_libtwolame]
-hash = "sha1-b2f53be810b74edc3c454ac75de7ddecfee322ca"
-other = "libtwolame MP2 (MPEG audio layer 2)"
-
-[encoder_libvpx]
-hash = "sha1-b85c923aecfb48de0e87e71b6a21bfc2c547c70e"
-other = "libvpx VP8 (codec vp8)"
-
-[encoder_libvpx-vp9]
-hash = "sha1-3106417bd89bee87daa691e87614caf78cb934fe"
-other = "libvpx VP9 (codec vp9)"
-
-[encoder_libwebp]
-hash = "sha1-1d590d47d46f7880246061fce0e0de6d743db39e"
-other = "libwebp WebP image"
-
-[encoder_libwebp_anim]
-hash = "sha1-f141a9c8f23d79c13d44c30d8f34e05b363771ad"
-other = "libwebp_anim WebP image"
-
-[encoder_libx264]
-hash = "sha1-6d764ac459c0bf3c819d76618418cdfbb7a749eb"
-other = "H.264 libx264"
-
-[encoder_libx265]
-hash = "sha1-55544c166b1e15fd71a58096518e528109599eea"
-other = "H.265 libx265"
-
-[encoder_libxvid]
-hash = "sha1-d4bed46d6cdd2bfa8fd1689801164a83ab10c3f5"
-other = "libxvidcore MPEG-4 part 2"
-
-[encoder_mjpeg]
-hash = "sha1-94ba63a322b493a04da65e566781fe1cf8bb0d50"
-other = "MJPEG (Motion JPEG)"
-
-[encoder_mp2]
-hash = "sha1-a9154b7203349e5d6fbfd67d1ea97715f54b2065"
-other = "MP2 (MPEG audio layer 2)"
-
-[encoder_mp2fixed]
-hash = "sha1-dd2ee670d8bc8a60a96a717ebd26f16b5748cf3f"
-other = "MP2 fixed point (MPEG audio layer 2)"
-
-[encoder_mpeg1video]
-hash = "sha1-30043660719a3cb19dab5c33450665a8a9cc1c01"
-other = "MPEG-1"
-
-[encoder_mpeg2video]
-hash = "sha1-ccb2dcd8510cfdc9d52e5258af1863e5f2c51e77"
-other = "MPEG-2"
-
-[encoder_mpeg4]
-hash = "sha1-67fe42f18421b2f6c90fcdc579f9199bfca4b182"
-other = "MPEG-4 part 2"
-
-[encoder_msmpeg4]
-hash = "sha1-313ee597e4f0d9bd63a2bc6ac1618f028aef76f4"
-other = "MPEG-4 part 2 Microsoft variant version 3"
-
-[encoder_msmpeg4v2]
-hash = "sha1-adc442ce88f2717693b2da3010a1937d77ee522f"
-other = "MPEG-4 part 2 Microsoft variant version 2"
-
-[encoder_msvideo1]
-hash = "sha1-00f43ac0dc162bca10e0d98d6b70c0c6a902f66f"
-other = "Microsoft Video-1"
-
-[encoder_png]
-hash = "sha1-6715d4b82f5d9dfe3e53e30b402ffa1a6fbf30a5"
-other = "PNG image"
-
-[encoder_qtrle]
-hash = "sha1-31bf155cffaf6842ebc54084e4337ca08fdd9848"
-other = "QuickTime Animation (RLE) video"
-
-[encoder_sgi]
-hash = "sha1-f4510e237f7fc3c02caa728f9e500f4b069f9c11"
-other = "SGI image"
-
-[encoder_tiff]
-hash = "sha1-ed09d78c38e0b17ed695f35740c756dd7340eeac"
-other = "TIFF image"
-
-[encoder_wmav1]
-hash = "sha1-cd4a4c5eeac694b6699d55d0f9b477b3b50f18c7"
-other = "Windows Media Audio 1"
-
-[encoder_wmav2]
-hash = "sha1-eb2e5306cb33a702577ecfbdca0461862c66c053"
-other = "Windows Media Audio 2"
-
-[encoder_wmv1]
-hash = "sha1-f9b748554c590c36a56bcba2cd317196b7bdeddb"
-other = "Windows Media Video 7"
-
-[encoder_wmv2]
-hash = "sha1-5b21c87f5c6104797ead60b488b2948428f6b1b7"
-other = "Windows Media Video 8"
-
-[encoder_xbm]
-hash = "sha1-2dfc35881da62e9a1379d8238cf7839b24f79566"
-other = "XBM (X BitMap) image"
-
-[error]
-hash = "sha1-a7df8f8b5d754f226ac4cb320577fe692b33e483"
-other = "An error has occurred!"
-
-[errorConverter]
-hash = "sha1-55ebddceddb8b044e33cc3893ec2eba7bbd9fcf9"
-other = "Couldn't convert video"
-
-[errorDatabase]
-hash = "sha1-531abc3f0d12727e542df6e5a22de91098380fc1"
-other = "could not create file 'database' in folder 'data'"
-
-[errorDatabaseTimeout]
-hash = "sha1-f8153516ac2442d19be4b6daccce839d204ff09f"
-other = "Could not open configuration file.\nMake sure another copy of the program is not running!"
-
-[errorDragAndDropFile]
-hash = "sha1-863cf1ad9c820d5b0c2006ceeaa29e25f81c1714"
-other = "Not all files were added"
-
-[errorFFmpeg]
-hash = "sha1-ccf0b95c0d1b392dc215258d917eb4e5d0b88ed0"
-other = "this is not FFmpeg"
-
-[errorFFmpegVersion]
-hash = "sha1-9a4148d42186b6b32cf83bef726e23022c53283f"
-other = "Could not determine FFmpeg version"
-
-[errorFFplay]
-hash = "sha1-988122112ac6002094e25518cfb5f0d606217298"
-other = "this is not FFplay"
-
-[errorFFplayVersion]
-hash = "sha1-cd60928d20d93210e103dd464306ab138bf1b184"
-other = "Could not determine FFplay version"
-
-[errorFFprobe]
-hash = "sha1-86d1b0b4c4ccd6a4f71e758fc67ce11aff4ba9b8"
-other = "this is not FFprobe"
-
-[errorFFprobeVersion]
-hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17"
-other = "Failed to determine FFprobe version"
-
-[errorNoFilesAddedForConversion]
-hash = "sha1-5cf1f65bef15cb0382e56be98f44c6abde56a314"
-other = "There are no files to convert"
-
-[errorQueue]
-hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7"
-other = "Error"
-
-[errorSelectedEncoder]
-hash = "sha1-33ed1aaf4cb3c2ee9d8f8c325b9b75d16ddf9979"
-other = "Converter not selected"
-
-[errorSelectedFolderSave]
-hash = "sha1-16f3ef93ee36813fdd79d8fb9bb7fc02acbb94a8"
-other = "No save folder selected!"
-
-[errorSelectedFormat]
-hash = "sha1-cda92c56a1ef1aabc92bbfc405ede8ab13087e66"
-other = "File extension not selected"
-
-[exit]
-hash = "sha1-c42457057d1ab7950cea00719cbe0b078891775f"
-other = "Exit"
-
-[ffmpegLGPL]
-hash = "sha1-d395b16cc8f8eab98a8a970307c5b010ba22dde6"
-other = "This software uses libraries from the **FFmpeg** project under the **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**."
-
-[ffmpegTrademark]
-hash = "sha1-45f772b2eca5098cd6d31f2d1dc6edec1987a617"
-other = "**FFmpeg** is a trademark of **[Fabrice Bellard](http://bellard.org/)**, originator of the **[FFmpeg](https://ffmpeg.org/about.html)** project."
-
-[fileForConversionTitle]
-hash = "sha1-96ac799e1086b31fd8f5f8d4c801829d6c853f08"
-other = "File:"
-
-[fileQueueTitle]
-hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8"
-other = "Queue"
-
-[formPreset]
-hash = "sha1-7759891ba1ef9f7adc70defc7ac18fbf149c1a68"
-other = "Preset"
-
-[gratitude]
-hash = "sha1-51968fc38e53a9a11c861126c62404674fd6096f"
-other = "Gratitude"
-
-[gratitudeText]
-hash = "sha1-cb343e4d39ca31e6da6f72b9394cc915cb7d1258"
-other = "I sincerely thank you for your invaluable\n\r and timely assistance:"
-
-[help]
-hash = "sha1-6a45cef900c668effcb2ab10da05855c1fd10f6f"
-other = "Help"
-
-[helpFFplay]
-hash = "sha1-ecc294b8b3d217ee1c2d63dc2f0253c3d1b3712c"
-other = "FFplay Player Keys"
-
-[helpFFplayActivateFrameStepMode]
-hash = "sha1-f47ede90932d69465f6197cb2a7cc4d1e3ab150e"
-other = "Activate frame-by-frame mode."
-
-[helpFFplayCycleVideoFiltersOrShowModes]
-hash = "sha1-83bb702c777e4768cdc326a668d541c23ab759b7"
-other = "A cycle of video filters or display modes."
-
-[helpFFplayDecreaseVolume]
-hash = "sha1-de28db96a9c22be885ec5067a13f8f17fd3954bc"
-other = "Decrease the volume."
-
-[helpFFplayDescription]
-hash = "sha1-f5441f6aee76222c4120066575e80c2d177ac3c0"
-other = "Description"
-
-[helpFFplayDoubleClickLeftMouseButton]
-hash = "sha1-2657aa576055769952dfcde570fc9b4765d594ad"
-other = "double click\nleft mouse button"
-
-[helpFFplayIncreaseVolume]
-hash = "sha1-8ba7bde2d9a80f4a7cd122cf4973975698d3bd34"
-other = "Increase the volume."
-
-[helpFFplayKeyDown]
-hash = "sha1-c5aefd2f8c6908a69b08fe4a2d235b1ae0113470"
-other = "down"
-
-[helpFFplayKeyHoldS]
-hash = "sha1-89c5dd8287c15b3f40db66e06b038c34a715f02f"
-other = "hold S"
-
-[helpFFplayKeyLeft]
-hash = "sha1-feb671890703fb0300a436744d34018bbc7ba13a"
-other = "left"
-
-[helpFFplayKeyRight]
-hash = "sha1-a4f025d4bf7f90ee5bec6c48b2710bc9c5bbb267"
-other = "right"
-
-[helpFFplayKeySpace]
-hash = "sha1-a367ad00358ec44edc1d54a96df6f9114b0f8697"
-other = "SPACE"
-
-[helpFFplayKeyUp]
-hash = "sha1-e4845aa8c0e100a80eaf65446c59085236fd2098"
-other = "up"
-
-[helpFFplayKeys]
-hash = "sha1-0ad272ade8c568f394499f1492ecfab56e701e5d"
-other = "Keys"
-
-[helpFFplayPause]
-hash = "sha1-e83e107900fde0c39295f599c2cf8fba8d8cb604"
-other = "Pause or continue playing."
-
-[helpFFplayQuit]
-hash = "sha1-70785a2fd5d5a6519b7439f0d8cfcd7d54c5771d"
-other = "Close the player."
-
-[helpFFplaySeekBForward10Minutes]
-hash = "sha1-58ed63343376240f2596e447b5245c1805f35234"
-other = "Fast forward 10 minutes."
-
-[helpFFplaySeekBForward1Minute]
-hash = "sha1-3fe46b8d5413b7fdc53ae9ed9427bcb1769ec74c"
-other = "Fast forward 1 minute."
-
-[helpFFplaySeekBackward10Minutes]
-hash = "sha1-927dffe9af72ffd40f46873b452a4c90627bccf8"
-other = "Rewind 10 minutes."
-
-[helpFFplaySeekBackward10Seconds]
-hash = "sha1-e97615ecec0f8cf5647e8802bdda38dc2b0d809f"
-other = "Rewind 10 seconds."
-
-[helpFFplaySeekBackward1Minute]
-hash = "sha1-5b19e280a0850122c8ebc80c622491bb09520e1a"
-other = "Rewind 1 minute."
-
-[helpFFplaySeekForward10Seconds]
-hash = "sha1-8d840251d4a1668edaea3515df197a8a79031ec3"
-other = "Fast forward 10 seconds."
-
-[helpFFplayToggleFullScreen]
-hash = "sha1-d32df02849258c5b02f15e5711f54ee6a8a75fd4"
-other = "Switch to full screen or exit full screen."
-
-[helpFFplayToggleMute]
-hash = "sha1-4bdbb124fe8de3a8037c1e74719e9600b21b25ab"
-other = "Mute or unmute."
-
-[inProgressQueue]
-hash = "sha1-eff79c40e2100ae5fadf3a7d99336025edcca8b5"
-other = "In Progress"
-
-[languageSelectionFormHead]
-hash = "sha1-0ff5fa82cf684112660128cba1711297acf11003"
-other = "Switch language"
-
-[languageSelectionHead]
-hash = "sha1-daf1108fc10d3b1a908288d611f749b3cc651e4b"
-other = "Choose language"
-
-[licenseLink]
-hash = "sha1-ea18ab849f0eea030d770da82c2a6b3484a7bd13"
-other = "License information"
-
-[licenseLinkOther]
-hash = "sha1-359fff328717c05104e51a2d29f05bf1875d26b7"
-other = "Licenses from other products used in the program"
-
-[menuSettingsLanguage]
-hash = "sha1-ed3f0e507a5b4ed0649d7c768fe0d47413d839ba"
-other = "Language"
-
-[menuSettingsTheme]
-hash = "sha1-553c45f1b84a92b08dc1f088c13f924cde95765e"
-other = "Theme"
-
-[or]
-hash = "sha1-30bb0333ca1583110e4ced513b5d2455b86f529b"
-other = "or"
-
-[parameterCheckbox]
-hash = "sha1-9e35221d454870996fd51d576249cf47d1784a3c"
-other = "Enable option"
-
-[pathToFfmpeg]
-hash = "sha1-fafc50f1db0f720fe83a96cd70a9e1ad824e96b6"
-other = "Path to FFmpeg:"
-
-[pathToFfplay]
-hash = "sha1-5389830dd75a63aa8a5e41e8f07c5fadd8385398"
-other = "Path to FFplay:"
-
-[pathToFfprobe]
-hash = "sha1-b872edc9633a2e81ef678dc46fe46a7e91732024"
-other = "Path to FFprobe:"
-
-[preset_fast]
-hash = "sha1-935e1ac9d3c8ba4478326c909ba66662acb0540e"
-other = "fast (slower than \"faster\", but the file will weigh less)"
-
-[preset_faster]
-hash = "sha1-98620b73c896440c39ea6ec4b9b19d41301c9a7e"
-other = "faster (slower than \"veryfast\", but the file will weigh less)"
-
-[preset_medium]
-hash = "sha1-f7d1c30135c22c2f07c247075c0df103bb3c3ea5"
-other = "medium (slower than \"fast\", but the file will weigh less)"
-
-[preset_placebo]
-hash = "sha1-7bcff099104bb192881139e6404981bd426b3f91"
-other = "placebo (not recommended)"
-
-[preset_slow]
-hash = "sha1-681bf587275a45b48af49bb2ad8f0947919530e7"
-other = "slow (slower than \"medium\", but the file will weigh less)"
-
-[preset_slower]
-hash = "sha1-d1c692ee2b7643ae2c71a48bea880327a3c6b1e3"
-other = "slower (slower than \"slow\", but the file will weigh less)"
-
-[preset_superfast]
-hash = "sha1-41c39959e8f1547cc9259a5b459c4ccbf368cc23"
-other = "superfast (slower than \"ultrafast\", but the file will weigh less)"
-
-[preset_ultrafast]
-hash = "sha1-dfed981573ac2046832f9a9450bc9388958753fa"
-other = "ultrafast (fast, but the file will weigh a lot)"
-
-[preset_veryfast]
-hash = "sha1-370b82509887d02d7a2ef9b110df4616b16123ce"
-other = "veryfast (slower than \"superfast\", but the file will weigh less)"
-
-[preset_veryslow]
-hash = "sha1-d428bfa6deea9dd5c7c1f80ceba24e123ae96d0d"
-other = "veryslow (slower than \"slower\", but the file will weigh less)"
-
-[programmLink]
-hash = "sha1-18f9a3fad6aacefe1b05eed23122800b391ff5ca"
-other = "Project website"
-
-[programmVersion]
-hash = "sha1-fa2e4994a301bb24bc2a8fa166e5486ea95a7475"
-other = "**Program version:** {{.Version}}"
-
-[queue]
-hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8"
-other = "Queue"
-
-[save]
-hash = "sha1-4864057d626a868fa60f999bed3191d61d045ddc"
-other = "Save"
-
-[selectEncoder]
-hash = "sha1-88f3670b09758a3336057520a215058d61006abd"
-other = "Encoder:"
-
-[selectFFPathTitle]
-hash = "sha1-95581446a28d968ff1a027c623159a7eb08654cf"
-other = "Specify the path to FFmpeg and FFprobe"
-
-[selectFormat]
-hash = "sha1-f3809b0b48886570cd4cf1d7099de6da5b6d4524"
-other = "File extension:"
-
-[settings]
-hash = "sha1-7f17c7c62a7fd8d1a508481f4778688927734c2f"
-other = "Settings"
-
-[testFF]
-hash = "sha1-f5b8ed88e9609963035d2235be0a79bbec619976"
-other = "Checking FFmpeg for serviceability..."
-
-[themesNameDark]
-hash = "sha1-bd16b234708a2515a9f2d0ca41fb11e7fe8a38a2"
-other = "Dark"
-
-[themesNameDefault]
-hash = "sha1-469631cb165dcbbfea9e747056c25fbccb28c481"
-other = "Default"
-
-[themesNameLight]
-hash = "sha1-8080010c5e7d7edf56e89a99d8a2422898417845"
-other = "Light"
-
-[titleDownloadLink]
-hash = "sha1-92df86371f6c3a06ca1e4754f113142776a32d49"
-other = "You can download it from here"
-
-[total]
-hash = "sha1-3b5143902e0c5c84459aedf918e17604d9735b94"
-other = "Total"
-
-[unzipRun]
-hash = "sha1-c554dad13026668a1f6adf3171837c5d51bbac36"
-other = "Unpacked..."
-
-[waitingQueue]
-hash = "sha1-307429dd84150877080c4bbff2b340d1e7dadff2"
-other = "Waiting"
diff --git a/languages/active.kk.toml b/languages/active.kk.toml
deleted file mode 100644
index 2074652..0000000
--- a/languages/active.kk.toml
+++ /dev/null
@@ -1,571 +0,0 @@
-[AlsoUsedProgram]
-hash = "sha1-a72be72e7808bb8a0144ed7a93acb29c568b1ed4"
-other = "Бағдарлама сонымен қатар пайдаланады:"
-
-[about]
-hash = "sha1-3da0b9ef719fd707f443ac00404447f29445976f"
-other = "Бағдарлама туралы"
-
-[aboutText]
-hash = "sha1-8bd565814118ba8b90c40eb5b62acf8d2676e7d6"
-other = "FFmpeg консоль утилитасы үшін қарапайым интерфейс. \nБірақ мен FFmpeg утилитасының авторы емеспін."
-
-[addedFilesTitle]
-hash = "sha1-8ba0f6e477b0d78df2cc06f1d8b41b888623b851"
-other = "Қосылған файлдар"
-
-[autoClearAfterAddingToQueue]
-hash = "sha1-b3781695a4c35380d2cd075bb52f27a2a6d8f19c"
-other = "Кезекке қосқаннан кейін тазалаңыз"
-
-[buttonDownloadFFmpeg]
-hash = "sha1-c223c2e15171156192bc3146aee91e6094bb475b"
-other = "FFmpeg автоматты түрде жүктеп алыңыз"
-
-[buttonForSelectedDirTitle]
-hash = "sha1-8cbe5c67bcf89e4624635a79cbea104227faedda"
-other = "Қалтаға сақтаңыз:"
-
-[cancel]
-hash = "sha1-0ec753be8df955a117404fb634b01b45eb386e2a"
-other = "Болдырмау"
-
-[changeFFPath]
-hash = "sha1-1f704de0560f8135eb6924cd232ed919ca2e5af0"
-other = "FFmpeg, FFprobe және FFplay"
-
-[changeLanguage]
-hash = "sha1-8b276eaf378d485c769fb3d5dcc06dfc25b0c01b"
-other = "Тілді өзгерту"
-
-[checkboxOverwriteOutputFilesTitle]
-hash = "sha1-5860124bb781e7ef680f573fa93977e96328d4e7"
-other = "Файлды қайта жазуға рұқсат беріңіз"
-
-[choose]
-hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94"
-other = "таңдау"
-
-[clearAll]
-hash = "sha1-f32702d79ac206432400ac6b041695d020f6fa77"
-other = "Тізімді өшіру"
-
-[completedQueue]
-hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe"
-other = "Дайын"
-
-[converterVideoFilesSubmitTitle]
-hash = "sha1-7ac460f3c24c9952082f2db6e4d62f752598709c"
-other = "Файлды түрлендіру"
-
-[converterVideoFilesTitle]
-hash = "sha1-1ab29597cc9dfefab08e54ea5442e7ffa15f0394"
-other = "Бейне, аудио және суретті түрлендіргіш"
-
-[download]
-hash = "sha1-fe8f79f29da457de2f6bc9531de6e536e0c426ad"
-other = "Жүктеп алу"
-
-[downloadFFmpegFromSite]
-hash = "sha1-0889c95aa3a8659d8d903b4dab7097699c4d8aa4"
-other = "Сайттан жүктеледі:"
-
-[downloadRun]
-hash = "sha1-55f87f114628fa2d5d8e67d1e1cda22c0e4f9271"
-other = "Жүктеп алынуда..."
-
-[dragAndDropFiles]
-hash = "sha1-07bb747cc7590d7a51cdf96dff49a74139097766"
-other = "файлдарды сүйреп апарыңыз"
-
-[encoderGroupAudio]
-hash = "sha1-24321cb5400df96be8f3e2131918bebdb3a01bba"
-other = "Аудио"
-
-[encoderGroupImage]
-hash = "sha1-a7e528bc7ac9538aec87d1593c38b80be95d4745"
-other = "Суреттер"
-
-[encoderGroupVideo]
-hash = "sha1-8e7b9894c7ef0f57ac0bf910f6a8aac1c8a53683"
-other = "Бейне"
-
-[encoder_apng]
-hash = "sha1-1cbd9abfef96d5614a7e569161b41bd6ad87bbaf"
-other = "APNG image"
-
-[encoder_bmp]
-hash = "sha1-e0b9c16b016961a5abdc2217e8ffd1ba7ddebc40"
-other = "BMP image"
-
-[encoder_flv]
-hash = "sha1-3602bbf1cc90e48254f81975c7879b5fc0c4d602"
-other = "FLV"
-
-[encoder_gif]
-hash = "sha1-d092a779172291b5215aa095390a5b11659128a4"
-other = "GIF image"
-
-[encoder_h264_nvenc]
-hash = "sha1-169389f8c4a2518410159c363378ab5c978c32e5"
-other = "NVIDIA қолдауымен H.264"
-
-[encoder_libmp3lame]
-hash = "sha1-cd2c8d6f246c8bc18554b7105cb50b78d3cb2b98"
-other = "libmp3lame MP3 (MPEG audio layer 3)"
-
-[encoder_libshine]
-hash = "sha1-891d56c85857e5d83ef5a1fe077c1f1540788f49"
-other = "libshine MP3 (MPEG audio layer 3)"
-
-[encoder_libtwolame]
-hash = "sha1-b2f53be810b74edc3c454ac75de7ddecfee322ca"
-other = "libtwolame MP2 (MPEG audio layer 2)"
-
-[encoder_libvpx]
-hash = "sha1-b85c923aecfb48de0e87e71b6a21bfc2c547c70e"
-other = "libvpx VP8 (codec vp8)"
-
-[encoder_libvpx-vp9]
-hash = "sha1-3106417bd89bee87daa691e87614caf78cb934fe"
-other = "libvpx VP9 (codec vp9)"
-
-[encoder_libwebp]
-hash = "sha1-1d590d47d46f7880246061fce0e0de6d743db39e"
-other = "libwebp WebP image"
-
-[encoder_libwebp_anim]
-hash = "sha1-f141a9c8f23d79c13d44c30d8f34e05b363771ad"
-other = "libwebp_anim WebP image"
-
-[encoder_libx264]
-hash = "sha1-6d764ac459c0bf3c819d76618418cdfbb7a749eb"
-other = "H.264 libx264"
-
-[encoder_libx265]
-hash = "sha1-55544c166b1e15fd71a58096518e528109599eea"
-other = "H.265 libx265"
-
-[encoder_libxvid]
-hash = "sha1-d4bed46d6cdd2bfa8fd1689801164a83ab10c3f5"
-other = "libxvidcore MPEG-4 part 2"
-
-[encoder_mjpeg]
-hash = "sha1-94ba63a322b493a04da65e566781fe1cf8bb0d50"
-other = "MJPEG (Motion JPEG)"
-
-[encoder_mp2]
-hash = "sha1-a9154b7203349e5d6fbfd67d1ea97715f54b2065"
-other = "MP2 (MPEG audio layer 2)"
-
-[encoder_mp2fixed]
-hash = "sha1-dd2ee670d8bc8a60a96a717ebd26f16b5748cf3f"
-other = "MP2 fixed point (MPEG audio layer 2)"
-
-[encoder_mpeg1video]
-hash = "sha1-30043660719a3cb19dab5c33450665a8a9cc1c01"
-other = "MPEG-1"
-
-[encoder_mpeg2video]
-hash = "sha1-ccb2dcd8510cfdc9d52e5258af1863e5f2c51e77"
-other = "MPEG-2"
-
-[encoder_mpeg4]
-hash = "sha1-67fe42f18421b2f6c90fcdc579f9199bfca4b182"
-other = "MPEG-4 part 2"
-
-[encoder_msmpeg4]
-hash = "sha1-313ee597e4f0d9bd63a2bc6ac1618f028aef76f4"
-other = "MPEG-4 part 2 Microsoft variant version 3"
-
-[encoder_msmpeg4v2]
-hash = "sha1-adc442ce88f2717693b2da3010a1937d77ee522f"
-other = "MPEG-4 part 2 Microsoft variant version 2"
-
-[encoder_msvideo1]
-hash = "sha1-00f43ac0dc162bca10e0d98d6b70c0c6a902f66f"
-other = "Microsoft Video-1"
-
-[encoder_png]
-hash = "sha1-6715d4b82f5d9dfe3e53e30b402ffa1a6fbf30a5"
-other = "PNG image"
-
-[encoder_qtrle]
-hash = "sha1-31bf155cffaf6842ebc54084e4337ca08fdd9848"
-other = "QuickTime Animation (RLE) video"
-
-[encoder_sgi]
-hash = "sha1-f4510e237f7fc3c02caa728f9e500f4b069f9c11"
-other = "SGI image"
-
-[encoder_tiff]
-hash = "sha1-ed09d78c38e0b17ed695f35740c756dd7340eeac"
-other = "TIFF image"
-
-[encoder_wmav1]
-hash = "sha1-cd4a4c5eeac694b6699d55d0f9b477b3b50f18c7"
-other = "Windows Media Audio 1"
-
-[encoder_wmav2]
-hash = "sha1-eb2e5306cb33a702577ecfbdca0461862c66c053"
-other = "Windows Media Audio 2"
-
-[encoder_wmv1]
-hash = "sha1-f9b748554c590c36a56bcba2cd317196b7bdeddb"
-other = "Windows Media Video 7"
-
-[encoder_wmv2]
-hash = "sha1-5b21c87f5c6104797ead60b488b2948428f6b1b7"
-other = "Windows Media Video 8"
-
-[encoder_xbm]
-hash = "sha1-2dfc35881da62e9a1379d8238cf7839b24f79566"
-other = "XBM (X BitMap) image"
-
-[error]
-hash = "sha1-a7df8f8b5d754f226ac4cb320577fe692b33e483"
-other = "Қате орын алды!"
-
-[errorConverter]
-hash = "sha1-55ebddceddb8b044e33cc3893ec2eba7bbd9fcf9"
-other = "Бейнені түрлендіру мүмкін болмады"
-
-[errorDatabase]
-hash = "sha1-531abc3f0d12727e542df6e5a22de91098380fc1"
-other = "'data' қалтасында 'database' файлын жасау мүмкін болмады"
-
-[errorDatabaseTimeout]
-hash = "sha1-f8153516ac2442d19be4b6daccce839d204ff09f"
-other = "Конфигурация файлын аша алмады.\nБағдарламаның басқа көшірмесі іске қосылмағанына көз жеткізіңіз!"
-
-[errorDragAndDropFile]
-hash = "sha1-863cf1ad9c820d5b0c2006ceeaa29e25f81c1714"
-other = "Барлық файлдар қосылмаған"
-
-[errorFFmpeg]
-hash = "sha1-ccf0b95c0d1b392dc215258d917eb4e5d0b88ed0"
-other = "бұл FFmpeg емес"
-
-[errorFFmpegVersion]
-hash = "sha1-9a4148d42186b6b32cf83bef726e23022c53283f"
-other = "FFmpeg нұсқасын анықтау мүмкін болмады"
-
-[errorFFplay]
-hash = "sha1-988122112ac6002094e25518cfb5f0d606217298"
-other = "бұл FFplay емес"
-
-[errorFFplayVersion]
-hash = "sha1-cd60928d20d93210e103dd464306ab138bf1b184"
-other = "FFplay нұсқасын анықтау мүмкін болмады"
-
-[errorFFprobe]
-hash = "sha1-86d1b0b4c4ccd6a4f71e758fc67ce11aff4ba9b8"
-other = "бұл FFprobe емес"
-
-[errorFFprobeVersion]
-hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17"
-other = "FFprobe нұсқасын анықтау мүмкін болмады"
-
-[errorNoFilesAddedForConversion]
-hash = "sha1-5cf1f65bef15cb0382e56be98f44c6abde56a314"
-other = "Түрлендіруге арналған файлдар жоқ"
-
-[errorQueue]
-hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7"
-other = "Қате"
-
-[errorSelectedEncoder]
-hash = "sha1-33ed1aaf4cb3c2ee9d8f8c325b9b75d16ddf9979"
-other = "Түрлендіргіш таңдалмаған"
-
-[errorSelectedFolderSave]
-hash = "sha1-16f3ef93ee36813fdd79d8fb9bb7fc02acbb94a8"
-other = "Сақтау қалтасы таңдалмаған!"
-
-[errorSelectedFormat]
-hash = "sha1-cda92c56a1ef1aabc92bbfc405ede8ab13087e66"
-other = "Файл кеңейтімі таңдалмаған"
-
-[exit]
-hash = "sha1-c42457057d1ab7950cea00719cbe0b078891775f"
-other = "Шығу"
-
-[ffmpegLGPL]
-hash = "sha1-d395b16cc8f8eab98a8a970307c5b010ba22dde6"
-other = "Бұл бағдарламалық құрал **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)** астында **FFmpeg** жобасының кітапханаларын пайдаланады."
-
-[ffmpegTrademark]
-hash = "sha1-45f772b2eca5098cd6d31f2d1dc6edec1987a617"
-other = "FFmpeg — **[FFmpeg](https://ffmpeg.org/about.html)** жобасын жасаушы **[Fabrice Bellard](http://bellard.org/)** сауда белгісі."
-
-[fileForConversionTitle]
-hash = "sha1-96ac799e1086b31fd8f5f8d4c801829d6c853f08"
-other = "Файл:"
-
-[fileQueueTitle]
-hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8"
-other = "Кезек"
-
-[formPreset]
-hash = "sha1-7759891ba1ef9f7adc70defc7ac18fbf149c1a68"
-other = "Алдын ала орнатылған"
-
-[gratitude]
-hash = "sha1-51968fc38e53a9a11c861126c62404674fd6096f"
-other = "Алғыс"
-
-[gratitudeText]
-hash = "sha1-cb343e4d39ca31e6da6f72b9394cc915cb7d1258"
-other = "Сізге баға жетпес және уақтылы көмектескеніңіз\n\r үшін шын жүректен алғыс айтамын:"
-
-[help]
-hash = "sha1-6a45cef900c668effcb2ab10da05855c1fd10f6f"
-other = "Анықтама"
-
-[helpFFplay]
-hash = "sha1-ecc294b8b3d217ee1c2d63dc2f0253c3d1b3712c"
-other = "FFplay ойнатқышының пернелері"
-
-[helpFFplayActivateFrameStepMode]
-hash = "sha1-f47ede90932d69465f6197cb2a7cc4d1e3ab150e"
-other = "Уақыт аралығын іске қосыңыз."
-
-[helpFFplayCycleVideoFiltersOrShowModes]
-hash = "sha1-83bb702c777e4768cdc326a668d541c23ab759b7"
-other = "Бейне сүзгілерінің немесе дисплей режимдерінің циклі."
-
-[helpFFplayDecreaseVolume]
-hash = "sha1-de28db96a9c22be885ec5067a13f8f17fd3954bc"
-other = "Дыбыс деңгейін төмендетіңіз."
-
-[helpFFplayDescription]
-hash = "sha1-f5441f6aee76222c4120066575e80c2d177ac3c0"
-other = "Сипаттама"
-
-[helpFFplayDoubleClickLeftMouseButton]
-hash = "sha1-2657aa576055769952dfcde570fc9b4765d594ad"
-other = "тінтуірдің сол жақ\nбатырмасын екі рет басу"
-
-[helpFFplayIncreaseVolume]
-hash = "sha1-8ba7bde2d9a80f4a7cd122cf4973975698d3bd34"
-other = "Дыбыс деңгейін арттыру."
-
-[helpFFplayKeyDown]
-hash = "sha1-c5aefd2f8c6908a69b08fe4a2d235b1ae0113470"
-other = "төмен"
-
-[helpFFplayKeyHoldS]
-hash = "sha1-89c5dd8287c15b3f40db66e06b038c34a715f02f"
-other = "ұстау S"
-
-[helpFFplayKeyLeft]
-hash = "sha1-feb671890703fb0300a436744d34018bbc7ba13a"
-other = "сол"
-
-[helpFFplayKeyRight]
-hash = "sha1-a4f025d4bf7f90ee5bec6c48b2710bc9c5bbb267"
-other = "құқық"
-
-[helpFFplayKeySpace]
-hash = "sha1-a367ad00358ec44edc1d54a96df6f9114b0f8697"
-other = "SPACE (пробел)"
-
-[helpFFplayKeyUp]
-hash = "sha1-e4845aa8c0e100a80eaf65446c59085236fd2098"
-other = "жоғары"
-
-[helpFFplayKeys]
-hash = "sha1-0ad272ade8c568f394499f1492ecfab56e701e5d"
-other = "Кілттер"
-
-[helpFFplayPause]
-hash = "sha1-e83e107900fde0c39295f599c2cf8fba8d8cb604"
-other = "Кідіртіңіз немесе жоғалтуды жалғастырыңыз."
-
-[helpFFplayQuit]
-hash = "sha1-70785a2fd5d5a6519b7439f0d8cfcd7d54c5771d"
-other = "Ойнатқышты жабыңыз."
-
-[helpFFplaySeekBForward10Minutes]
-hash = "sha1-58ed63343376240f2596e447b5245c1805f35234"
-other = "10 минутқа алға айналдырыңыз."
-
-[helpFFplaySeekBForward1Minute]
-hash = "sha1-3fe46b8d5413b7fdc53ae9ed9427bcb1769ec74c"
-other = "1 минутқа алға айналдырыңыз."
-
-[helpFFplaySeekBackward10Minutes]
-hash = "sha1-927dffe9af72ffd40f46873b452a4c90627bccf8"
-other = "10 минутқа артқа айналдырыңыз."
-
-[helpFFplaySeekBackward10Seconds]
-hash = "sha1-e97615ecec0f8cf5647e8802bdda38dc2b0d809f"
-other = "10 секундқа артқа айналдырыңыз."
-
-[helpFFplaySeekBackward1Minute]
-hash = "sha1-5b19e280a0850122c8ebc80c622491bb09520e1a"
-other = "1 минутқа артқа айналдырыңыз."
-
-[helpFFplaySeekForward10Seconds]
-hash = "sha1-8d840251d4a1668edaea3515df197a8a79031ec3"
-other = "10 секунд алға айналдырыңыз."
-
-[helpFFplayToggleFullScreen]
-hash = "sha1-d32df02849258c5b02f15e5711f54ee6a8a75fd4"
-other = "Толық экранға ауысу немесе толық экраннан шығу."
-
-[helpFFplayToggleMute]
-hash = "sha1-4bdbb124fe8de3a8037c1e74719e9600b21b25ab"
-other = "Дыбысты өшіріңіз немесе дыбысты қосыңыз."
-
-[inProgressQueue]
-hash = "sha1-eff79c40e2100ae5fadf3a7d99336025edcca8b5"
-other = "Орындалуда"
-
-[languageSelectionFormHead]
-hash = "sha1-0ff5fa82cf684112660128cba1711297acf11003"
-other = "Тілді ауыстыру"
-
-[languageSelectionHead]
-hash = "sha1-daf1108fc10d3b1a908288d611f749b3cc651e4b"
-other = "Тілді таңдаңыз"
-
-[licenseLink]
-hash = "sha1-ea18ab849f0eea030d770da82c2a6b3484a7bd13"
-other = "Лицензия туралы ақпарат"
-
-[licenseLinkOther]
-hash = "sha1-359fff328717c05104e51a2d29f05bf1875d26b7"
-other = "Бағдарламада пайдаланылатын басқа өнімдердің лицензиялары"
-
-[menuSettingsLanguage]
-hash = "sha1-ed3f0e507a5b4ed0649d7c768fe0d47413d839ba"
-other = "Тіл"
-
-[menuSettingsTheme]
-hash = "sha1-553c45f1b84a92b08dc1f088c13f924cde95765e"
-other = "Тақырып"
-
-[or]
-hash = "sha1-30bb0333ca1583110e4ced513b5d2455b86f529b"
-other = "немесе"
-
-[parameterCheckbox]
-hash = "sha1-9e35221d454870996fd51d576249cf47d1784a3c"
-other = "Опцияны қосу"
-
-[pathToFfmpeg]
-hash = "sha1-fafc50f1db0f720fe83a96cd70a9e1ad824e96b6"
-other = "FFmpeg жол:"
-
-[pathToFfplay]
-hash = "sha1-5389830dd75a63aa8a5e41e8f07c5fadd8385398"
-other = "FFplay жол:"
-
-[pathToFfprobe]
-hash = "sha1-b872edc9633a2e81ef678dc46fe46a7e91732024"
-other = "FFprobe жол:"
-
-[preset_fast]
-hash = "sha1-935e1ac9d3c8ba4478326c909ba66662acb0540e"
-other = "fast («faster» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
-
-[preset_faster]
-hash = "sha1-98620b73c896440c39ea6ec4b9b19d41301c9a7e"
-other = "faster («veryfast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
-
-[preset_medium]
-hash = "sha1-f7d1c30135c22c2f07c247075c0df103bb3c3ea5"
-other = "medium («fast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
-
-[preset_placebo]
-hash = "sha1-7bcff099104bb192881139e6404981bd426b3f91"
-other = "placebo (ұсынылмайды)"
-
-[preset_slow]
-hash = "sha1-681bf587275a45b48af49bb2ad8f0947919530e7"
-other = "slow («medium» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
-
-[preset_slower]
-hash = "sha1-d1c692ee2b7643ae2c71a48bea880327a3c6b1e3"
-other = "slower («slow» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
-
-[preset_superfast]
-hash = "sha1-41c39959e8f1547cc9259a5b459c4ccbf368cc23"
-other = "superfast («ultrafast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
-
-[preset_ultrafast]
-hash = "sha1-dfed981573ac2046832f9a9450bc9388958753fa"
-other = "ultrafast (жылдам, бірақ файлдың салмағы көп болады)"
-
-[preset_veryfast]
-hash = "sha1-370b82509887d02d7a2ef9b110df4616b16123ce"
-other = "veryfast («superfast» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
-
-[preset_veryslow]
-hash = "sha1-d428bfa6deea9dd5c7c1f80ceba24e123ae96d0d"
-other = "veryslow («slower» қарағанда баяуырақ, бірақ файлдың салмағы аз болады)"
-
-[programmLink]
-hash = "sha1-18f9a3fad6aacefe1b05eed23122800b391ff5ca"
-other = "Жобаның веб-сайты"
-
-[programmVersion]
-hash = "sha1-fa2e4994a301bb24bc2a8fa166e5486ea95a7475"
-other = "**Бағдарлама нұсқасы:** {{.Version}}"
-
-[queue]
-hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8"
-other = "Кезек"
-
-[save]
-hash = "sha1-4864057d626a868fa60f999bed3191d61d045ddc"
-other = "Сақтау"
-
-[selectEncoder]
-hash = "sha1-88f3670b09758a3336057520a215058d61006abd"
-other = "Кодировщик:"
-
-[selectFFPathTitle]
-hash = "sha1-95581446a28d968ff1a027c623159a7eb08654cf"
-other = "FFmpeg және FFprobe жолын көрсетіңіз"
-
-[selectFormat]
-hash = "sha1-f3809b0b48886570cd4cf1d7099de6da5b6d4524"
-other = "Файл кеңейтімі:"
-
-[settings]
-hash = "sha1-7f17c7c62a7fd8d1a508481f4778688927734c2f"
-other = "Параметрлер"
-
-[testFF]
-hash = "sha1-f5b8ed88e9609963035d2235be0a79bbec619976"
-other = "FFmpeg функционалдығы тексерілуде..."
-
-[themesNameDark]
-hash = "sha1-bd16b234708a2515a9f2d0ca41fb11e7fe8a38a2"
-other = "Қараңғы тақырып"
-
-[themesNameDefault]
-hash = "sha1-469631cb165dcbbfea9e747056c25fbccb28c481"
-other = "Әдепкі бойынша"
-
-[themesNameLight]
-hash = "sha1-8080010c5e7d7edf56e89a99d8a2422898417845"
-other = "Жеңіл тақырып"
-
-[titleDownloadLink]
-hash = "sha1-92df86371f6c3a06ca1e4754f113142776a32d49"
-other = "Сіз оны осы жерден жүктей аласыз"
-
-[total]
-hash = "sha1-3b5143902e0c5c84459aedf918e17604d9735b94"
-other = "Барлығы"
-
-[unzipRun]
-hash = "sha1-c554dad13026668a1f6adf3171837c5d51bbac36"
-other = "Орамнан шығарылуда..."
-
-[waitingQueue]
-hash = "sha1-307429dd84150877080c4bbff2b340d1e7dadff2"
-other = "Күту"
diff --git a/languages/active.ru.toml b/languages/active.ru.toml
deleted file mode 100644
index 2383c00..0000000
--- a/languages/active.ru.toml
+++ /dev/null
@@ -1,143 +0,0 @@
-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 = "не смогли отконвертировать видео"
-errorDatabase = "не смогли создать файл 'database' в папке 'data'"
-errorDatabaseTimeout = "Не смогли открыть файл конфигурации.\nУбедитесь, что другая копия программы не запущена!"
-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 = "В очереди"
diff --git a/localizer/repository.go b/localizer/repository.go
deleted file mode 100644
index 46e36f2..0000000
--- a/localizer/repository.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package localizer
-
-import (
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting"
-)
-
-type RepositoryContract interface {
- GetCode() (string, error)
- Save(code string) (setting.Setting, error)
-}
-
-type Repository struct {
- settingRepository setting.RepositoryContract
-}
-
-func NewRepository(settingRepository setting.RepositoryContract) *Repository {
- return &Repository{settingRepository: settingRepository}
-}
-
-func (r Repository) GetCode() (string, error) {
- return r.settingRepository.GetValue("language")
-}
-
-func (r Repository) Save(code string) (setting.Setting, error) {
- return r.settingRepository.CreateOrUpdate("language", code)
-}
diff --git a/localizer/view.go b/localizer/view.go
deleted file mode 100644
index c0e5af6..0000000
--- a/localizer/view.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package localizer
-
-import (
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/widget"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "github.com/nicksnyder/go-i18n/v2/i18n"
-)
-
-type ViewContract interface {
- LanguageSelection(funcSelected func(lang kernel.Lang))
-}
-
-type View struct {
- app kernel.AppContract
-}
-
-func NewView(app kernel.AppContract) *View {
- return &View{
- app: app,
- }
-}
-
-func (v View) LanguageSelection(funcSelected func(lang kernel.Lang)) {
- languages := v.app.GetLocalizerService().GetLanguages()
- 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) {
- _ = v.app.GetLocalizerService().SetCurrentLanguage(languages[id])
- funcSelected(languages[id])
- }
-
- messageHead := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "languageSelectionHead",
- })
- v.app.GetWindow().SetContent(widget.NewCard(messageHead, "", listView))
-}
-
-func LanguageSelectionForm(localizerService kernel.LocalizerContract, funcSelected func(lang kernel.Lang)) fyne.CanvasObject {
- languages := localizerService.GetLanguages()
- currentLanguage := localizerService.GetCurrentLanguage()
- 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)
- if languages[i].Code == currentLanguage.Lang.Code {
- block.TextStyle = fyne.TextStyle{Bold: true}
- }
- })
- listView.OnSelected = func(id widget.ListItemID) {
- _ = localizerService.SetCurrentLanguage(languages[id])
- funcSelected(languages[id])
- }
-
- messageHead := localizerService.GetMessage(&i18n.LocalizeConfig{
- MessageID: "languageSelectionFormHead",
- })
- return widget.NewCard(messageHead, "", listView)
-}
diff --git a/main.go b/main.go
index 5f30405..41749c5 100644
--- a/main.go
+++ b/main.go
@@ -1,140 +1,36 @@
package main
import (
- "errors"
- "fyne.io/fyne/v2"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor"
- dberror "git.kor-elf.net/kor-elf/gui-for-ffmpeg/db"
- error2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/error"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/handler"
- "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/migration"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/theme"
- "go.etcd.io/bbolt"
- "golang.org/x/text/language"
- "os"
- "time"
+ "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/convertor"
+ "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"
)
-var application kernel.AppContract
-var ffPathUtilities *kernel.FFPathUtilities
-
-func init() {
- iconResource, _ := fyne.LoadResourceFromPath("icon.png")
- appMetadata := &fyne.AppMetadata{
- ID: "net.kor-elf.projects.gui-for-ffmpeg",
- Name: "GUI for FFmpeg",
- Version: "0.9.0",
- Icon: iconResource,
- }
-
- localizerService, err := kernel.NewLocalizer("languages", language.Russian)
- if err != nil {
- kernel.PanicErrorLang(err, appMetadata)
- return
- }
-
- ffPathUtilities = &kernel.FFPathUtilities{FFmpeg: "", FFprobe: "", FFplay: ""}
- convertorService := kernel.NewService(ffPathUtilities)
- ffplayService := kernel.NewFFplay(ffPathUtilities)
-
- queue := kernel.NewQueueList()
- application = kernel.NewApp(
- appMetadata,
- localizerService,
+func main() {
+ fyneApp := app.New()
+ appSetting := setting.NewSetting(fyneApp)
+ ffmpegService := ffmpeg.NewUtilities(appSetting)
+ progressBarService := convertor.NewProgressBar(ffmpegService)
+ convertorService := convertor.NewConvertor(ffmpegService)
+ itemsToConvert := convertor.NewItemsToConvert(ffmpegService)
+ queue := convertor.NewQueueList()
+ myApp := application.NewApp(
+ fyneApp,
+ appSetting,
+ progressBarService,
+ ffmpegService,
+ itemsToConvert,
queue,
- ffplayService,
convertorService,
)
-}
-
-func main() {
- errorView := error2.NewView(application)
- if canCreateFile("data/database.db") != true {
- errorView.PanicErrorWriteDirectoryData()
- application.GetWindow().ShowAndRun()
- return
- }
-
- db, err := bbolt.Open("data/database.db", 0600, &bbolt.Options{Timeout: 3 * time.Second})
- if err != nil {
- errorView.PanicError(err)
- application.GetWindow().ShowAndRun()
- return
- }
-
- defer db.Close()
-
- err = migration.Run(db)
- if err != nil {
- errorView.PanicError(err)
- application.GetWindow().ShowAndRun()
- return
- }
-
- settingRepository := setting.NewRepository(db)
- settingDirectoryForSaving := setting.NewSettingDirectoryForSaving(settingRepository)
-
- convertorRepository := convertor.NewRepository(settingRepository)
- pathFFmpeg, err := convertorRepository.GetPathFfmpeg()
- if err != nil && errors.Is(err, dberror.ErrRecordNotFound) == false {
- errorView.PanicError(err)
- application.GetWindow().ShowAndRun()
- return
- }
- ffPathUtilities.FFmpeg = pathFFmpeg
-
- pathFFprobe, err := convertorRepository.GetPathFfprobe()
- if err != nil && errors.Is(err, dberror.ErrRecordNotFound) == false {
- errorView.PanicError(err)
- application.GetWindow().ShowAndRun()
- return
- }
- ffPathUtilities.FFprobe = pathFFprobe
-
- pathFFplay, err := convertorRepository.GetPathFfplay()
- if err != nil && errors.Is(err, dberror.ErrRecordNotFound) == false {
- errorView.PanicError(err)
- application.GetWindow().ShowAndRun()
- return
- }
- ffPathUtilities.FFplay = pathFFplay
-
- 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)
-
- localizerRepository := localizer.NewRepository(settingRepository)
- menuView := menu.NewView(application)
- menuSettingView := menu.NewViewSetting(application, themeService)
- mainMenu := handler.NewMenuHandler(application, convertorHandler, menuView, menuSettingView, localizerView, localizerRepository, themeService)
-
- mainHandler := handler.NewMainHandler(application, convertorHandler, mainMenu, localizerRepository)
- mainHandler.Start()
-
- application.GetWindow().SetMainMenu(mainMenu.GetMainMenu())
- application.GetWindow().ShowAndRun()
-}
-
-func canCreateFile(path string) bool {
- file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0666)
- if err != nil {
- return false
- }
- _ = file.Close()
- return true
+ mainController := controller.NewController(myApp)
+ mainController.Start()
+
+ myApp.RunConvertor()
+ defer myApp.AfterClosing()
+
+ myApp.Run()
}
diff --git a/menu/view_setting.go b/menu/view_setting.go
deleted file mode 100644
index 045662e..0000000
--- a/menu/view_setting.go
+++ /dev/null
@@ -1,112 +0,0 @@
-package menu
-
-import (
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/canvas"
- "fyne.io/fyne/v2/widget"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/theme"
- "github.com/nicksnyder/go-i18n/v2/i18n"
- "image/color"
-)
-
-type ViewSettingContract interface {
- Main(
- save func(*SettingForm) error,
- cancel func(),
- )
-}
-
-type SettingForm struct {
- Language kernel.Lang
- ThemeInfo theme.ThemeInfoContract
-}
-
-type ViewSetting struct {
- app kernel.AppContract
- themeService theme.ThemeContract
-}
-
-func NewViewSetting(app kernel.AppContract, themeService theme.ThemeContract) *ViewSetting {
- return &ViewSetting{
- app: app,
- themeService: themeService,
- }
-}
-
-func (v ViewSetting) Main(save func(*SettingForm) error, cancel func()) {
- errorMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
- errorMessage.TextSize = 16
- errorMessage.TextStyle = fyne.TextStyle{Bold: true}
-
- viewSettingForm := &SettingForm{
- Language: v.app.GetLocalizerService().GetCurrentLanguage().Lang,
- ThemeInfo: v.themeService.GetCurrentThemeInfo(),
- }
-
- languageItems := []string{}
- langByTitle := map[string]kernel.Lang{}
- for _, language := range v.app.GetLocalizerService().GetLanguages() {
- languageItems = append(languageItems, language.Title)
- langByTitle[language.Title] = language
- }
- selectLanguage := widget.NewSelect(languageItems, func(s string) {
- if lang, ok := langByTitle[s]; ok {
- viewSettingForm.Language = lang
- }
- })
- selectLanguage.Selected = v.app.GetLocalizerService().GetCurrentLanguage().Lang.Title
-
- themeItems := []string{}
- themeByTitle := map[string]theme.ThemeInfoContract{}
- for _, themeInfo := range v.themeService.List() {
- themeItems = append(themeItems, themeInfo.GetTitle())
- themeByTitle[themeInfo.GetTitle()] = themeInfo
- }
- selectTheme := widget.NewSelect(themeItems, func(s string) {
- if themeInfo, ok := themeByTitle[s]; ok {
- viewSettingForm.ThemeInfo = themeInfo
- }
- })
- selectTheme.Selected = v.themeService.GetCurrentThemeInfo().GetTitle()
-
- form := &widget.Form{
- Items: []*widget.FormItem{
- {
- Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "menuSettingsLanguage",
- }),
- Widget: selectLanguage,
- },
- {
- Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "menuSettingsTheme",
- }),
- Widget: selectTheme,
- },
- {
- Widget: errorMessage,
- },
- },
- SubmitText: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "save",
- }),
- OnSubmit: func() {
- err := save(viewSettingForm)
- if err != nil {
- errorMessage.Text = err.Error()
- }
- },
- }
- if cancel != nil {
- form.OnCancel = cancel
- form.CancelText = v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "cancel",
- })
- }
-
- messageHead := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
- MessageID: "settings",
- })
- v.app.GetWindow().SetContent(widget.NewCard(messageHead, "", form))
-}
diff --git a/migration/migration.go b/migration/migration.go
deleted file mode 100644
index 39af7af..0000000
--- a/migration/migration.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package migration
-
-import (
- "go.etcd.io/bbolt"
-)
-
-func Run(db *bbolt.DB) error {
- return db.Update(func(tx *bbolt.Tx) error {
- _, err := tx.CreateBucketIfNotExists([]byte("settings"))
- return err
- })
-}
diff --git a/setting/directory_for_saving.go b/setting/directory_for_saving.go
deleted file mode 100644
index 706560a..0000000
--- a/setting/directory_for_saving.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package setting
-
-type DirectoryForSavingContract interface {
- GetDirectoryForSaving() (string, error)
- SaveDirectoryForSaving(path string) (Setting, error)
-}
-
-type DirectoryForSaving struct {
- settingRepository RepositoryContract
-}
-
-func NewSettingDirectoryForSaving(settingRepository RepositoryContract) *DirectoryForSaving {
- return &DirectoryForSaving{settingRepository: settingRepository}
-}
-
-func (setting DirectoryForSaving) GetDirectoryForSaving() (string, error) {
- return setting.settingRepository.GetValue("directoryForSaving")
-}
-
-func (setting DirectoryForSaving) SaveDirectoryForSaving(path string) (Setting, error) {
- return setting.settingRepository.CreateOrUpdate("directoryForSaving", path)
-}
diff --git a/setting/entity.go b/setting/entity.go
deleted file mode 100644
index e3c18f3..0000000
--- a/setting/entity.go
+++ /dev/null
@@ -1,6 +0,0 @@
-package setting
-
-type Setting struct {
- Code string `json:"code"`
- Value string `json:"value"`
-}
diff --git a/setting/repository.go b/setting/repository.go
deleted file mode 100644
index 9f2f671..0000000
--- a/setting/repository.go
+++ /dev/null
@@ -1,82 +0,0 @@
-package setting
-
-import (
- "encoding/json"
- "errors"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/db"
- "go.etcd.io/bbolt"
-)
-
-type RepositoryContract interface {
- Create(setting Setting) (Setting, error)
- CreateOrUpdate(code string, value string) (Setting, error)
- GetValue(code string) (value string, err error)
-}
-
-type Repository struct {
- db *bbolt.DB
-}
-
-func NewRepository(db *bbolt.DB) *Repository {
- return &Repository{db}
-}
-
-func (r Repository) GetValue(code string) (value string, err error) {
- var setting Setting
-
- err = r.db.View(func(tx *bbolt.Tx) error {
- b := tx.Bucket([]byte("settings"))
- if b == nil {
- return errors.New("bucket 'settings' not found")
- }
- val := b.Get([]byte(code))
- if val == nil {
- return db.ErrRecordNotFound
- }
- return json.Unmarshal(val, &setting)
- })
- if err != nil {
- return "", err
- }
-
- return setting.Value, nil
-
-}
-
-func (r Repository) Create(setting Setting) (Setting, error) {
- err := r.db.Update(func(tx *bbolt.Tx) error {
- b := tx.Bucket([]byte("settings"))
- if b == nil {
- return errors.New("bucket 'settings' not found")
- }
-
- data, err := json.Marshal(setting)
- if err != nil {
- return err
- }
-
- return b.Put([]byte(setting.Code), data)
- })
- return setting, err
-}
-
-func (r Repository) CreateOrUpdate(code string, value string) (Setting, error) {
- var setting Setting
- setting.Code = code
- setting.Value = value
-
- err := r.db.Update(func(tx *bbolt.Tx) error {
- b := tx.Bucket([]byte("settings"))
- if b == nil {
- return errors.New("bucket 'settings' not found")
- }
-
- data, err := json.Marshal(setting)
- if err != nil {
- return err
- }
-
- return b.Put([]byte(code), data)
- })
- return setting, err
-}
diff --git a/theme/repository.go b/theme/repository.go
deleted file mode 100644
index 91b2351..0000000
--- a/theme/repository.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package theme
-
-import "git.kor-elf.net/kor-elf/gui-for-ffmpeg/setting"
-
-type RepositoryContract interface {
- GetCode() string
- Save(code string) (setting.Setting, error)
-}
-
-type Repository struct {
- settingRepository setting.RepositoryContract
-}
-
-func NewRepository(settingRepository setting.RepositoryContract) *Repository {
- return &Repository{settingRepository: settingRepository}
-}
-
-func (r Repository) GetCode() string {
- name, err := r.settingRepository.GetValue("theme")
- if err != nil {
- return "default"
- }
- return name
-}
-
-func (r Repository) Save(code string) (setting.Setting, error) {
- return r.settingRepository.CreateOrUpdate("theme", code)
-}
diff --git a/theme/theme.go b/theme/theme.go
deleted file mode 100644
index ba0dfa0..0000000
--- a/theme/theme.go
+++ /dev/null
@@ -1,158 +0,0 @@
-package theme
-
-import (
- "fyne.io/fyne/v2"
- fyneTheme "fyne.io/fyne/v2/theme"
- "git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
- "github.com/nicksnyder/go-i18n/v2/i18n"
- "image/color"
-)
-
-type ThemeContract interface {
- List() map[string]ThemeInfoContract
- GetCurrentThemeInfo() ThemeInfoContract
- SetCurrentTheme(themeInfo ThemeInfoContract) error
-}
-
-type theme struct {
- app kernel.AppContract
- repository RepositoryContract
- list map[string]ThemeInfoContract
-}
-
-func NewTheme(app kernel.AppContract, repository RepositoryContract) ThemeContract {
- theme := &theme{
- app: app,
- repository: repository,
- list: getThemes(app.GetLocalizerService()),
- }
-
- theme.init()
-
- return theme
-}
-
-func (t theme) init() {
- themeInfo := t.GetCurrentThemeInfo()
- if themeInfo.GetName() == "default" {
- t.app.GetAppFyne().Settings().SetTheme(fyneTheme.DefaultTheme())
- return
- }
- t.app.GetAppFyne().Settings().SetTheme(&forcedVariant{theme: fyneTheme.DefaultTheme(), variant: themeInfo.GetVariant()})
-}
-
-func (t theme) GetCurrentThemeInfo() ThemeInfoContract {
- themes := t.List()
- if themeInfo, ok := themes[t.repository.GetCode()]; ok {
- return themeInfo
- }
-
- return themes["default"]
-}
-
-func (t theme) List() map[string]ThemeInfoContract {
- return t.list
-}
-
-func (t theme) SetCurrentTheme(themeInfo ThemeInfoContract) error {
- _, err := t.repository.Save(themeInfo.GetName())
- if err != nil {
- return err
- }
-
- if themeInfo.GetName() == "default" {
- t.app.GetAppFyne().Settings().SetTheme(fyneTheme.DefaultTheme())
- return nil
- }
- t.app.GetAppFyne().Settings().SetTheme(&forcedVariant{theme: fyneTheme.DefaultTheme(), variant: themeInfo.GetVariant()})
-
- return nil
-}
-
-type ThemeInfoContract interface {
- GetName() string
- GetTitle() string
- GetVariant() fyne.ThemeVariant
-}
-
-type themeInfo struct {
- name string
- title string
- variant fyne.ThemeVariant
-}
-
-func (inf themeInfo) GetName() string {
- return inf.name
-}
-
-func (inf themeInfo) GetTitle() string {
- return inf.title
-}
-
-func (inf themeInfo) GetVariant() fyne.ThemeVariant {
- return inf.variant
-}
-
-func getThemes(localizer kernel.LocalizerContract) map[string]ThemeInfoContract {
- themesNameDefault := &themeInfo{
- name: "default",
- title: localizer.GetMessage(&i18n.LocalizeConfig{
- MessageID: "themesNameDefault",
- }),
- }
-
- themesNameLight := &themeInfo{
- name: "light",
- title: localizer.GetMessage(&i18n.LocalizeConfig{
- MessageID: "themesNameLight",
- }),
- variant: fyneTheme.VariantLight,
- }
-
- themesNameDark := &themeInfo{
- name: "dark",
- title: localizer.GetMessage(&i18n.LocalizeConfig{
- MessageID: "themesNameDark",
- }),
- variant: fyneTheme.VariantDark,
- }
-
- list := map[string]ThemeInfoContract{
- "default": themesNameDefault,
- "light": themesNameLight,
- "dark": themesNameDark,
- }
-
- localizer.AddChangeCallback("themesNameDefault", func(text string) {
- themesNameDefault.title = text
- })
- localizer.AddChangeCallback("themesNameLight", func(text string) {
- themesNameLight.title = text
- })
- localizer.AddChangeCallback("themesNameDark", func(text string) {
- themesNameDark.title = text
- })
-
- return list
-}
-
-type forcedVariant struct {
- theme fyne.Theme
- variant fyne.ThemeVariant
-}
-
-func (f *forcedVariant) Color(name fyne.ThemeColorName, _ fyne.ThemeVariant) color.Color {
- return f.theme.Color(name, f.variant)
-}
-
-func (f *forcedVariant) Font(style fyne.TextStyle) fyne.Resource {
- return fyneTheme.DefaultTheme().Font(style)
-}
-
-func (f *forcedVariant) Icon(name fyne.ThemeIconName) fyne.Resource {
- return fyneTheme.DefaultTheme().Icon(name)
-}
-
-func (f *forcedVariant) Size(name fyne.ThemeSizeName) float32 {
- return fyneTheme.DefaultTheme().Size(name)
-}