Add FFplay support to the application
Integrated FFplay functionality across the application. This includes support for setting up the FFplay path and invoking FFplay for media playback.
This commit is contained in:
parent
a831d56d93
commit
306383449a
@ -9,6 +9,8 @@ type RepositoryContract interface {
|
|||||||
SavePathFfmpeg(code string) (setting.Setting, error)
|
SavePathFfmpeg(code string) (setting.Setting, error)
|
||||||
GetPathFfprobe() (string, error)
|
GetPathFfprobe() (string, error)
|
||||||
SavePathFfprobe(code string) (setting.Setting, error)
|
SavePathFfprobe(code string) (setting.Setting, error)
|
||||||
|
GetPathFfplay() (string, error)
|
||||||
|
SavePathFfplay(code string) (setting.Setting, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
@ -34,3 +36,11 @@ func (r Repository) GetPathFfprobe() (string, error) {
|
|||||||
func (r Repository) SavePathFfprobe(path string) (setting.Setting, error) {
|
func (r Repository) SavePathFfprobe(path string) (setting.Setting, error) {
|
||||||
return r.settingRepository.CreateOrUpdate("ffprobe", path)
|
return r.settingRepository.CreateOrUpdate("ffprobe", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r Repository) GetPathFfplay() (string, error) {
|
||||||
|
return r.settingRepository.GetValue("ffplay")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Repository) SavePathFfplay(path string) (setting.Setting, error) {
|
||||||
|
return r.settingRepository.CreateOrUpdate("ffplay", path)
|
||||||
|
}
|
||||||
|
@ -18,7 +18,8 @@ type ViewContract interface {
|
|||||||
SelectFFPath(
|
SelectFFPath(
|
||||||
ffmpegPath string,
|
ffmpegPath string,
|
||||||
ffprobePath string,
|
ffprobePath string,
|
||||||
save func(ffmpegPath string, ffprobePath string) error,
|
ffplayPath string,
|
||||||
|
save func(ffmpegPath string, ffprobePath string, ffplayPath string) error,
|
||||||
cancel func(),
|
cancel func(),
|
||||||
donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error,
|
donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error,
|
||||||
)
|
)
|
||||||
|
@ -15,7 +15,8 @@ import (
|
|||||||
func (v View) SelectFFPath(
|
func (v View) SelectFFPath(
|
||||||
currentPathFfmpeg string,
|
currentPathFfmpeg string,
|
||||||
currentPathFfprobe string,
|
currentPathFfprobe string,
|
||||||
save func(ffmpegPath string, ffprobePath string) error,
|
currentPathFfplay string,
|
||||||
|
save func(ffmpegPath string, ffprobePath string, ffplayPath string) error,
|
||||||
cancel func(),
|
cancel func(),
|
||||||
donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error,
|
donwloadFFmpeg func(progressBar *widget.ProgressBar, progressMessage *canvas.Text) error,
|
||||||
) {
|
) {
|
||||||
@ -25,6 +26,7 @@ func (v View) SelectFFPath(
|
|||||||
|
|
||||||
ffmpegPath, buttonFFmpeg, buttonFFmpegMessage := v.getButtonSelectFile(currentPathFfmpeg)
|
ffmpegPath, buttonFFmpeg, buttonFFmpegMessage := v.getButtonSelectFile(currentPathFfmpeg)
|
||||||
ffprobePath, buttonFFprobe, buttonFFprobeMessage := v.getButtonSelectFile(currentPathFfprobe)
|
ffprobePath, buttonFFprobe, buttonFFprobeMessage := v.getButtonSelectFile(currentPathFfprobe)
|
||||||
|
ffplayPath, buttonFFplay, buttonFFplayMessage := v.getButtonSelectFile(currentPathFfplay)
|
||||||
|
|
||||||
link := widget.NewHyperlink("https://ffmpeg.org/download.html", &url.URL{
|
link := widget.NewHyperlink("https://ffmpeg.org/download.html", &url.URL{
|
||||||
Scheme: "https",
|
Scheme: "https",
|
||||||
@ -58,6 +60,15 @@ func (v View) SelectFFPath(
|
|||||||
{
|
{
|
||||||
Widget: container.NewHScroll(buttonFFprobeMessage),
|
Widget: container.NewHScroll(buttonFFprobeMessage),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Text: v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
|
MessageID: "pathToFfplay",
|
||||||
|
}),
|
||||||
|
Widget: buttonFFplay,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Widget: container.NewHScroll(buttonFFplayMessage),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Widget: errorMessage,
|
Widget: errorMessage,
|
||||||
},
|
},
|
||||||
@ -66,7 +77,7 @@ func (v View) SelectFFPath(
|
|||||||
MessageID: "save",
|
MessageID: "save",
|
||||||
}),
|
}),
|
||||||
OnSubmit: func() {
|
OnSubmit: func() {
|
||||||
err := save(*ffmpegPath, *ffprobePath)
|
err := save(*ffmpegPath, *ffprobePath, *ffplayPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorMessage.Text = err.Error()
|
errorMessage.Text = err.Error()
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ type ConvertorHandlerContract interface {
|
|||||||
FfPathSelection()
|
FfPathSelection()
|
||||||
GetFfmpegVersion() (string, error)
|
GetFfmpegVersion() (string, error)
|
||||||
GetFfprobeVersion() (string, error)
|
GetFfprobeVersion() (string, error)
|
||||||
|
GetFfplayVersion() (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConvertorHandler struct {
|
type ConvertorHandler struct {
|
||||||
@ -53,13 +54,14 @@ func (h ConvertorHandler) MainConvertor() {
|
|||||||
h.convertorView.Main(conversion)
|
h.convertorView.Main(conversion)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.convertorView.SelectFFPath("", "", h.saveSettingFFPath, nil, h.downloadFFmpeg)
|
h.convertorView.SelectFFPath("", "", "", h.saveSettingFFPath, nil, h.downloadFFmpeg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h ConvertorHandler) FfPathSelection() {
|
func (h ConvertorHandler) FfPathSelection() {
|
||||||
ffmpeg, _ := h.convertorRepository.GetPathFfmpeg()
|
ffmpeg, _ := h.convertorRepository.GetPathFfmpeg()
|
||||||
ffprobe, _ := h.convertorRepository.GetPathFfprobe()
|
ffprobe, _ := h.convertorRepository.GetPathFfprobe()
|
||||||
h.convertorView.SelectFFPath(ffmpeg, ffprobe, h.saveSettingFFPath, h.MainConvertor, h.downloadFFmpeg)
|
ffplay, _ := h.convertorRepository.GetPathFfplay()
|
||||||
|
h.convertorView.SelectFFPath(ffmpeg, ffprobe, ffplay, h.saveSettingFFPath, h.MainConvertor, h.downloadFFmpeg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h ConvertorHandler) GetFfmpegVersion() (string, error) {
|
func (h ConvertorHandler) GetFfmpegVersion() (string, error) {
|
||||||
@ -70,6 +72,10 @@ func (h ConvertorHandler) GetFfprobeVersion() (string, error) {
|
|||||||
return h.app.GetConvertorService().GetFFprobeVersion()
|
return h.app.GetConvertorService().GetFFprobeVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h ConvertorHandler) GetFfplayVersion() (string, error) {
|
||||||
|
return h.app.GetConvertorService().GetFFplayVersion()
|
||||||
|
}
|
||||||
|
|
||||||
func (h ConvertorHandler) runConvert(setting view.HandleConvertSetting) {
|
func (h ConvertorHandler) runConvert(setting view.HandleConvertSetting) {
|
||||||
h.app.GetQueue().Add(&kernel.ConvertSetting{
|
h.app.GetQueue().Add(&kernel.ConvertSetting{
|
||||||
VideoFileInput: setting.FileInput,
|
VideoFileInput: setting.FileInput,
|
||||||
@ -98,15 +104,21 @@ func (h ConvertorHandler) checkingFFPathUtilities() bool {
|
|||||||
if ffprobeChecking == false {
|
if ffprobeChecking == false {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ffplayChecking, _ := h.app.GetConvertorService().ChangeFFplayPath(item.FFplay)
|
||||||
|
if ffplayChecking == false {
|
||||||
|
continue
|
||||||
|
}
|
||||||
_, _ = h.convertorRepository.SavePathFfmpeg(item.FFmpeg)
|
_, _ = h.convertorRepository.SavePathFfmpeg(item.FFmpeg)
|
||||||
_, _ = h.convertorRepository.SavePathFfprobe(item.FFprobe)
|
_, _ = h.convertorRepository.SavePathFfprobe(item.FFprobe)
|
||||||
|
_, _ = h.convertorRepository.SavePathFfplay(item.FFplay)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h ConvertorHandler) saveSettingFFPath(ffmpegPath string, ffprobePath string) error {
|
func (h ConvertorHandler) saveSettingFFPath(ffmpegPath string, ffprobePath string, ffplayPath string) error {
|
||||||
ffmpegChecking, _ := h.app.GetConvertorService().ChangeFFmpegPath(ffmpegPath)
|
ffmpegChecking, _ := h.app.GetConvertorService().ChangeFFmpegPath(ffmpegPath)
|
||||||
if ffmpegChecking == false {
|
if ffmpegChecking == false {
|
||||||
errorText := h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
errorText := h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
@ -123,8 +135,17 @@ func (h ConvertorHandler) saveSettingFFPath(ffmpegPath string, ffprobePath strin
|
|||||||
return errors.New(errorText)
|
return errors.New(errorText)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ffplayChecking, _ := h.app.GetConvertorService().ChangeFFplayPath(ffplayPath)
|
||||||
|
if ffplayChecking == false {
|
||||||
|
errorText := h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
|
MessageID: "errorFFplay",
|
||||||
|
})
|
||||||
|
return errors.New(errorText)
|
||||||
|
}
|
||||||
|
|
||||||
_, _ = h.convertorRepository.SavePathFfmpeg(ffmpegPath)
|
_, _ = h.convertorRepository.SavePathFfmpeg(ffmpegPath)
|
||||||
_, _ = h.convertorRepository.SavePathFfprobe(ffprobePath)
|
_, _ = h.convertorRepository.SavePathFfprobe(ffprobePath)
|
||||||
|
_, _ = h.convertorRepository.SavePathFfplay(ffplayPath)
|
||||||
|
|
||||||
h.MainConvertor()
|
h.MainConvertor()
|
||||||
|
|
||||||
@ -142,5 +163,10 @@ func (h ConvertorHandler) checkingFFPath() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = h.app.GetConvertorService().GetFFplayVersion()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func getPathsToFF() []kernel.FFPathUtilities {
|
func getPathsToFF() []kernel.FFPathUtilities {
|
||||||
return []kernel.FFPathUtilities{{"ffmpeg/bin/ffmpeg", "ffmpeg/bin/ffprobe"}, {"ffmpeg", "ffprobe"}}
|
return []kernel.FFPathUtilities{{FFmpeg: "ffmpeg/bin/ffmpeg", FFprobe: "ffmpeg/bin/ffprobe", FFplay: "ffmpeg/bin/ffplay"}, {FFmpeg: "ffmpeg", FFprobe: "ffprobe", FFplay: "ffplay"}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) {
|
func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) {
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func getPathsToFF() []kernel.FFPathUtilities {
|
func getPathsToFF() []kernel.FFPathUtilities {
|
||||||
return []kernel.FFPathUtilities{{"ffmpeg/bin/ffmpeg", "ffmpeg/bin/ffprobe"}, {"ffmpeg", "ffprobe"}}
|
return []kernel.FFPathUtilities{{FFmpeg: "ffmpeg/bin/ffmpeg", FFprobe: "ffmpeg/bin/ffprobe", FFplay: "ffmpeg/bin/ffplay"}, {FFmpeg: "ffmpeg", FFprobe: "ffprobe", FFplay: "ffplay"}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) {
|
func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) {
|
||||||
@ -60,7 +60,11 @@ func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progre
|
|||||||
progressMessage.Refresh()
|
progressMessage.Refresh()
|
||||||
})
|
})
|
||||||
|
|
||||||
err = h.saveSettingFFPath("ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/ffmpeg", "ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/ffprobe")
|
err = h.saveSettingFFPath(
|
||||||
|
"ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/ffmpeg",
|
||||||
|
"ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/ffprobe",
|
||||||
|
"ffmpeg/ffmpeg-master-latest-linux64-gpl/bin/ffplay",
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -217,6 +221,12 @@ func unTarXz(fileTar string, directory string, progressBar *widget.ProgressBar)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ffplayPath := filepath.Join(directory, "ffmpeg-master-latest-linux64-gpl", "bin", "ffplay")
|
||||||
|
err = os.Chmod(ffplayPath, 0755)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func getPathsToFF() []kernel.FFPathUtilities {
|
func getPathsToFF() []kernel.FFPathUtilities {
|
||||||
return []kernel.FFPathUtilities{{"ffmpeg\\bin\\ffmpeg.exe", "ffmpeg\\bin\\ffprobe.exe"}}
|
return []kernel.FFPathUtilities{{FFmpeg: "ffmpeg\\bin\\ffmpeg.exe", FFprobe: "ffmpeg\\bin\\ffprobe.exe", FFplay: "ffmpeg\\bin\\ffplay.exe"}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) {
|
func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progressMessage *canvas.Text) (err error) {
|
||||||
@ -59,7 +59,11 @@ func (h ConvertorHandler) downloadFFmpeg(progressBar *widget.ProgressBar, progre
|
|||||||
fyne.Do(func() {
|
fyne.Do(func() {
|
||||||
progressMessage.Refresh()
|
progressMessage.Refresh()
|
||||||
})
|
})
|
||||||
err = h.saveSettingFFPath("ffmpeg/ffmpeg-master-latest-win64-gpl/bin/ffmpeg.exe", "ffmpeg/ffmpeg-master-latest-win64-gpl/bin/ffprobe.exe")
|
err = h.saveSettingFFPath(
|
||||||
|
"ffmpeg/ffmpeg-master-latest-win64-gpl/bin/ffmpeg.exe",
|
||||||
|
"ffmpeg/ffmpeg-master-latest-win64-gpl/bin/ffprobe.exe",
|
||||||
|
"ffmpeg/ffmpeg-master-latest-win64-gpl/bin/ffplay.exe",
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -117,8 +117,14 @@ func (h MenuHandler) openAbout() {
|
|||||||
MessageID: "errorFFprobeVersion",
|
MessageID: "errorFFprobeVersion",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
ffplay, err := h.convertorHandler.GetFfplayVersion()
|
||||||
|
if err != nil {
|
||||||
|
ffplay = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
|
MessageID: "errorFFplayVersion",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
h.menuView.About(ffmpeg, ffprobe)
|
h.menuView.About(ffmpeg, ffprobe, ffplay)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h MenuHandler) openGratitude() {
|
func (h MenuHandler) openGratitude() {
|
||||||
|
@ -32,8 +32,10 @@ type ConvertorContract interface {
|
|||||||
GetTotalDuration(file *File) (float64, error)
|
GetTotalDuration(file *File) (float64, error)
|
||||||
GetFFmpegVesrion() (string, error)
|
GetFFmpegVesrion() (string, error)
|
||||||
GetFFprobeVersion() (string, error)
|
GetFFprobeVersion() (string, error)
|
||||||
|
GetFFplayVersion() (string, error)
|
||||||
ChangeFFmpegPath(path string) (bool, error)
|
ChangeFFmpegPath(path string) (bool, error)
|
||||||
ChangeFFprobePath(path string) (bool, error)
|
ChangeFFprobePath(path string) (bool, error)
|
||||||
|
ChangeFFplayPath(path string) (bool, error)
|
||||||
GetRunningProcesses() map[int]*exec.Cmd
|
GetRunningProcesses() map[int]*exec.Cmd
|
||||||
GetSupportFormats() (encoder.ConvertorFormatsContract, error)
|
GetSupportFormats() (encoder.ConvertorFormatsContract, error)
|
||||||
}
|
}
|
||||||
@ -46,6 +48,7 @@ type ProgressContract interface {
|
|||||||
type FFPathUtilities struct {
|
type FFPathUtilities struct {
|
||||||
FFmpeg string
|
FFmpeg string
|
||||||
FFprobe string
|
FFprobe string
|
||||||
|
FFplay string
|
||||||
}
|
}
|
||||||
|
|
||||||
type runningProcesses struct {
|
type runningProcesses struct {
|
||||||
@ -177,6 +180,17 @@ func (s Convertor) GetFFprobeVersion() (string, error) {
|
|||||||
return text[0], nil
|
return text[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s Convertor) GetFFplayVersion() (string, error) {
|
||||||
|
cmd := exec.Command(s.ffPathUtilities.FFplay, "-version")
|
||||||
|
helper.PrepareBackgroundCommand(cmd)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
text := regexp.MustCompile("\r?\n").Split(strings.TrimSpace(string(out)), -1)
|
||||||
|
return text[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s Convertor) ChangeFFmpegPath(path string) (bool, error) {
|
func (s Convertor) ChangeFFmpegPath(path string) (bool, error) {
|
||||||
cmd := exec.Command(path, "-version")
|
cmd := exec.Command(path, "-version")
|
||||||
helper.PrepareBackgroundCommand(cmd)
|
helper.PrepareBackgroundCommand(cmd)
|
||||||
@ -205,6 +219,20 @@ func (s Convertor) ChangeFFprobePath(path string) (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s Convertor) ChangeFFplayPath(path string) (bool, error) {
|
||||||
|
cmd := exec.Command(path, "-version")
|
||||||
|
helper.PrepareBackgroundCommand(cmd)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if strings.Contains(strings.TrimSpace(string(out)), "ffplay") == false {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
s.ffPathUtilities.FFplay = path
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s Convertor) GetSupportFormats() (encoder.ConvertorFormatsContract, error) {
|
func (s Convertor) GetSupportFormats() (encoder.ConvertorFormatsContract, error) {
|
||||||
formats := encoder.NewConvertorFormats()
|
formats := encoder.NewConvertorFormats()
|
||||||
cmd := exec.Command(s.ffPathUtilities.FFmpeg, "-encoders")
|
cmd := exec.Command(s.ffPathUtilities.FFmpeg, "-encoders")
|
||||||
|
30
kernel/ffplay.go
Normal file
30
kernel/ffplay.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package kernel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/helper"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FFplay struct {
|
||||||
|
ffPathUtilities *FFPathUtilities
|
||||||
|
}
|
||||||
|
|
||||||
|
type FFplaySetting struct {
|
||||||
|
PathToFile string
|
||||||
|
}
|
||||||
|
|
||||||
|
type FFplayContract interface {
|
||||||
|
Run(setting FFplaySetting) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFFplay(ffPathUtilities *FFPathUtilities) *FFplay {
|
||||||
|
return &FFplay{ffPathUtilities: ffPathUtilities}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ffplay FFplay) Run(setting FFplaySetting) error {
|
||||||
|
args := []string{setting.PathToFile}
|
||||||
|
cmd := exec.Command(ffplay.ffPathUtilities.FFplay, args...)
|
||||||
|
helper.PrepareBackgroundCommand(cmd)
|
||||||
|
|
||||||
|
return cmd.Start()
|
||||||
|
}
|
@ -66,6 +66,7 @@ type QueueLayoutObject struct {
|
|||||||
items map[int]QueueLayoutItem
|
items map[int]QueueLayoutItem
|
||||||
localizerService LocalizerContract
|
localizerService LocalizerContract
|
||||||
queueStatisticsFormat *queueStatisticsFormat
|
queueStatisticsFormat *queueStatisticsFormat
|
||||||
|
ffplayService FFplayContract
|
||||||
}
|
}
|
||||||
|
|
||||||
type QueueLayoutItem struct {
|
type QueueLayoutItem struct {
|
||||||
@ -73,11 +74,12 @@ type QueueLayoutItem struct {
|
|||||||
ProgressBar *widget.ProgressBar
|
ProgressBar *widget.ProgressBar
|
||||||
StatusMessage *canvas.Text
|
StatusMessage *canvas.Text
|
||||||
MessageError *canvas.Text
|
MessageError *canvas.Text
|
||||||
|
buttonPlay *widget.Button
|
||||||
|
|
||||||
status *StatusContract
|
status *StatusContract
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewQueueLayoutObject(queue QueueListContract, localizerService LocalizerContract) *QueueLayoutObject {
|
func NewQueueLayoutObject(queue QueueListContract, localizerService LocalizerContract, ffplayService FFplayContract) *QueueLayoutObject {
|
||||||
title := widget.NewLabel(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "queue"}))
|
title := widget.NewLabel(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "queue"}))
|
||||||
title.TextStyle.Bold = true
|
title.TextStyle.Bold = true
|
||||||
|
|
||||||
@ -98,6 +100,7 @@ func NewQueueLayoutObject(queue QueueListContract, localizerService LocalizerCon
|
|||||||
items: items,
|
items: items,
|
||||||
localizerService: localizerService,
|
localizerService: localizerService,
|
||||||
queueStatisticsFormat: queueStatisticsFormat,
|
queueStatisticsFormat: queueStatisticsFormat,
|
||||||
|
ffplayService: ffplayService,
|
||||||
}
|
}
|
||||||
|
|
||||||
queue.AddListener(queueLayoutObject)
|
queue.AddListener(queueLayoutObject)
|
||||||
@ -121,11 +124,18 @@ func (o QueueLayoutObject) Add(id int, queue *Queue) {
|
|||||||
|
|
||||||
statusMessage := canvas.NewText(o.getStatusTitle(queue.Status), theme.Color(theme.ColorNamePrimary))
|
statusMessage := canvas.NewText(o.getStatusTitle(queue.Status), theme.Color(theme.ColorNamePrimary))
|
||||||
messageError := canvas.NewText("", theme.Color(theme.ColorNameError))
|
messageError := canvas.NewText("", theme.Color(theme.ColorNameError))
|
||||||
|
buttonPlay := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
|
||||||
|
|
||||||
|
})
|
||||||
|
buttonPlay.Hide()
|
||||||
|
|
||||||
content := container.NewVBox(
|
content := container.NewVBox(
|
||||||
container.NewHScroll(widget.NewLabel(queue.Setting.VideoFileInput.Name)),
|
container.NewHScroll(widget.NewLabel(queue.Setting.VideoFileInput.Name)),
|
||||||
progressBar,
|
progressBar,
|
||||||
container.NewHScroll(statusMessage),
|
container.NewHScroll(container.NewHBox(
|
||||||
|
buttonPlay,
|
||||||
|
statusMessage,
|
||||||
|
)),
|
||||||
container.NewHScroll(messageError),
|
container.NewHScroll(messageError),
|
||||||
canvas.NewLine(theme.Color(theme.ColorNameFocus)),
|
canvas.NewLine(theme.Color(theme.ColorNameFocus)),
|
||||||
container.NewPadded(),
|
container.NewPadded(),
|
||||||
@ -141,6 +151,7 @@ func (o QueueLayoutObject) Add(id int, queue *Queue) {
|
|||||||
ProgressBar: progressBar,
|
ProgressBar: progressBar,
|
||||||
StatusMessage: statusMessage,
|
StatusMessage: statusMessage,
|
||||||
MessageError: messageError,
|
MessageError: messageError,
|
||||||
|
buttonPlay: buttonPlay,
|
||||||
status: &queue.Status,
|
status: &queue.Status,
|
||||||
}
|
}
|
||||||
o.container.Add(content)
|
o.container.Add(content)
|
||||||
@ -169,6 +180,20 @@ func (o QueueLayoutObject) ChangeQueueStatus(queueId int, queue *Queue) {
|
|||||||
item.MessageError.Refresh()
|
item.MessageError.Refresh()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if queue.Status == StatusType(Completed) {
|
||||||
|
item.buttonPlay.Show()
|
||||||
|
item.buttonPlay.OnTapped = func() {
|
||||||
|
item.buttonPlay.Disable()
|
||||||
|
go func() {
|
||||||
|
_ = o.ffplayService.Run(FFplaySetting{
|
||||||
|
PathToFile: queue.Setting.VideoFileOut.Path,
|
||||||
|
})
|
||||||
|
fyne.Do(func() {
|
||||||
|
item.buttonPlay.Enable()
|
||||||
|
})
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
if o.queueStatisticsFormat.isChecked(queue.Status) == false && item.CanvasObject.Visible() == true {
|
if o.queueStatisticsFormat.isChecked(queue.Status) == false && item.CanvasObject.Visible() == true {
|
||||||
item.CanvasObject.Hide()
|
item.CanvasObject.Hide()
|
||||||
} else if item.CanvasObject.Visible() == false {
|
} else if item.CanvasObject.Visible() == false {
|
||||||
|
@ -83,5 +83,7 @@ func (w Window) GetLayout() LayoutContract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w Window) SetOnDropped(callback func(position fyne.Position, uris []fyne.URI)) {
|
func (w Window) SetOnDropped(callback func(position fyne.Position, uris []fyne.URI)) {
|
||||||
w.windowFyne.SetOnDropped(callback)
|
fyne.Do(func() {
|
||||||
|
w.windowFyne.SetOnDropped(callback)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@ hash = "sha1-0ec753be8df955a117404fb634b01b45eb386e2a"
|
|||||||
other = "Cancel"
|
other = "Cancel"
|
||||||
|
|
||||||
[changeFFPath]
|
[changeFFPath]
|
||||||
hash = "sha1-46793a2844600d0eb19fa3540fb9564ee5705491"
|
hash = "sha1-1f704de0560f8135eb6924cd232ed919ca2e5af0"
|
||||||
other = "FFmpeg and FFprobe"
|
other = "FFmpeg, FFprobe and FFplay"
|
||||||
|
|
||||||
[changeLanguage]
|
[changeLanguage]
|
||||||
hash = "sha1-8b276eaf378d485c769fb3d5dcc06dfc25b0c01b"
|
hash = "sha1-8b276eaf378d485c769fb3d5dcc06dfc25b0c01b"
|
||||||
@ -238,6 +238,14 @@ other = "this is not FFmpeg"
|
|||||||
hash = "sha1-9a4148d42186b6b32cf83bef726e23022c53283f"
|
hash = "sha1-9a4148d42186b6b32cf83bef726e23022c53283f"
|
||||||
other = "Could not determine FFmpeg version"
|
other = "Could not determine FFmpeg version"
|
||||||
|
|
||||||
|
[errorFFplay]
|
||||||
|
hash = "sha1-988122112ac6002094e25518cfb5f0d606217298"
|
||||||
|
other = "this is not FFplay"
|
||||||
|
|
||||||
|
[errorFFplayVersion]
|
||||||
|
hash = "sha1-cd60928d20d93210e103dd464306ab138bf1b184"
|
||||||
|
other = "Could not determine FFplay version"
|
||||||
|
|
||||||
[errorFFprobe]
|
[errorFFprobe]
|
||||||
hash = "sha1-86d1b0b4c4ccd6a4f71e758fc67ce11aff4ba9b8"
|
hash = "sha1-86d1b0b4c4ccd6a4f71e758fc67ce11aff4ba9b8"
|
||||||
other = "this is not FFprobe"
|
other = "this is not FFprobe"
|
||||||
@ -330,6 +338,10 @@ other = "Enable option"
|
|||||||
hash = "sha1-fafc50f1db0f720fe83a96cd70a9e1ad824e96b6"
|
hash = "sha1-fafc50f1db0f720fe83a96cd70a9e1ad824e96b6"
|
||||||
other = "Path to FFmpeg:"
|
other = "Path to FFmpeg:"
|
||||||
|
|
||||||
|
[pathToFfplay]
|
||||||
|
hash = "sha1-5389830dd75a63aa8a5e41e8f07c5fadd8385398"
|
||||||
|
other = "Path to FFplay:"
|
||||||
|
|
||||||
[pathToFfprobe]
|
[pathToFfprobe]
|
||||||
hash = "sha1-b872edc9633a2e81ef678dc46fe46a7e91732024"
|
hash = "sha1-b872edc9633a2e81ef678dc46fe46a7e91732024"
|
||||||
other = "Path to FFprobe:"
|
other = "Path to FFprobe:"
|
||||||
|
@ -23,8 +23,8 @@ hash = "sha1-0ec753be8df955a117404fb634b01b45eb386e2a"
|
|||||||
other = "Болдырмау"
|
other = "Болдырмау"
|
||||||
|
|
||||||
[changeFFPath]
|
[changeFFPath]
|
||||||
hash = "sha1-46793a2844600d0eb19fa3540fb9564ee5705491"
|
hash = "sha1-1f704de0560f8135eb6924cd232ed919ca2e5af0"
|
||||||
other = "FFmpeg және FFprobe"
|
other = "FFmpeg, FFprobe және FFplay"
|
||||||
|
|
||||||
[changeLanguage]
|
[changeLanguage]
|
||||||
hash = "sha1-8b276eaf378d485c769fb3d5dcc06dfc25b0c01b"
|
hash = "sha1-8b276eaf378d485c769fb3d5dcc06dfc25b0c01b"
|
||||||
@ -238,6 +238,14 @@ other = "бұл FFmpeg емес"
|
|||||||
hash = "sha1-9a4148d42186b6b32cf83bef726e23022c53283f"
|
hash = "sha1-9a4148d42186b6b32cf83bef726e23022c53283f"
|
||||||
other = "FFmpeg нұсқасын анықтау мүмкін болмады"
|
other = "FFmpeg нұсқасын анықтау мүмкін болмады"
|
||||||
|
|
||||||
|
[errorFFplay]
|
||||||
|
hash = "sha1-988122112ac6002094e25518cfb5f0d606217298"
|
||||||
|
other = "бұл FFplay емес"
|
||||||
|
|
||||||
|
[errorFFplayVersion]
|
||||||
|
hash = "sha1-cd60928d20d93210e103dd464306ab138bf1b184"
|
||||||
|
other = "FFplay нұсқасын анықтау мүмкін болмады"
|
||||||
|
|
||||||
[errorFFprobe]
|
[errorFFprobe]
|
||||||
hash = "sha1-86d1b0b4c4ccd6a4f71e758fc67ce11aff4ba9b8"
|
hash = "sha1-86d1b0b4c4ccd6a4f71e758fc67ce11aff4ba9b8"
|
||||||
other = "бұл FFprobe емес"
|
other = "бұл FFprobe емес"
|
||||||
@ -330,6 +338,10 @@ other = "Опцияны қосу"
|
|||||||
hash = "sha1-fafc50f1db0f720fe83a96cd70a9e1ad824e96b6"
|
hash = "sha1-fafc50f1db0f720fe83a96cd70a9e1ad824e96b6"
|
||||||
other = "FFmpeg жол:"
|
other = "FFmpeg жол:"
|
||||||
|
|
||||||
|
[pathToFfplay]
|
||||||
|
hash = "sha1-5389830dd75a63aa8a5e41e8f07c5fadd8385398"
|
||||||
|
other = "FFplay жол:"
|
||||||
|
|
||||||
[pathToFfprobe]
|
[pathToFfprobe]
|
||||||
hash = "sha1-b872edc9633a2e81ef678dc46fe46a7e91732024"
|
hash = "sha1-b872edc9633a2e81ef678dc46fe46a7e91732024"
|
||||||
other = "FFprobe жол:"
|
other = "FFprobe жол:"
|
||||||
|
@ -4,7 +4,7 @@ aboutText = "Простенький интерфейс для консольно
|
|||||||
buttonDownloadFFmpeg = "Скачать автоматически FFmpeg"
|
buttonDownloadFFmpeg = "Скачать автоматически FFmpeg"
|
||||||
buttonForSelectedDirTitle = "Сохранить в папку:"
|
buttonForSelectedDirTitle = "Сохранить в папку:"
|
||||||
cancel = "Отмена"
|
cancel = "Отмена"
|
||||||
changeFFPath = "FFmpeg и FFprobe"
|
changeFFPath = "FFmpeg, FFprobe и FFplay"
|
||||||
changeLanguage = "Поменять язык"
|
changeLanguage = "Поменять язык"
|
||||||
checkboxOverwriteOutputFilesTitle = "Разрешить перезаписать файл"
|
checkboxOverwriteOutputFilesTitle = "Разрешить перезаписать файл"
|
||||||
choose = "выбрать"
|
choose = "выбрать"
|
||||||
@ -58,6 +58,8 @@ errorDatabaseTimeout = "Не смогли открыть файл конфигу
|
|||||||
errorDragAndDrop1File = "Можно перетащить только 1 файл"
|
errorDragAndDrop1File = "Можно перетащить только 1 файл"
|
||||||
errorFFmpeg = "это не FFmpeg"
|
errorFFmpeg = "это не FFmpeg"
|
||||||
errorFFmpegVersion = "Не смогли определить версию FFmpeg"
|
errorFFmpegVersion = "Не смогли определить версию FFmpeg"
|
||||||
|
errorFFplay = "это не FFplay"
|
||||||
|
errorFFplayVersion = "Не смогли определить версию FFplay"
|
||||||
errorFFprobe = "это не FFprobe"
|
errorFFprobe = "это не FFprobe"
|
||||||
errorFFprobeVersion = "Не смогли определить версию FFprobe"
|
errorFFprobeVersion = "Не смогли определить версию FFprobe"
|
||||||
errorIsFolder = "Можно перетаскивать только файл"
|
errorIsFolder = "Можно перетаскивать только файл"
|
||||||
@ -81,6 +83,7 @@ licenseLinkOther = "Лицензии от других продуктов, ко
|
|||||||
or = "или"
|
or = "или"
|
||||||
parameterCheckbox = "Включить параметр"
|
parameterCheckbox = "Включить параметр"
|
||||||
pathToFfmpeg = "Путь к FFmpeg:"
|
pathToFfmpeg = "Путь к FFmpeg:"
|
||||||
|
pathToFfplay = "Путь к FFplay:"
|
||||||
pathToFfprobe = "Путь к FFprobe:"
|
pathToFfprobe = "Путь к FFprobe:"
|
||||||
preset_fast = "fast (медленней чем faster, но будет файл и меньше весить)"
|
preset_fast = "fast (медленней чем faster, но будет файл и меньше весить)"
|
||||||
preset_faster = "faster (медленней чем veryfast, но будет файл и меньше весить)"
|
preset_faster = "faster (медленней чем veryfast, но будет файл и меньше весить)"
|
||||||
|
13
main.go
13
main.go
@ -36,15 +36,16 @@ func init() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ffPathUtilities = &kernel.FFPathUtilities{FFmpeg: "", FFprobe: ""}
|
ffPathUtilities = &kernel.FFPathUtilities{FFmpeg: "", FFprobe: "", FFplay: ""}
|
||||||
convertorService := kernel.NewService(ffPathUtilities)
|
convertorService := kernel.NewService(ffPathUtilities)
|
||||||
|
ffplayService := kernel.NewFFplay(ffPathUtilities)
|
||||||
|
|
||||||
queue := kernel.NewQueueList()
|
queue := kernel.NewQueueList()
|
||||||
application = kernel.NewApp(
|
application = kernel.NewApp(
|
||||||
appMetadata,
|
appMetadata,
|
||||||
localizerService,
|
localizerService,
|
||||||
queue,
|
queue,
|
||||||
kernel.NewQueueLayoutObject(queue, localizerService),
|
kernel.NewQueueLayoutObject(queue, localizerService, ffplayService),
|
||||||
convertorService,
|
convertorService,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -93,6 +94,14 @@ func main() {
|
|||||||
}
|
}
|
||||||
ffPathUtilities.FFprobe = pathFFprobe
|
ffPathUtilities.FFprobe = pathFFprobe
|
||||||
|
|
||||||
|
pathFFplay, err := convertorRepository.GetPathFfplay()
|
||||||
|
if err != nil && errors.Is(err, dberror.ErrRecordNotFound) == false {
|
||||||
|
errorView.PanicError(err)
|
||||||
|
application.GetWindow().ShowAndRun()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ffPathUtilities.FFplay = pathFFplay
|
||||||
|
|
||||||
application.RunConvertor()
|
application.RunConvertor()
|
||||||
defer application.AfterClosing()
|
defer application.AfterClosing()
|
||||||
|
|
||||||
|
35
menu/view.go
35
menu/view.go
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ViewContract interface {
|
type ViewContract interface {
|
||||||
About(ffmpegVersion string, ffprobeVersion string)
|
About(ffmpegVersion string, ffprobeVersion string, ffplayVersion string)
|
||||||
Gratitude()
|
Gratitude()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ func (v View) Gratitude() {
|
|||||||
view.Show()
|
view.Show()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v View) About(ffmpegVersion string, ffprobeVersion string) {
|
func (v View) About(ffmpegVersion string, ffprobeVersion string, ffplayVersion string) {
|
||||||
view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
view := v.app.GetAppFyne().NewWindow(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
MessageID: "about",
|
MessageID: "about",
|
||||||
}))
|
}))
|
||||||
@ -134,6 +134,7 @@ func (v View) About(ffmpegVersion string, ffprobeVersion string) {
|
|||||||
)),
|
)),
|
||||||
v.getAboutFfmpeg(ffmpegVersion),
|
v.getAboutFfmpeg(ffmpegVersion),
|
||||||
v.getAboutFfprobe(ffprobeVersion),
|
v.getAboutFfprobe(ffprobeVersion),
|
||||||
|
v.getAboutFfplay(ffplayVersion),
|
||||||
widget.NewCard(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
widget.NewCard(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
MessageID: "AlsoUsedProgram",
|
MessageID: "AlsoUsedProgram",
|
||||||
}), "", v.getOther()),
|
}), "", v.getOther()),
|
||||||
@ -207,6 +208,36 @@ func (v View) getAboutFfprobe(version string) *fyne.Container {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v View) getAboutFfplay(version string) *fyne.Container {
|
||||||
|
programmName := canvas.NewText(" FFplay", colornames.Darkgreen)
|
||||||
|
programmName.TextStyle = fyne.TextStyle{Bold: true}
|
||||||
|
programmName.TextSize = 20
|
||||||
|
|
||||||
|
programmLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
|
MessageID: "programmLink",
|
||||||
|
}), &url.URL{
|
||||||
|
Scheme: "https",
|
||||||
|
Host: "ffmpeg.org",
|
||||||
|
Path: "ffplay.html",
|
||||||
|
})
|
||||||
|
|
||||||
|
licenseLink := widget.NewHyperlink(v.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
||||||
|
MessageID: "licenseLink",
|
||||||
|
}), &url.URL{
|
||||||
|
Scheme: "https",
|
||||||
|
Host: "ffmpeg.org",
|
||||||
|
Path: "legal.html",
|
||||||
|
})
|
||||||
|
|
||||||
|
return container.NewVBox(
|
||||||
|
programmName,
|
||||||
|
widget.NewLabel(version),
|
||||||
|
widget.NewRichTextFromMarkdown("**FFmpeg** is a trademark of **[Fabrice Bellard](http://bellard.org/)**, originator of the **[FFmpeg](https://ffmpeg.org/about.html)** project."),
|
||||||
|
widget.NewRichTextFromMarkdown("This software uses libraries from the **FFmpeg** project under the **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**."),
|
||||||
|
container.NewHBox(programmLink, licenseLink),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func (v View) getOther() *fyne.Container {
|
func (v View) getOther() *fyne.Container {
|
||||||
return container.NewVBox(
|
return container.NewVBox(
|
||||||
canvas.NewLine(colornames.Darkgreen),
|
canvas.NewLine(colornames.Darkgreen),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user