2024-01-14 16:31:07 +06:00
|
|
|
package convertor
|
|
|
|
|
|
|
|
import (
|
2024-01-18 20:23:23 +06:00
|
|
|
"errors"
|
2024-01-14 16:31:07 +06:00
|
|
|
"fyne.io/fyne/v2"
|
|
|
|
"fyne.io/fyne/v2/canvas"
|
|
|
|
"fyne.io/fyne/v2/container"
|
2024-02-10 20:11:26 +06:00
|
|
|
"fyne.io/fyne/v2/storage"
|
2024-01-14 16:31:07 +06:00
|
|
|
"fyne.io/fyne/v2/widget"
|
2024-03-07 22:18:35 +05:00
|
|
|
encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
|
2024-02-17 19:08:58 +06:00
|
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
|
2024-03-07 22:18:35 +05:00
|
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel/encoder"
|
2024-01-28 22:01:16 +06:00
|
|
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
2024-01-14 16:31:07 +06:00
|
|
|
"image/color"
|
2024-02-10 20:11:26 +06:00
|
|
|
"path/filepath"
|
2024-01-14 16:31:07 +06:00
|
|
|
)
|
|
|
|
|
|
|
|
type ViewContract interface {
|
|
|
|
Main(
|
2024-02-17 19:08:58 +06:00
|
|
|
runConvert func(setting HandleConvertSetting),
|
2024-03-07 22:18:35 +05:00
|
|
|
formats encoder.ConvertorFormatsContract,
|
2024-01-14 16:31:07 +06:00
|
|
|
)
|
2024-01-31 21:02:12 +06:00
|
|
|
SelectFFPath(
|
2024-02-01 00:23:28 +06:00
|
|
|
ffmpegPath string,
|
|
|
|
ffprobePath string,
|
|
|
|
save func(ffmpegPath string, ffprobePath string) error,
|
|
|
|
cancel func(),
|
2024-02-04 20:16:15 +06:00
|
|
|
donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error,
|
2024-01-31 21:02:12 +06:00
|
|
|
)
|
2024-01-14 16:31:07 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
type View struct {
|
2024-02-17 19:08:58 +06:00
|
|
|
app kernel.AppContract
|
2024-01-14 16:31:07 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
type HandleConvertSetting struct {
|
2024-02-17 19:08:58 +06:00
|
|
|
VideoFileInput kernel.File
|
2024-01-18 20:23:23 +06:00
|
|
|
DirectoryForSave string
|
|
|
|
OverwriteOutputFiles bool
|
2024-03-07 22:18:35 +05:00
|
|
|
Format string
|
|
|
|
Encoder encoder2.EncoderContract
|
2024-01-14 16:31:07 +06:00
|
|
|
}
|
|
|
|
|
2024-01-15 20:28:02 +06:00
|
|
|
type enableFormConversionStruct struct {
|
|
|
|
fileVideoForConversion *widget.Button
|
2024-01-18 20:23:23 +06:00
|
|
|
buttonForSelectedDir *widget.Button
|
2024-01-15 20:28:02 +06:00
|
|
|
form *widget.Form
|
|
|
|
}
|
|
|
|
|
2024-02-17 19:08:58 +06:00
|
|
|
func NewView(app kernel.AppContract) *View {
|
2024-01-28 22:01:16 +06:00
|
|
|
return &View{
|
2024-02-17 19:08:58 +06:00
|
|
|
app: app,
|
2024-01-28 22:01:16 +06:00
|
|
|
}
|
2024-01-14 16:31:07 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v View) Main(
|
2024-02-17 19:08:58 +06:00
|
|
|
runConvert func(setting HandleConvertSetting),
|
2024-03-07 22:18:35 +05:00
|
|
|
formats encoder.ConvertorFormatsContract,
|
2024-01-14 16:31:07 +06:00
|
|
|
) {
|
2024-01-15 20:28:02 +06:00
|
|
|
form := &widget.Form{}
|
2024-01-14 16:31:07 +06:00
|
|
|
|
2024-02-01 00:28:06 +06:00
|
|
|
conversionMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
|
2024-01-14 16:31:07 +06:00
|
|
|
conversionMessage.TextSize = 16
|
|
|
|
conversionMessage.TextStyle = fyne.TextStyle{Bold: true}
|
|
|
|
|
2024-02-17 19:08:58 +06:00
|
|
|
fileVideoForConversion, fileVideoForConversionMessage, fileInput := v.getButtonFileVideoForConversion(form, conversionMessage)
|
2024-01-18 20:23:23 +06:00
|
|
|
buttonForSelectedDir, buttonForSelectedDirMessage, pathToSaveDirectory := v.getButtonForSelectingDirectoryForSaving()
|
|
|
|
|
|
|
|
isOverwriteOutputFiles := false
|
2024-02-17 19:08:58 +06:00
|
|
|
checkboxOverwriteOutputFilesTitle := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
2024-01-28 22:01:16 +06:00
|
|
|
MessageID: "checkboxOverwriteOutputFilesTitle",
|
|
|
|
})
|
|
|
|
checkboxOverwriteOutputFiles := widget.NewCheck(checkboxOverwriteOutputFilesTitle, func(b bool) {
|
2024-01-18 20:23:23 +06:00
|
|
|
isOverwriteOutputFiles = b
|
|
|
|
})
|
2024-01-15 20:28:02 +06:00
|
|
|
|
2024-03-07 22:18:35 +05:00
|
|
|
selectEncoder := v.getSelectFormat(formats)
|
|
|
|
|
2024-01-15 20:28:02 +06:00
|
|
|
form.Items = []*widget.FormItem{
|
2024-01-28 22:01:16 +06:00
|
|
|
{
|
2024-03-07 22:18:35 +05:00
|
|
|
Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "fileForConversionTitle"}),
|
2024-01-28 22:01:16 +06:00
|
|
|
Widget: fileVideoForConversion,
|
|
|
|
},
|
|
|
|
{
|
2024-02-10 20:11:26 +06:00
|
|
|
Widget: container.NewHScroll(fileVideoForConversionMessage),
|
2024-01-28 22:01:16 +06:00
|
|
|
},
|
|
|
|
{
|
2024-02-17 19:08:58 +06:00
|
|
|
Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "buttonForSelectedDirTitle"}),
|
2024-01-28 22:01:16 +06:00
|
|
|
Widget: buttonForSelectedDir,
|
|
|
|
},
|
|
|
|
{
|
2024-02-10 20:11:26 +06:00
|
|
|
Widget: container.NewHScroll(buttonForSelectedDirMessage),
|
2024-01-28 22:01:16 +06:00
|
|
|
},
|
|
|
|
{
|
|
|
|
Widget: checkboxOverwriteOutputFiles,
|
|
|
|
},
|
2024-03-07 22:18:35 +05:00
|
|
|
{
|
|
|
|
Widget: selectEncoder.SelectFileType,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "selectFormat"}),
|
|
|
|
Widget: selectEncoder.SelectFormat,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{MessageID: "selectEncoder"}),
|
|
|
|
Widget: selectEncoder.SelectEncoder,
|
|
|
|
},
|
2024-01-15 20:28:02 +06:00
|
|
|
}
|
2024-02-17 19:08:58 +06:00
|
|
|
form.SubmitText = v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
2024-01-28 22:01:16 +06:00
|
|
|
MessageID: "converterVideoFilesSubmitTitle",
|
|
|
|
})
|
2024-01-15 20:28:02 +06:00
|
|
|
|
|
|
|
enableFormConversionStruct := enableFormConversionStruct{
|
|
|
|
fileVideoForConversion: fileVideoForConversion,
|
2024-01-18 20:23:23 +06:00
|
|
|
buttonForSelectedDir: buttonForSelectedDir,
|
2024-01-15 20:28:02 +06:00
|
|
|
form: form,
|
|
|
|
}
|
|
|
|
|
|
|
|
form.OnSubmit = func() {
|
2024-01-18 20:23:23 +06:00
|
|
|
if len(*pathToSaveDirectory) == 0 {
|
2024-02-17 19:08:58 +06:00
|
|
|
showConversionMessage(conversionMessage, errors.New(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
2024-01-28 22:01:16 +06:00
|
|
|
MessageID: "errorSelectedFolderSave",
|
|
|
|
})))
|
2024-01-18 20:23:23 +06:00
|
|
|
enableFormConversion(enableFormConversionStruct)
|
|
|
|
return
|
|
|
|
}
|
2024-03-07 22:18:35 +05:00
|
|
|
if len(selectEncoder.SelectFormat.Selected) == 0 {
|
|
|
|
showConversionMessage(conversionMessage, errors.New(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
|
|
|
MessageID: "errorSelectedFormat",
|
|
|
|
})))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if selectEncoder.Encoder == nil {
|
|
|
|
showConversionMessage(conversionMessage, errors.New(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
|
|
|
MessageID: "errorSelectedEncoder",
|
|
|
|
})))
|
|
|
|
return
|
|
|
|
}
|
2024-01-18 20:23:23 +06:00
|
|
|
conversionMessage.Text = ""
|
|
|
|
|
2024-01-15 20:28:02 +06:00
|
|
|
fileVideoForConversion.Disable()
|
2024-01-18 20:23:23 +06:00
|
|
|
buttonForSelectedDir.Disable()
|
2024-01-15 20:28:02 +06:00
|
|
|
form.Disable()
|
|
|
|
|
|
|
|
setting := HandleConvertSetting{
|
2024-02-17 19:08:58 +06:00
|
|
|
VideoFileInput: *fileInput,
|
2024-01-18 20:23:23 +06:00
|
|
|
DirectoryForSave: *pathToSaveDirectory,
|
|
|
|
OverwriteOutputFiles: isOverwriteOutputFiles,
|
2024-03-07 22:18:35 +05:00
|
|
|
Format: selectEncoder.SelectFormat.Selected,
|
|
|
|
Encoder: selectEncoder.Encoder,
|
2024-01-15 20:28:02 +06:00
|
|
|
}
|
2024-02-17 19:08:58 +06:00
|
|
|
runConvert(setting)
|
2024-01-15 20:28:02 +06:00
|
|
|
enableFormConversion(enableFormConversionStruct)
|
2024-02-17 19:08:58 +06:00
|
|
|
|
|
|
|
fileVideoForConversionMessage.Text = ""
|
|
|
|
form.Disable()
|
2024-01-15 20:28:02 +06:00
|
|
|
}
|
|
|
|
|
2024-02-17 19:08:58 +06:00
|
|
|
converterVideoFilesTitle := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
2024-01-28 22:01:16 +06:00
|
|
|
MessageID: "converterVideoFilesTitle",
|
|
|
|
})
|
2024-02-17 19:08:58 +06:00
|
|
|
v.app.GetWindow().SetContent(widget.NewCard(converterVideoFilesTitle, "", container.NewVBox(form, conversionMessage)))
|
2024-01-15 20:28:02 +06:00
|
|
|
form.Disable()
|
|
|
|
}
|
|
|
|
|
2024-02-17 19:08:58 +06:00
|
|
|
func (v View) getButtonFileVideoForConversion(form *widget.Form, conversionMessage *canvas.Text) (*widget.Button, *canvas.Text, *kernel.File) {
|
|
|
|
fileInput := &kernel.File{}
|
2024-01-15 20:28:02 +06:00
|
|
|
|
2024-02-01 00:28:06 +06:00
|
|
|
fileVideoForConversionMessage := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
|
2024-01-15 20:28:02 +06:00
|
|
|
fileVideoForConversionMessage.TextSize = 16
|
|
|
|
fileVideoForConversionMessage.TextStyle = fyne.TextStyle{Bold: true}
|
|
|
|
|
2024-02-17 19:08:58 +06:00
|
|
|
buttonTitle := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
2024-01-28 22:01:16 +06:00
|
|
|
MessageID: "choose",
|
|
|
|
})
|
|
|
|
|
2024-02-10 20:11:26 +06:00
|
|
|
var locationURI fyne.ListableURI
|
|
|
|
|
2024-01-28 22:01:16 +06:00
|
|
|
button := widget.NewButton(buttonTitle, func() {
|
2024-02-17 19:08:58 +06:00
|
|
|
v.app.GetWindow().NewFileOpen(func(r fyne.URIReadCloser, err error) {
|
|
|
|
if err != nil {
|
|
|
|
fileVideoForConversionMessage.Text = err.Error()
|
|
|
|
setStringErrorStyle(fileVideoForConversionMessage)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if r == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
fileInput.Path = r.URI().Path()
|
|
|
|
fileInput.Name = r.URI().Name()
|
|
|
|
fileInput.Ext = r.URI().Extension()
|
|
|
|
|
|
|
|
fileVideoForConversionMessage.Text = r.URI().Path()
|
|
|
|
setStringSuccessStyle(fileVideoForConversionMessage)
|
|
|
|
|
|
|
|
form.Enable()
|
|
|
|
conversionMessage.Text = ""
|
|
|
|
|
|
|
|
listableURI := storage.NewFileURI(filepath.Dir(r.URI().Path()))
|
|
|
|
locationURI, err = storage.ListerForURI(listableURI)
|
|
|
|
}, locationURI)
|
2024-01-14 16:31:07 +06:00
|
|
|
})
|
|
|
|
|
2024-01-15 20:28:02 +06:00
|
|
|
return button, fileVideoForConversionMessage, fileInput
|
2024-01-14 16:31:07 +06:00
|
|
|
}
|
|
|
|
|
2024-01-18 20:23:23 +06:00
|
|
|
func (v View) getButtonForSelectingDirectoryForSaving() (button *widget.Button, buttonMessage *canvas.Text, dirPath *string) {
|
2024-02-01 00:28:06 +06:00
|
|
|
buttonMessage = canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
|
2024-01-18 20:23:23 +06:00
|
|
|
buttonMessage.TextSize = 16
|
|
|
|
buttonMessage.TextStyle = fyne.TextStyle{Bold: true}
|
|
|
|
|
|
|
|
path := ""
|
|
|
|
dirPath = &path
|
|
|
|
|
2024-02-17 19:08:58 +06:00
|
|
|
buttonTitle := v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
2024-01-28 22:01:16 +06:00
|
|
|
MessageID: "choose",
|
|
|
|
})
|
|
|
|
|
2024-02-10 20:11:26 +06:00
|
|
|
var locationURI fyne.ListableURI
|
|
|
|
|
2024-01-28 22:01:16 +06:00
|
|
|
button = widget.NewButton(buttonTitle, func() {
|
2024-02-17 19:08:58 +06:00
|
|
|
v.app.GetWindow().NewFolderOpen(func(r fyne.ListableURI, err error) {
|
|
|
|
if err != nil {
|
|
|
|
buttonMessage.Text = err.Error()
|
|
|
|
setStringErrorStyle(buttonMessage)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if r == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
path = r.Path()
|
|
|
|
|
|
|
|
buttonMessage.Text = r.Path()
|
|
|
|
setStringSuccessStyle(buttonMessage)
|
|
|
|
locationURI, _ = storage.ListerForURI(r)
|
|
|
|
|
|
|
|
}, locationURI)
|
2024-01-18 20:23:23 +06:00
|
|
|
})
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-03-07 22:18:35 +05:00
|
|
|
type selectEncoder struct {
|
|
|
|
SelectFileType *widget.RadioGroup
|
|
|
|
SelectFormat *widget.Select
|
|
|
|
SelectEncoder *widget.Select
|
|
|
|
Encoder encoder2.EncoderContract
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v View) getSelectFormat(formats encoder.ConvertorFormatsContract) *selectEncoder {
|
|
|
|
selectEncoder := &selectEncoder{}
|
|
|
|
|
|
|
|
encoders := map[int]encoder2.EncoderDataContract{}
|
|
|
|
selectEncoder.SelectEncoder = widget.NewSelect([]string{}, func(s string) {
|
|
|
|
if encoders[selectEncoder.SelectEncoder.SelectedIndex()] == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
selectEncoder.Encoder = encoders[selectEncoder.SelectEncoder.SelectedIndex()].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 = format.GetEncoders()
|
|
|
|
for _, e := range encoders {
|
|
|
|
encoderOptions = append(encoderOptions, v.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())
|
|
|
|
}
|
|
|
|
selectEncoder.SelectFileType = widget.NewRadioGroup([]string{"video", "audio", "image"}, func(s string) {
|
|
|
|
formatOptions := []string{}
|
|
|
|
for _, f := range formats.GetFormats() {
|
|
|
|
if s != f.GetFileType().Name() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
formatOptions = append(formatOptions, f.GetTitle())
|
|
|
|
}
|
|
|
|
selectEncoder.SelectFormat.SetOptions(formatOptions)
|
|
|
|
if s == encoder2.FileType(encoder2.Video).Name() {
|
|
|
|
selectEncoder.SelectFormat.SetSelected("mp4")
|
|
|
|
} else {
|
|
|
|
selectEncoder.SelectFormat.SetSelectedIndex(0)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
selectEncoder.SelectFileType.Horizontal = true
|
|
|
|
selectEncoder.SelectFileType.SetSelected("video")
|
|
|
|
|
|
|
|
return selectEncoder
|
|
|
|
}
|
|
|
|
|
2024-01-14 16:31:07 +06:00
|
|
|
func setStringErrorStyle(text *canvas.Text) {
|
2024-02-01 00:28:06 +06:00
|
|
|
text.Color = color.RGBA{R: 255, G: 0, B: 0, A: 255}
|
2024-01-14 16:31:07 +06:00
|
|
|
text.Refresh()
|
|
|
|
}
|
|
|
|
|
|
|
|
func setStringSuccessStyle(text *canvas.Text) {
|
2024-02-01 00:28:06 +06:00
|
|
|
text.Color = color.RGBA{R: 49, G: 127, B: 114, A: 255}
|
2024-01-14 16:31:07 +06:00
|
|
|
text.Refresh()
|
|
|
|
}
|
2024-01-15 20:28:02 +06:00
|
|
|
|
|
|
|
func showConversionMessage(conversionMessage *canvas.Text, err error) {
|
|
|
|
conversionMessage.Text = err.Error()
|
|
|
|
setStringErrorStyle(conversionMessage)
|
|
|
|
}
|
|
|
|
|
|
|
|
func enableFormConversion(enableFormConversionStruct enableFormConversionStruct) {
|
|
|
|
enableFormConversionStruct.fileVideoForConversion.Enable()
|
2024-01-18 20:23:23 +06:00
|
|
|
enableFormConversionStruct.buttonForSelectedDir.Enable()
|
2024-01-15 20:28:02 +06:00
|
|
|
enableFormConversionStruct.form.Enable()
|
|
|
|
}
|