Integrated FFplay functionality across the application. This includes support for setting up the FFplay path and invoking FFplay for media playback.
195 lines
4.1 KiB
Go
195 lines
4.1 KiB
Go
//go:build windows
|
|
// +build windows
|
|
|
|
package handler
|
|
|
|
import (
|
|
"archive/zip"
|
|
"errors"
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/canvas"
|
|
"fyne.io/fyne/v2/widget"
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
|
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
func getPathsToFF() []kernel.FFPathUtilities {
|
|
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) {
|
|
isDirectoryFFmpeg := isDirectory("ffmpeg")
|
|
if isDirectoryFFmpeg == false {
|
|
err = os.Mkdir("ffmpeg", 0777)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
|
MessageID: "downloadRun",
|
|
})
|
|
fyne.Do(func() {
|
|
progressMessage.Refresh()
|
|
})
|
|
err = downloadFile("ffmpeg/ffmpeg.zip", "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip", progressBar)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
|
MessageID: "unzipRun",
|
|
})
|
|
fyne.Do(func() {
|
|
progressMessage.Refresh()
|
|
})
|
|
err = unZip("ffmpeg/ffmpeg.zip", "ffmpeg", progressBar)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_ = os.Remove("ffmpeg/ffmpeg.zip")
|
|
|
|
progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
|
MessageID: "testFF",
|
|
})
|
|
fyne.Do(func() {
|
|
progressMessage.Refresh()
|
|
})
|
|
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 {
|
|
return err
|
|
}
|
|
|
|
progressMessage.Text = h.app.GetLocalizerService().GetMessage(&i18n.LocalizeConfig{
|
|
MessageID: "completedQueue",
|
|
})
|
|
fyne.Do(func() {
|
|
progressMessage.Refresh()
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
func downloadFile(filepath string, url string, progressBar *widget.ProgressBar) (err error) {
|
|
progressBar.Value = 0
|
|
progressBar.Max = 100
|
|
|
|
req, err := http.NewRequest("GET", url, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
f, err := os.OpenFile(filepath, os.O_CREATE|os.O_WRONLY, 0644)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
buf := make([]byte, 32*1024)
|
|
var downloaded int64
|
|
for {
|
|
n, err := resp.Body.Read(buf)
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
return err
|
|
}
|
|
if n > 0 {
|
|
f.Write(buf[:n])
|
|
downloaded += int64(n)
|
|
progressBar.Value = float64(downloaded) / float64(resp.ContentLength) * 100
|
|
fyne.Do(func() {
|
|
progressBar.Refresh()
|
|
})
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func unZip(fileZip string, directory string, progressBar *widget.ProgressBar) error {
|
|
progressBar.Value = 0
|
|
progressBar.Max = 100
|
|
|
|
fyne.Do(func() {
|
|
progressBar.Refresh()
|
|
})
|
|
|
|
archive, err := zip.OpenReader(fileZip)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer archive.Close()
|
|
|
|
totalBytes := int64(0)
|
|
for _, f := range archive.File {
|
|
totalBytes += int64(f.UncompressedSize64)
|
|
}
|
|
|
|
unpackedBytes := int64(0)
|
|
|
|
for _, f := range archive.File {
|
|
filePath := filepath.Join(directory, f.Name)
|
|
|
|
if !strings.HasPrefix(filePath, filepath.Clean(directory)+string(os.PathSeparator)) {
|
|
return errors.New("invalid file path")
|
|
}
|
|
if f.FileInfo().IsDir() {
|
|
os.MkdirAll(filePath, os.ModePerm)
|
|
continue
|
|
}
|
|
|
|
if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
|
|
return err
|
|
}
|
|
|
|
dstFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fileInArchive, err := f.Open()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
bytesRead, err := io.Copy(dstFile, fileInArchive)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
unpackedBytes += bytesRead
|
|
progressBar.Value = float64(unpackedBytes) / float64(totalBytes) * 100
|
|
fyne.Do(func() {
|
|
progressBar.Refresh()
|
|
})
|
|
|
|
dstFile.Close()
|
|
fileInArchive.Close()
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func isDirectory(path string) bool {
|
|
fileInfo, err := os.Stat(path)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return fileInfo.IsDir()
|
|
}
|