2024-01-14 16:31:07 +06:00
|
|
|
package handler
|
|
|
|
|
|
|
|
import (
|
2024-01-20 01:53:25 +06:00
|
|
|
"bufio"
|
2024-01-18 01:39:20 +06:00
|
|
|
"errors"
|
2024-01-14 16:31:07 +06:00
|
|
|
"fyne.io/fyne/v2/widget"
|
2024-02-12 22:21:47 +06:00
|
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/convertor"
|
|
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/helper"
|
|
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/localizer"
|
2024-01-28 22:01:16 +06:00
|
|
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
2024-01-20 01:53:25 +06:00
|
|
|
"io"
|
2024-01-14 16:31:07 +06:00
|
|
|
"regexp"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2024-01-31 21:02:12 +06:00
|
|
|
type ConvertorHandlerContract interface {
|
|
|
|
MainConvertor()
|
2024-02-01 00:23:28 +06:00
|
|
|
FfPathSelection()
|
2024-02-03 17:47:32 +06:00
|
|
|
GetFfmpegVersion() (string, error)
|
|
|
|
GetFfprobeVersion() (string, error)
|
2024-01-31 21:02:12 +06:00
|
|
|
}
|
|
|
|
|
2024-01-14 16:31:07 +06:00
|
|
|
type ConvertorHandler struct {
|
2024-02-01 00:23:28 +06:00
|
|
|
convertorService convertor.ServiceContract
|
|
|
|
convertorView convertor.ViewContract
|
|
|
|
convertorRepository convertor.RepositoryContract
|
|
|
|
localizerService localizer.ServiceContract
|
2024-01-14 16:31:07 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewConvertorHandler(
|
|
|
|
convertorService convertor.ServiceContract,
|
|
|
|
convertorView convertor.ViewContract,
|
2024-02-01 00:23:28 +06:00
|
|
|
convertorRepository convertor.RepositoryContract,
|
2024-01-28 22:01:16 +06:00
|
|
|
localizerService localizer.ServiceContract,
|
2024-01-14 16:31:07 +06:00
|
|
|
) *ConvertorHandler {
|
|
|
|
return &ConvertorHandler{
|
2024-02-01 00:23:28 +06:00
|
|
|
convertorService: convertorService,
|
|
|
|
convertorView: convertorView,
|
|
|
|
convertorRepository: convertorRepository,
|
|
|
|
localizerService: localizerService,
|
2024-01-14 16:31:07 +06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-31 21:02:12 +06:00
|
|
|
func (h ConvertorHandler) MainConvertor() {
|
2024-01-18 01:39:20 +06:00
|
|
|
if h.checkingFFPathUtilities() == true {
|
2024-01-20 01:53:25 +06:00
|
|
|
h.convertorView.Main(h.runConvert)
|
2024-01-18 01:39:20 +06:00
|
|
|
return
|
|
|
|
}
|
2024-02-04 20:16:15 +06:00
|
|
|
h.convertorView.SelectFFPath("", "", h.saveSettingFFPath, nil, h.downloadFFmpeg)
|
2024-02-01 00:23:28 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (h ConvertorHandler) FfPathSelection() {
|
|
|
|
ffmpeg, _ := h.convertorRepository.GetPathFfmpeg()
|
|
|
|
ffprobe, _ := h.convertorRepository.GetPathFfprobe()
|
2024-02-04 20:16:15 +06:00
|
|
|
h.convertorView.SelectFFPath(ffmpeg, ffprobe, h.saveSettingFFPath, h.MainConvertor, h.downloadFFmpeg)
|
2024-01-14 16:31:07 +06:00
|
|
|
}
|
|
|
|
|
2024-02-03 17:47:32 +06:00
|
|
|
func (h ConvertorHandler) GetFfmpegVersion() (string, error) {
|
|
|
|
return h.convertorService.GetFFmpegVesrion()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h ConvertorHandler) GetFfprobeVersion() (string, error) {
|
|
|
|
return h.convertorService.GetFFprobeVersion()
|
|
|
|
}
|
|
|
|
|
2024-01-20 01:53:25 +06:00
|
|
|
func (h ConvertorHandler) runConvert(setting convertor.HandleConvertSetting, progressbar *widget.ProgressBar) error {
|
|
|
|
totalDuration, err := h.convertorService.GetTotalDuration(setting.VideoFileInput)
|
2024-01-14 16:31:07 +06:00
|
|
|
if err != nil {
|
2024-01-20 01:53:25 +06:00
|
|
|
return err
|
2024-01-14 16:31:07 +06:00
|
|
|
}
|
2024-01-28 22:01:16 +06:00
|
|
|
progress := NewProgress(totalDuration, progressbar, h.localizerService)
|
2024-01-18 20:23:23 +06:00
|
|
|
|
2024-01-14 16:31:07 +06:00
|
|
|
return h.convertorService.RunConvert(
|
|
|
|
convertor.ConvertSetting{
|
|
|
|
VideoFileInput: setting.VideoFileInput,
|
2024-01-18 20:23:23 +06:00
|
|
|
VideoFileOut: &convertor.File{
|
|
|
|
Path: setting.DirectoryForSave + helper.PathSeparator() + setting.VideoFileInput.Name + ".mp4",
|
|
|
|
Name: setting.VideoFileInput.Name,
|
|
|
|
Ext: ".mp4",
|
|
|
|
},
|
|
|
|
OverwriteOutputFiles: setting.OverwriteOutputFiles,
|
2024-01-14 16:31:07 +06:00
|
|
|
},
|
2024-01-20 01:53:25 +06:00
|
|
|
progress,
|
2024-01-14 16:31:07 +06:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2024-01-18 01:39:20 +06:00
|
|
|
func (h ConvertorHandler) checkingFFPathUtilities() bool {
|
|
|
|
if h.checkingFFPath() == true {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2024-01-23 21:33:01 +06:00
|
|
|
pathsToFF := getPathsToFF()
|
2024-01-18 01:39:20 +06:00
|
|
|
for _, item := range pathsToFF {
|
|
|
|
ffmpegChecking, _ := h.convertorService.ChangeFFmpegPath(item.FFmpeg)
|
|
|
|
if ffmpegChecking == false {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
ffprobeChecking, _ := h.convertorService.ChangeFFprobePath(item.FFprobe)
|
|
|
|
if ffprobeChecking == false {
|
|
|
|
continue
|
|
|
|
}
|
2024-02-01 00:23:28 +06:00
|
|
|
_, _ = h.convertorRepository.SavePathFfmpeg(item.FFmpeg)
|
|
|
|
_, _ = h.convertorRepository.SavePathFfprobe(item.FFprobe)
|
2024-01-18 01:39:20 +06:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h ConvertorHandler) saveSettingFFPath(ffmpegPath string, ffprobePath string) error {
|
|
|
|
ffmpegChecking, _ := h.convertorService.ChangeFFmpegPath(ffmpegPath)
|
|
|
|
if ffmpegChecking == false {
|
2024-01-28 22:01:16 +06:00
|
|
|
errorText := h.localizerService.GetMessage(&i18n.LocalizeConfig{
|
|
|
|
MessageID: "errorFFmpeg",
|
|
|
|
})
|
|
|
|
return errors.New(errorText)
|
2024-01-18 01:39:20 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
ffprobeChecking, _ := h.convertorService.ChangeFFprobePath(ffprobePath)
|
|
|
|
if ffprobeChecking == false {
|
2024-01-28 22:01:16 +06:00
|
|
|
errorText := h.localizerService.GetMessage(&i18n.LocalizeConfig{
|
|
|
|
MessageID: "errorFFprobe",
|
|
|
|
})
|
|
|
|
return errors.New(errorText)
|
2024-01-18 01:39:20 +06:00
|
|
|
}
|
|
|
|
|
2024-02-01 00:23:28 +06:00
|
|
|
_, _ = h.convertorRepository.SavePathFfmpeg(ffmpegPath)
|
|
|
|
_, _ = h.convertorRepository.SavePathFfprobe(ffprobePath)
|
2024-01-18 01:39:20 +06:00
|
|
|
|
2024-01-31 21:02:12 +06:00
|
|
|
h.MainConvertor()
|
2024-01-18 01:39:20 +06:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h ConvertorHandler) checkingFFPath() bool {
|
|
|
|
_, err := h.convertorService.GetFFmpegVesrion()
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = h.convertorService.GetFFprobeVersion()
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
2024-01-20 01:53:25 +06:00
|
|
|
|
2024-01-31 21:22:38 +06:00
|
|
|
type Progress struct {
|
2024-01-28 22:01:16 +06:00
|
|
|
totalDuration float64
|
|
|
|
progressbar *widget.ProgressBar
|
|
|
|
protocol string
|
|
|
|
localizerService localizer.ServiceContract
|
2024-01-20 01:53:25 +06:00
|
|
|
}
|
|
|
|
|
2024-01-31 21:22:38 +06:00
|
|
|
func NewProgress(totalDuration float64, progressbar *widget.ProgressBar, localizerService localizer.ServiceContract) Progress {
|
|
|
|
return Progress{
|
2024-01-28 22:01:16 +06:00
|
|
|
totalDuration: totalDuration,
|
|
|
|
progressbar: progressbar,
|
|
|
|
protocol: "pipe:",
|
|
|
|
localizerService: localizerService,
|
2024-01-20 01:53:25 +06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-31 21:22:38 +06:00
|
|
|
func (p Progress) GetProtocole() string {
|
2024-01-20 01:53:25 +06:00
|
|
|
return p.protocol
|
|
|
|
}
|
|
|
|
|
2024-01-31 21:22:38 +06:00
|
|
|
func (p Progress) Run(stdOut io.ReadCloser, stdErr io.ReadCloser) error {
|
2024-01-20 01:53:25 +06:00
|
|
|
isProcessCompleted := false
|
|
|
|
var errorText string
|
|
|
|
|
|
|
|
p.progressbar.Value = 0
|
|
|
|
p.progressbar.Max = p.totalDuration
|
|
|
|
p.progressbar.Refresh()
|
|
|
|
|
|
|
|
progress := 0.0
|
|
|
|
|
|
|
|
go func() {
|
2024-02-10 20:13:17 +06:00
|
|
|
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
|
2024-01-20 01:53:25 +06:00
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2024-02-10 20:13:17 +06:00
|
|
|
scannerOut := bufio.NewReader(stdOut)
|
|
|
|
for {
|
|
|
|
line, _, err := scannerOut.ReadLine()
|
|
|
|
if err != nil {
|
|
|
|
if err == io.EOF {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
data := strings.TrimSpace(string(line))
|
2024-01-27 21:17:04 +06:00
|
|
|
if strings.Contains(data, "progress=end") {
|
|
|
|
p.progressbar.Value = p.totalDuration
|
|
|
|
p.progressbar.Refresh()
|
|
|
|
isProcessCompleted = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
2024-01-20 01:53:25 +06:00
|
|
|
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
|
|
|
|
p.progressbar.Refresh()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if isProcessCompleted == false {
|
|
|
|
if len(errorText) == 0 {
|
2024-01-28 22:01:16 +06:00
|
|
|
errorText = p.localizerService.GetMessage(&i18n.LocalizeConfig{
|
|
|
|
MessageID: "errorConverter",
|
|
|
|
})
|
2024-01-20 01:53:25 +06:00
|
|
|
}
|
|
|
|
return errors.New(errorText)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|