Added the ability to convert files to different extensions.

This commit is contained in:
2024-03-07 22:18:35 +05:00
parent 1eb7ea4a93
commit 1ece1e443d
45 changed files with 1735 additions and 48 deletions

View File

@@ -1,8 +1,11 @@
package kernel
import (
"bufio"
"errors"
encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/helper"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel/encoder"
"io"
"os/exec"
"regexp"
@@ -20,6 +23,7 @@ type ConvertSetting struct {
VideoFileInput File
VideoFileOut File
OverwriteOutputFiles bool
Encoder encoder2.EncoderContract
}
type ConvertorContract interface {
@@ -30,6 +34,7 @@ type ConvertorContract interface {
ChangeFFmpegPath(path string) (bool, error)
ChangeFFprobePath(path string) (bool, error)
GetRunningProcesses() map[int]*exec.Cmd
GetSupportFormats() (encoder.ConvertorFormatsContract, error)
}
type ProgressContract interface {
@@ -68,7 +73,9 @@ func (s Convertor) RunConvert(setting ConvertSetting, progress ProgressContract)
if setting.OverwriteOutputFiles == true {
overwriteOutputFiles = "-y"
}
args := []string{overwriteOutputFiles, "-i", setting.VideoFileInput.Path, "-c:v", "libx264", "-progress", progress.GetProtocole(), setting.VideoFileOut.Path}
args := []string{overwriteOutputFiles, "-i", setting.VideoFileInput.Path}
args = append(args, setting.Encoder.GetParams()...)
args = append(args, "-progress", progress.GetProtocole(), setting.VideoFileOut.Path)
cmd := exec.Command(s.ffPathUtilities.FFmpeg, args...)
helper.PrepareBackgroundCommand(cmd)
@@ -115,7 +122,30 @@ func (s Convertor) GetTotalDuration(file *File) (duration float64, err error) {
}
return 0, err
}
return strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
frames := strings.TrimSpace(string(out))
if len(frames) == 0 {
return s.getAlternativeTotalDuration(file)
}
return strconv.ParseFloat(frames, 64)
}
func (s Convertor) getAlternativeTotalDuration(file *File) (duration float64, err error) {
args := []string{"-v", "error", "-select_streams", "a:0", "-count_packets", "-show_entries", "stream=nb_read_packets", "-of", "csv=p=0", file.Path}
cmd := exec.Command(s.ffPathUtilities.FFprobe, args...)
helper.PrepareBackgroundCommand(cmd)
out, err := cmd.CombinedOutput()
if err != nil {
errString := strings.TrimSpace(string(out))
if len(errString) > 1 {
return 0, errors.New(errString)
}
return 0, err
}
frames := strings.TrimSpace(string(out))
if len(frames) == 0 {
return 0, errors.New("error getting number of frames")
}
return strconv.ParseFloat(frames, 64)
}
func (s Convertor) GetFFmpegVesrion() (string, error) {
@@ -168,6 +198,45 @@ func (s Convertor) ChangeFFprobePath(path string) (bool, error) {
return true, nil
}
func (s Convertor) GetSupportFormats() (encoder.ConvertorFormatsContract, error) {
formats := encoder.NewConvertorFormats()
cmd := exec.Command(s.ffPathUtilities.FFmpeg, "-encoders")
stdOut, err := cmd.StdoutPipe()
if err != nil {
return formats, err
}
err = cmd.Start()
if err != nil {
return formats, err
}
scannerErr := bufio.NewReader(stdOut)
for {
line, _, err := scannerErr.ReadLine()
if err != nil {
if err == io.EOF {
break
}
continue
}
text := strings.Split(strings.TrimSpace(string(line)), " ")
encoderType := string(text[0][0])
if len(text) < 2 || (encoderType != "V" && encoderType != "A") {
continue
}
formats.NewEncoder(text[1])
}
err = cmd.Wait()
if err != nil {
return formats, err
}
return formats, nil
}
func (s Convertor) GetRunningProcesses() map[int]*exec.Cmd {
return s.runningProcesses.items
}

84
kernel/encoder/encoder.go Normal file
View File

@@ -0,0 +1,84 @@
package encoder
import (
"errors"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
)
type ConvertorFormatContract interface {
GetTitle() string
AddEncoder(encoder encoder.EncoderDataContract)
GetFileType() encoder.FileTypeContract
GetEncoders() map[int]encoder.EncoderDataContract
}
type ConvertorFormat struct {
title string
fileType encoder.FileTypeContract
encoders map[int]encoder.EncoderDataContract
}
func NewConvertorFormat(title string, fileType encoder.FileTypeContract) *ConvertorFormat {
return &ConvertorFormat{
title: title,
fileType: fileType,
encoders: map[int]encoder.EncoderDataContract{},
}
}
func (f ConvertorFormat) GetTitle() string {
return f.title
}
func (f ConvertorFormat) AddEncoder(encoder encoder.EncoderDataContract) {
f.encoders[len(f.encoders)] = encoder
}
func (f ConvertorFormat) GetEncoders() map[int]encoder.EncoderDataContract {
return f.encoders
}
func (f ConvertorFormat) GetFileType() encoder.FileTypeContract {
return f.fileType
}
type ConvertorFormatsContract interface {
NewEncoder(encoderName string) bool
GetFormats() map[string]ConvertorFormatContract
GetFormat(format string) (ConvertorFormatContract, error)
}
type ConvertorFormats struct {
formats map[string]ConvertorFormatContract
}
func NewConvertorFormats() *ConvertorFormats {
return &ConvertorFormats{
formats: map[string]ConvertorFormatContract{},
}
}
func (f ConvertorFormats) NewEncoder(encoderName string) bool {
if supportEncoders[encoderName] == nil {
return false
}
data := supportEncoders[encoderName]()
for _, format := range data.GetFormats() {
if f.formats[format] == nil {
f.formats[format] = NewConvertorFormat(format, data.GetFileType())
}
f.formats[format].AddEncoder(data)
}
return true
}
func (f ConvertorFormats) GetFormats() map[string]ConvertorFormatContract {
return f.formats
}
func (f ConvertorFormats) GetFormat(format string) (ConvertorFormatContract, error) {
if f.formats[format] == nil {
return ConvertorFormat{}, errors.New("not found ConvertorFormat")
}
return f.formats[format], nil
}

View File

@@ -0,0 +1,74 @@
package encoder
import (
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/apng"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/bmp"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/flv"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/gif"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/h264_nvenc"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libmp3lame"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libshine"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libtwolame"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libvpx"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libvpx_vp9"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libwebp"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libwebp_anim"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libx264"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libx265"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/libxvid"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/mjpeg"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/mp2"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/mp2fixed"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/mpeg1video"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/mpeg2video"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/mpeg4"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/msmpeg4"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/msmpeg4v2"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/msvideo1"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/png"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/qtrle"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/sgi"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/tiff"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/wmav1"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/wmav2"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/wmv1"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/wmv2"
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/encoder/xbm"
)
var supportEncoders = map[string]func() encoder.EncoderDataContract{
"libx264": libx264.NewData,
"h264_nvenc": h264_nvenc.NewData,
"libx265": libx265.NewData,
"png": png.NewData,
"gif": gif.NewData,
"flv": flv.NewData,
"apng": apng.NewData,
"bmp": bmp.NewData,
"mjpeg": mjpeg.NewData,
"mpeg1video": mpeg1video.NewData,
"mpeg2video": mpeg2video.NewData,
"mpeg4": mpeg4.NewData,
"libxvid": libxvid.NewData,
"msmpeg4v2": msmpeg4v2.NewData,
"msmpeg4": msmpeg4.NewData,
"msvideo1": msvideo1.NewData,
"qtrle": qtrle.NewData,
"tiff": tiff.NewData,
"sgi": sgi.NewData,
"libvpx": libvpx.NewData,
"libvpx-vp9": libvpx_vp9.NewData,
"libwebp_anim": libwebp_anim.NewData,
"libwebp": libwebp.NewData,
"wmv1": wmv1.NewData,
"wmv2": wmv2.NewData,
"xbm": xbm.NewData,
"mp2": mp2.NewData,
"mp2fixed": mp2fixed.NewData,
"libtwolame": libtwolame.NewData,
"libmp3lame": libmp3lame.NewData,
"libshine": libshine.NewData,
"wmav1": wmav1.NewData,
"wmav2": wmav2.NewData,
}