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
|
|
|
"ffmpegGui/convertor"
|
2024-01-18 20:23:23 +06:00
|
|
|
"ffmpegGui/helper"
|
2024-01-28 22:01:16 +06:00
|
|
|
"ffmpegGui/localizer"
|
2024-01-18 01:39:20 +06:00
|
|
|
"ffmpegGui/setting"
|
2024-01-14 16:31:07 +06:00
|
|
|
"fyne.io/fyne/v2/widget"
|
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-01-14 16:31:07 +06:00
|
|
|
type ConvertorHandler struct {
|
2024-01-18 01:39:20 +06:00
|
|
|
convertorService convertor.ServiceContract
|
|
|
|
convertorView convertor.ViewContract
|
|
|
|
settingRepository setting.RepositoryContract
|
2024-01-28 22:01:16 +06:00
|
|
|
localizerService localizer.ServiceContract
|
2024-01-14 16:31:07 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewConvertorHandler(
|
|
|
|
convertorService convertor.ServiceContract,
|
|
|
|
convertorView convertor.ViewContract,
|
2024-01-18 01:39:20 +06:00
|
|
|
settingRepository setting.RepositoryContract,
|
2024-01-28 22:01:16 +06:00
|
|
|
localizerService localizer.ServiceContract,
|
2024-01-14 16:31:07 +06:00
|
|
|
) *ConvertorHandler {
|
|
|
|
return &ConvertorHandler{
|
2024-01-28 22:01:16 +06:00
|
|
|
convertorService: convertorService,
|
|
|
|
convertorView: convertorView,
|
|
|
|
settingRepository: settingRepository,
|
|
|
|
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-01-31 21:02:12 +06:00
|
|
|
h.convertorView.SelectFFPath(h.saveSettingFFPath)
|
2024-01-14 16:31:07 +06:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
ffmpegEntity := setting.Setting{Code: "ffmpeg", Value: item.FFmpeg}
|
2024-01-18 20:23:23 +06:00
|
|
|
_, _ = h.settingRepository.Create(ffmpegEntity)
|
2024-01-18 01:39:20 +06:00
|
|
|
ffprobeEntity := setting.Setting{Code: "ffprobe", Value: item.FFprobe}
|
2024-01-18 20:23:23 +06:00
|
|
|
_, _ = h.settingRepository.Create(ffprobeEntity)
|
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
|
|
|
}
|
|
|
|
|
|
|
|
ffmpegEntity := setting.Setting{Code: "ffmpeg", Value: ffmpegPath}
|
2024-01-18 20:23:23 +06:00
|
|
|
_, _ = h.settingRepository.Create(ffmpegEntity)
|
2024-01-18 01:39:20 +06:00
|
|
|
ffprobeEntity := setting.Setting{Code: "ffprobe", Value: ffprobePath}
|
2024-01-18 20:23:23 +06:00
|
|
|
_, _ = h.settingRepository.Create(ffprobeEntity)
|
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
|
|
|
|
|
|
|
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-28 22:01:16 +06:00
|
|
|
func NewProgress(totalDuration float64, progressbar *widget.ProgressBar, localizerService localizer.ServiceContract) progress {
|
2024-01-20 01:53:25 +06:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
p.progressbar.Refresh()
|
|
|
|
|
|
|
|
progress := 0.0
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
scannerErr := bufio.NewScanner(stdErr)
|
|
|
|
for scannerErr.Scan() {
|
|
|
|
errorText = scannerErr.Text()
|
|
|
|
}
|
|
|
|
if err := scannerErr.Err(); err != nil {
|
|
|
|
errorText = err.Error()
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
scannerOut := bufio.NewScanner(stdOut)
|
|
|
|
for scannerOut.Scan() {
|
|
|
|
data := scannerOut.Text()
|
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
|
|
|
|
}
|