Make a choice of the encoder in the form

Made a choice of the encoder by categories: video, audio and photo.
This commit is contained in:
Leonid Nikitin 2025-06-08 17:26:49 +05:00
parent 9cdfa18fc8
commit 9bb835beaf
Signed by: kor-elf
GPG Key ID: DAB5355A11C22541
7 changed files with 322 additions and 23 deletions

View File

@ -7,11 +7,18 @@ import (
)
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.window.SetContent(content)
}

View File

@ -1,17 +1,18 @@
package view
import (
"errors"
"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"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
"image/color"
"os"
"path/filepath"
@ -22,12 +23,14 @@ func Convertor(
addFileForConversion func(file ffmpeg.File),
directoryForSavingPath string,
directoryForSaving func(path string),
formats encoder.ConvertorFormatsContract,
) fyne.CanvasObject {
form := newFormConvertor(
window,
addFileForConversion,
directoryForSavingPath,
directoryForSaving,
formats,
)
converterVideoFilesTitle := lang.L("converterVideoFilesTitle")
@ -48,6 +51,7 @@ func newFormConvertor(
addFileForConversion func(file ffmpeg.File),
directoryForSavingPath string,
directoryForSaving func(path string),
formats encoder.ConvertorFormatsContract,
) *formConvertor {
f := widget.NewForm()
f.SubmitText = lang.L("converterVideoFilesSubmitTitle")
@ -61,6 +65,12 @@ func newFormConvertor(
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{
{
@ -78,9 +88,25 @@ func newFormConvertor(
{
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)
return formConvertor
}
@ -92,17 +118,13 @@ func (f *formConvertor) getForm() *widget.Form {
type fileForConversion struct {
button *widget.Button
message *canvas.Text
file *kernel.File
changeCallbacks map[int]func(err error)
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,
changeCallbacks: map[int]func(err error){},
}
buttonTitle := lang.L("choose") + "\n" +
@ -123,7 +145,6 @@ func (f *formConvertor) newFileForConversion() *fileForConversion {
fileForConversion.message.Text = err.Error()
fileForConversion.message.Refresh()
})
fileForConversion.eventSelectFile(err)
return
}
if r == nil {
@ -136,8 +157,6 @@ func (f *formConvertor) newFileForConversion() *fileForConversion {
Ext: r.URI().Extension(),
})
fileForConversion.eventSelectFile(nil)
listableURI := storage.NewFileURI(filepath.Dir(r.URI().Path()))
locationURI, _ = storage.ListerForURI(listableURI)
}, locationURI)
@ -166,8 +185,6 @@ func (f *formConvertor) newFileForConversion() *fileForConversion {
Ext: uri.Extension(),
})
fileForConversion.eventSelectFile(nil)
listableURI := storage.NewFileURI(filepath.Dir(uri.Path()))
locationURI, _ = storage.ListerForURI(listableURI)
}
@ -175,7 +192,6 @@ func (f *formConvertor) newFileForConversion() *fileForConversion {
if isError {
fileForConversion.message.Text = lang.L("errorDragAndDropFile")
utils.SetStringErrorStyle(fileForConversion.message)
fileForConversion.eventSelectFile(errors.New(fileForConversion.message.Text))
} else {
fyne.Do(func() {
fileForConversion.message.Text = ""
@ -238,12 +254,98 @@ func (f *formConvertor) newDirectoryForSaving(directoryForSavingPath string) *di
return directoryForSaving
}
func (c *fileForConversion) addChangeCallback(callback func(err error)) {
c.changeCallbacks[len(c.changeCallbacks)] = callback
type selectEncoder struct {
SelectFileType *widget.RadioGroup
SelectFormat *widget.Select
SelectEncoder *widget.Select
Encoder encoder2.EncoderContract
}
func (c *fileForConversion) eventSelectFile(err error) {
for _, changeCallback := range c.changeCallbacks {
changeCallback(err)
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()
f.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()
})
}

View File

@ -0,0 +1,64 @@
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/internal/ffmpeg/encoder"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/h264_nvenc"
)
func View(encoder encoder.EncoderContract) []*widget.FormItem {
items := []*widget.FormItem{}
items = append(items, presetParameter(encoder)...)
return items
}
func presetParameter(encoder encoder.EncoderContract) []*widget.FormItem {
parameter, err := encoder.GetParameter("preset")
if err != nil {
return nil
}
presets := map[string]string{}
presetsForSelect := []string{}
presetDefault := ""
for _, name := range h264_nvenc.Presets {
title := name
presetsForSelect = append(presetsForSelect, name)
presets[title] = name
if name == parameter.Get() {
presetDefault = title
}
}
elementSelect := widget.NewSelect(presetsForSelect, func(s string) {
if presets[s] == "" {
return
}
parameter.Set(presets[s])
})
elementSelect.SetSelected(presetDefault)
elementSelect.Hide()
checkboxTitle := lang.L("parameterCheckbox")
elementCheckbox := widget.NewCheck(checkboxTitle, func(b bool) {
if b == true {
parameter.SetEnable()
elementSelect.Show()
return
}
parameter.SetDisable()
elementSelect.Hide()
})
return []*widget.FormItem{
{
Text: lang.L("formPreset"),
Widget: container.NewVBox(elementCheckbox, elementSelect),
},
}
}

View File

@ -0,0 +1,64 @@
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/internal/ffmpeg/encoder"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libx264"
)
func View(encoder encoder.EncoderContract) []*widget.FormItem {
items := []*widget.FormItem{}
items = append(items, presetParameter(encoder)...)
return items
}
func presetParameter(encoder encoder.EncoderContract) []*widget.FormItem {
parameter, err := encoder.GetParameter("preset")
if err != nil {
return nil
}
presets := map[string]string{}
presetsForSelect := []string{}
presetDefault := ""
for _, name := range libx264.Presets {
title := lang.L("preset_" + name)
presetsForSelect = append(presetsForSelect, title)
presets[title] = name
if name == parameter.Get() {
presetDefault = title
}
}
elementSelect := widget.NewSelect(presetsForSelect, func(s string) {
if presets[s] == "" {
return
}
parameter.Set(presets[s])
})
elementSelect.SetSelected(presetDefault)
elementSelect.Hide()
checkboxTitle := lang.L("parameterCheckbox")
elementCheckbox := widget.NewCheck(checkboxTitle, func(b bool) {
if b == true {
parameter.SetEnable()
elementSelect.Show()
return
}
parameter.SetDisable()
elementSelect.Hide()
})
return []*widget.FormItem{
{
Text: lang.L("formPreset"),
Widget: container.NewVBox(elementCheckbox, elementSelect),
},
}
}

View File

@ -0,0 +1,64 @@
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/internal/ffmpeg/encoder"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder/libx265"
)
func View(encoder encoder.EncoderContract) []*widget.FormItem {
items := []*widget.FormItem{}
items = append(items, presetParameter(encoder)...)
return items
}
func presetParameter(encoder encoder.EncoderContract) []*widget.FormItem {
parameter, err := encoder.GetParameter("preset")
if err != nil {
return nil
}
presets := map[string]string{}
presetsForSelect := []string{}
presetDefault := ""
for _, name := range libx265.Presets {
title := lang.L("preset_" + name)
presetsForSelect = append(presetsForSelect, title)
presets[title] = name
if name == parameter.Get() {
presetDefault = title
}
}
elementSelect := widget.NewSelect(presetsForSelect, func(s string) {
if presets[s] == "" {
return
}
parameter.Set(presets[s])
})
elementSelect.SetSelected(presetDefault)
elementSelect.Hide()
checkboxTitle := lang.L("parameterCheckbox")
elementCheckbox := widget.NewCheck(checkboxTitle, func(b bool) {
if b == true {
parameter.SetEnable()
elementSelect.Show()
return
}
parameter.SetDisable()
elementSelect.Hide()
})
return []*widget.FormItem{
{
Text: lang.L("formPreset"),
Widget: container.NewVBox(elementCheckbox, elementSelect),
},
}
}

View File

@ -7,7 +7,6 @@ import (
"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"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/application/convertor"
)
@ -21,7 +20,7 @@ type layout struct {
rContainer RightMainContainerContract
}
func NewLayout(progressBarService application.ProgressBarContract, itemsToConvert convertor.ItemsToConvertContract, queueLayout QueueLayoutContract) LayoutContract {
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())

View File

@ -3,7 +3,6 @@ package window
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/dialog"
"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/utils"
)
@ -22,13 +21,13 @@ type mainWindow struct {
fyneWindow fyne.Window
layout LayoutContract
itemsToConvert convertor.ItemsToConvertContract
progressBarService application.ProgressBarContract
progressBarService convertor.ProgressBarContract
queueLayout QueueLayoutContract
}
func NewMainWindow(
fyneWindow fyne.Window,
progressBarService application.ProgressBarContract,
progressBarService convertor.ProgressBarContract,
itemsToConvert convertor.ItemsToConvertContract,
queueLayout QueueLayoutContract,
) WindowContract {