Add GetTotalDuration
method to FFprobeContract
and implementation
Extend `FFprobeContract` interface with `GetTotalDuration` for retrieving the duration of media files.
This commit is contained in:
parent
29ca392880
commit
eb43669ae7
@ -5,11 +5,14 @@ import (
|
|||||||
"fyne.io/fyne/v2/lang"
|
"fyne.io/fyne/v2/lang"
|
||||||
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils"
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FFprobeContract interface {
|
type FFprobeContract interface {
|
||||||
GetPath() string
|
GetPath() string
|
||||||
|
GetTotalDuration(file *File) (float64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ffprobe struct {
|
type ffprobe struct {
|
||||||
@ -38,6 +41,50 @@ func (f *ffprobe) GetPath() string {
|
|||||||
return f.path
|
return f.path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *ffprobe) GetTotalDuration(file *File) (duration float64, err error) {
|
||||||
|
args := []string{"-v", "error", "-select_streams", "v:0", "-count_packets", "-show_entries", "stream=nb_read_packets", "-of", "csv=p=0", file.Path}
|
||||||
|
cmd := exec.Command(f.path, args...)
|
||||||
|
utils.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 f.getAlternativeTotalDuration(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
duration, err = strconv.ParseFloat(frames, 64)
|
||||||
|
if err != nil {
|
||||||
|
// fix .mts duration
|
||||||
|
return strconv.ParseFloat(getFirstDigits(frames), 64)
|
||||||
|
}
|
||||||
|
return duration, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *ffprobe) 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(f.path, args...)
|
||||||
|
utils.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 checkFFprobePath(path string) (bool, error) {
|
func checkFFprobePath(path string) (bool, error) {
|
||||||
cmd := exec.Command(path, "-version")
|
cmd := exec.Command(path, "-version")
|
||||||
utils.PrepareBackgroundCommand(cmd)
|
utils.PrepareBackgroundCommand(cmd)
|
||||||
@ -50,3 +97,15 @@ func checkFFprobePath(path string) (bool, error) {
|
|||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getFirstDigits(s string) string {
|
||||||
|
result := ""
|
||||||
|
for _, r := range s {
|
||||||
|
if unicode.IsDigit(r) {
|
||||||
|
result += string(r)
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user