Working prototype.

A simple working graphical interface with which you can transcode any video to mp4.
This commit is contained in:
2024-01-14 16:31:07 +06:00
parent e288d5efbb
commit 5a4c960201
7 changed files with 1062 additions and 0 deletions

78
src/convertor/service.go Normal file
View File

@@ -0,0 +1,78 @@
package convertor
import (
"os/exec"
"strconv"
"strings"
)
type ServiceContract interface {
RunConvert(setting ConvertSetting) error
GetTotalDuration(file File) (float64, error)
}
type Service struct {
pathFFmpeg string
pathFFprobe string
}
type File struct {
Path string
Name string
Ext string
}
type ConvertSetting struct {
VideoFileInput File
SocketPath string
}
type ConvertData struct {
totalDuration float64
}
func NewService(pathFFmpeg string, pathFFprobe string) *Service {
return &Service{
pathFFmpeg: pathFFmpeg,
pathFFprobe: pathFFprobe,
}
}
func (s Service) RunConvert(setting ConvertSetting) error {
//args := strings.Split("-report -n -c:v libx264", " ")
//args := strings.Split("-n -c:v libx264", " ")
//args = append(args, "-progress", "unix://"+setting.SocketPath, "-i", setting.VideoFileInput.Path, "file-out.mp4")
//args := "-report -n -i " + setting.VideoFileInput.Path + " -c:v libx264 -progress unix://" + setting.SocketPath + " output-file.mp4"
//args := "-n -i " + setting.VideoFileInput.Path + " -c:v libx264 -progress unix://" + setting.SocketPath + " output-file.mp4"
args := "-y -i " + setting.VideoFileInput.Path + " -c:v libx264 -progress unix://" + setting.SocketPath + " output-file.mp4"
cmd := exec.Command("ffmpeg", strings.Split(args, " ")...)
//stderr, _ := cmd.StdoutPipe()
err := cmd.Start()
if err != nil {
return err
}
//scanner := bufio.NewScanner(stderr)
////scanner.Split(bufio.ScanWords)
//for scanner.Scan() {
// m := scanner.Text()
// fmt.Println(m)
//}
err = cmd.Wait()
if err != nil {
return err
}
return nil
}
func (s Service) GetTotalDuration(file File) (duration float64, err error) {
args := "-v error -select_streams v:0 -count_packets -show_entries stream=nb_read_packets -of csv=p=0 " + file.Path
cmd := exec.Command(s.pathFFprobe, strings.Split(args, " ")...)
out, err := cmd.CombinedOutput()
if err != nil {
return 0, err
}
return strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
}

121
src/convertor/view.go Normal file
View File

@@ -0,0 +1,121 @@
package convertor
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/widget"
"image/color"
)
type ViewContract interface {
Main(
runConvert func(setting HandleConvertSetting) error,
getSocketPath func(File, *widget.ProgressBar) (string, error),
)
}
type View struct {
w fyne.Window
}
type HandleConvertSetting struct {
VideoFileInput File
SocketPath string
}
func NewView(w fyne.Window) *View {
return &View{w}
}
func (v View) Main(
runConvert func(setting HandleConvertSetting) error,
getSocketPath func(File, *widget.ProgressBar) (string, error),
) {
var fileInput File
var form *widget.Form
fileVideoForConversionMessage := canvas.NewText("", color.RGBA{255, 0, 0, 255})
fileVideoForConversionMessage.TextSize = 16
fileVideoForConversionMessage.TextStyle = fyne.TextStyle{Bold: true}
conversionMessage := canvas.NewText("", color.RGBA{255, 0, 0, 255})
conversionMessage.TextSize = 16
conversionMessage.TextStyle = fyne.TextStyle{Bold: true}
progress := widget.NewProgressBar()
progress.Hide()
fileVideoForConversion := widget.NewButton("выбрать", func() {
fileDialog := dialog.NewFileOpen(
func(r fyne.URIReadCloser, err error) {
if err != nil {
fileVideoForConversionMessage.Text = err.Error()
setStringErrorStyle(fileVideoForConversionMessage)
return
}
if r == nil {
return
}
fileInput = File{
Path: r.URI().Path(),
Name: r.URI().Name(),
Ext: r.URI().Extension(),
}
fileVideoForConversionMessage.Text = r.URI().Path()
setStringSuccessStyle(fileVideoForConversionMessage)
form.Enable()
}, v.w)
fileDialog.Show()
})
form = &widget.Form{
Items: []*widget.FormItem{
{Text: "Файл для ковертации:", Widget: fileVideoForConversion},
{Widget: fileVideoForConversionMessage},
},
SubmitText: "Конвертировать",
OnSubmit: func() {
fileVideoForConversion.Disable()
form.Disable()
socketPath, err := getSocketPath(fileInput, progress)
if err != nil {
conversionMessage.Text = err.Error()
setStringErrorStyle(conversionMessage)
fileVideoForConversion.Enable()
form.Enable()
}
setting := HandleConvertSetting{
VideoFileInput: fileInput,
SocketPath: socketPath,
}
err = runConvert(setting)
if err != nil {
conversionMessage.Text = err.Error()
setStringErrorStyle(conversionMessage)
}
fileVideoForConversion.Enable()
form.Enable()
},
}
v.w.SetContent(widget.NewCard("Конвертор видео файлов", "", container.NewVBox(form, conversionMessage, progress)))
form.Disable()
}
func setStringErrorStyle(text *canvas.Text) {
text.Color = color.RGBA{255, 0, 0, 255}
text.Refresh()
}
func setStringSuccessStyle(text *canvas.Text) {
text.Color = color.RGBA{49, 127, 114, 255}
text.Refresh()
}