.update ffmpeg + linux arm build
This commit is contained in:
+56
-41
@@ -81,13 +81,13 @@ jobs:
|
||||
- name: Prepare artifacts
|
||||
run: |
|
||||
mkdir -p dist
|
||||
Copy-Item -Path "build\bin\SpotiFLAC.exe" -Destination "dist\SpotiFLAC.exe"
|
||||
Compress-Archive -Path "build\bin\SpotiFLAC.exe" -DestinationPath "dist\SpotiFLAC-windows.zip" -Force
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows-portable
|
||||
path: dist/SpotiFLAC.exe
|
||||
name: windows-bundle
|
||||
path: dist/SpotiFLAC-windows.zip
|
||||
retention-days: 7
|
||||
|
||||
build-macos:
|
||||
@@ -147,36 +147,33 @@ jobs:
|
||||
- name: Build application
|
||||
run: wails build -platform darwin/universal
|
||||
|
||||
- name: Create DMG
|
||||
- name: Create macOS bundle
|
||||
run: |
|
||||
mkdir -p dist
|
||||
# Install create-dmg if not available
|
||||
brew install create-dmg || true
|
||||
|
||||
# Create DMG
|
||||
create-dmg \
|
||||
--volname "SpotiFLAC" \
|
||||
--window-pos 200 120 \
|
||||
--window-size 600 400 \
|
||||
--icon-size 100 \
|
||||
--icon "SpotiFLAC.app" 175 120 \
|
||||
--hide-extension "SpotiFLAC.app" \
|
||||
--app-drop-link 425 120 \
|
||||
"dist/SpotiFLAC.dmg" \
|
||||
"build/bin/SpotiFLAC.app" || \
|
||||
# Fallback to hdiutil if create-dmg fails
|
||||
hdiutil create -volname SpotiFLAC -srcfolder build/bin/SpotiFLAC.app -ov -format UDZO dist/SpotiFLAC.dmg
|
||||
ditto -c -k --sequesterRsrc --keepParent "build/bin/SpotiFLAC.app" "dist/SpotiFLAC-macos-bundle.zip"
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: macos-portable
|
||||
path: dist/SpotiFLAC.dmg
|
||||
name: macos-bundle
|
||||
path: dist/SpotiFLAC-macos-bundle.zip
|
||||
retention-days: 7
|
||||
|
||||
build-linux:
|
||||
name: Build Linux
|
||||
runs-on: ubuntu-24.04
|
||||
name: Build Linux (${{ matrix.arch }})
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: amd64
|
||||
goarch: amd64
|
||||
runner: ubuntu-24.04
|
||||
appimage_arch: x86_64
|
||||
- arch: arm64
|
||||
goarch: arm64
|
||||
runner: ubuntu-24.04-arm
|
||||
appimage_arch: aarch64
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
@@ -222,10 +219,15 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libfuse2 imagemagick upx-ucl
|
||||
PACKAGES="libgtk-3-dev libwebkit2gtk-4.1-dev libfuse2 imagemagick"
|
||||
if [ "${{ matrix.goarch }}" = "amd64" ]; then
|
||||
PACKAGES="$PACKAGES upx-ucl"
|
||||
fi
|
||||
sudo apt-get install -y $PACKAGES
|
||||
|
||||
# Create symlink for webkit2gtk-4.0 -> webkit2gtk-4.1 (Ubuntu 24.04 compatibility)
|
||||
sudo ln -sf /usr/lib/x86_64-linux-gnu/pkgconfig/webkit2gtk-4.1.pc /usr/lib/x86_64-linux-gnu/pkgconfig/webkit2gtk-4.0.pc
|
||||
MULTIARCH="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
|
||||
sudo ln -sf "/usr/lib/${MULTIARCH}/pkgconfig/webkit2gtk-4.1.pc" "/usr/lib/${MULTIARCH}/pkgconfig/webkit2gtk-4.0.pc"
|
||||
|
||||
- name: Install Wails CLI
|
||||
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
|
||||
@@ -237,9 +239,10 @@ jobs:
|
||||
pnpm run generate-icon
|
||||
|
||||
- name: Build application
|
||||
run: wails build -platform linux/amd64
|
||||
run: wails build -platform linux/${{ matrix.goarch }}
|
||||
|
||||
- name: Compress with UPX
|
||||
if: matrix.goarch == 'amd64'
|
||||
run: |
|
||||
upx --best --lzma build/bin/SpotiFLAC
|
||||
|
||||
@@ -248,13 +251,13 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: appimagetool
|
||||
key: appimagetool-x86_64-v1
|
||||
key: appimagetool-${{ matrix.appimage_arch }}-v1
|
||||
|
||||
- name: Download appimagetool
|
||||
if: steps.cache-appimagetool.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
wget --timeout=30 --tries=5 --retry-connrefused --waitretry=5 -O appimagetool https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage || \
|
||||
wget --timeout=30 --tries=5 --retry-connrefused --waitretry=5 -O appimagetool https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage
|
||||
wget --timeout=30 --tries=5 --retry-connrefused --waitretry=5 -O appimagetool https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-${{ matrix.appimage_arch }}.AppImage || \
|
||||
wget --timeout=30 --tries=5 --retry-connrefused --waitretry=5 -O appimagetool https://github.com/AppImage/appimagetool/releases/download/1.9.1/appimagetool-${{ matrix.appimage_arch }}.AppImage
|
||||
|
||||
- name: Make appimagetool executable
|
||||
run: chmod +x appimagetool
|
||||
@@ -309,13 +312,13 @@ jobs:
|
||||
|
||||
# Create AppImage
|
||||
mkdir -p dist
|
||||
ARCH=x86_64 ./appimagetool --no-appstream AppDir dist/SpotiFLAC.AppImage
|
||||
ARCH=${{ matrix.appimage_arch }} ./appimagetool --no-appstream AppDir dist/SpotiFLAC-linux-${{ matrix.arch }}.AppImage
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: linux-portable
|
||||
path: dist/SpotiFLAC.AppImage
|
||||
name: linux-appimage-${{ matrix.arch }}
|
||||
path: dist/SpotiFLAC-linux-${{ matrix.arch }}.AppImage
|
||||
retention-days: 7
|
||||
|
||||
create-release:
|
||||
@@ -343,6 +346,13 @@ jobs:
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R artifacts
|
||||
|
||||
- name: Create Linux bundle
|
||||
run: |
|
||||
mkdir -p release/SpotiFLAC-linux-bundle
|
||||
cp artifacts/linux-appimage-amd64/*.AppImage release/SpotiFLAC-linux-bundle/
|
||||
cp artifacts/linux-appimage-arm64/*.AppImage release/SpotiFLAC-linux-bundle/
|
||||
tar -czf release/SpotiFLAC-linux-bundle.tar.gz -C release SpotiFLAC-linux-bundle
|
||||
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
@@ -354,15 +364,20 @@ jobs:
|
||||
|
||||
## Downloads
|
||||
|
||||
- `SpotiFLAC.exe` - Windows
|
||||
- `SpotiFLAC.dmg` - macOS
|
||||
- `SpotiFLAC.AppImage` - Linux
|
||||
- `SpotiFLAC-windows.zip` - amd64
|
||||
- `SpotiFLAC-macos-bundle.zip` - amd64 + arm64
|
||||
- `SpotiFLAC-linux-bundle.tar.gz` - amd64 + arm64v8
|
||||
|
||||
<details>
|
||||
<summary><b>Linux Requirements</b></summary>
|
||||
|
||||
The AppImage requires `webkit2gtk-4.1` to be installed on your system:
|
||||
|
||||
Choose the correct AppImage after extracting the bundle:
|
||||
|
||||
- `SpotiFLAC-linux-amd64.AppImage` - amd64
|
||||
- `SpotiFLAC-linux-arm64.AppImage` - arm64v8
|
||||
|
||||
**Ubuntu/Debian:**
|
||||
```bash
|
||||
sudo apt install libwebkit2gtk-4.1-0
|
||||
@@ -380,14 +395,14 @@ jobs:
|
||||
|
||||
After installing the dependency, make the AppImage executable:
|
||||
```bash
|
||||
chmod +x SpotiFLAC.AppImage
|
||||
./SpotiFLAC.AppImage
|
||||
tar -xzf SpotiFLAC-linux-bundle.tar.gz
|
||||
chmod +x SpotiFLAC-linux-*.AppImage
|
||||
```
|
||||
|
||||
</details>
|
||||
files: |
|
||||
artifacts/windows-portable/*.exe
|
||||
artifacts/macos-portable/*.dmg
|
||||
artifacts/linux-portable/*.AppImage
|
||||
artifacts/windows-bundle/*.zip
|
||||
artifacts/macos-bundle/*.zip
|
||||
release/SpotiFLAC-linux-bundle.tar.gz
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
+89
-96
@@ -83,6 +83,37 @@ func GetFFmpegDir() (string, error) {
|
||||
return EnsureAppDir()
|
||||
}
|
||||
|
||||
func resolveSystemExecutable(executableName string) string {
|
||||
if runtime.GOOS == "darwin" {
|
||||
candidates := []string{
|
||||
"/opt/homebrew/bin/" + executableName,
|
||||
"/usr/local/bin/" + executableName,
|
||||
}
|
||||
for _, candidate := range candidates {
|
||||
if _, err := os.Stat(candidate); err == nil {
|
||||
return candidate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if runtime.GOOS != "windows" {
|
||||
path, err := exec.Command("which", executableName).Output()
|
||||
if err == nil {
|
||||
trimmed := strings.TrimSpace(string(path))
|
||||
if trimmed != "" {
|
||||
return trimmed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
path, err := exec.LookPath(executableName)
|
||||
if err == nil {
|
||||
return path
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func GetFFmpegPath() (string, error) {
|
||||
ffmpegDir, err := GetFFmpegDir()
|
||||
if err != nil {
|
||||
@@ -94,38 +125,15 @@ func GetFFmpegPath() (string, error) {
|
||||
ffmpegName = "ffmpeg.exe"
|
||||
}
|
||||
|
||||
if path := resolveSystemExecutable(ffmpegName); path != "" {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
localPath := filepath.Join(ffmpegDir, ffmpegName)
|
||||
if _, err := os.Stat(localPath); err == nil {
|
||||
return localPath, nil
|
||||
}
|
||||
|
||||
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
|
||||
homebrewPath := "/opt/homebrew/bin/" + ffmpegName
|
||||
if _, err := os.Stat(homebrewPath); err == nil {
|
||||
return homebrewPath, nil
|
||||
}
|
||||
} else if runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" {
|
||||
homebrewPath := "/usr/local/bin/" + ffmpegName
|
||||
if _, err := os.Stat(homebrewPath); err == nil {
|
||||
return homebrewPath, nil
|
||||
}
|
||||
}
|
||||
|
||||
if runtime.GOOS != "windows" {
|
||||
path, err := exec.Command("which", ffmpegName).Output()
|
||||
if err == nil {
|
||||
trimmed := strings.TrimSpace(string(path))
|
||||
if trimmed != "" {
|
||||
return trimmed, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
path, err := exec.LookPath(ffmpegName)
|
||||
if err == nil {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
return localPath, nil
|
||||
}
|
||||
|
||||
@@ -140,38 +148,15 @@ func GetFFprobePath() (string, error) {
|
||||
ffprobeName = "ffprobe.exe"
|
||||
}
|
||||
|
||||
if path := resolveSystemExecutable(ffprobeName); path != "" {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
localPath := filepath.Join(ffmpegDir, ffprobeName)
|
||||
if _, err := os.Stat(localPath); err == nil {
|
||||
return localPath, nil
|
||||
}
|
||||
|
||||
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
|
||||
homebrewPath := "/opt/homebrew/bin/" + ffprobeName
|
||||
if _, err := os.Stat(homebrewPath); err == nil {
|
||||
return homebrewPath, nil
|
||||
}
|
||||
} else if runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" {
|
||||
homebrewPath := "/usr/local/bin/" + ffprobeName
|
||||
if _, err := os.Stat(homebrewPath); err == nil {
|
||||
return homebrewPath, nil
|
||||
}
|
||||
}
|
||||
|
||||
if runtime.GOOS != "windows" {
|
||||
path, err := exec.Command("which", ffprobeName).Output()
|
||||
if err == nil {
|
||||
trimmed := strings.TrimSpace(string(path))
|
||||
if trimmed != "" {
|
||||
return trimmed, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
path, err := exec.LookPath(ffprobeName)
|
||||
if err == nil {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
return localPath, fmt.Errorf("ffprobe not found in app directory or system path")
|
||||
}
|
||||
|
||||
@@ -205,7 +190,11 @@ func IsFFmpegInstalled() (bool, error) {
|
||||
|
||||
setHideWindow(cmd)
|
||||
err = cmd.Run()
|
||||
return err == nil, nil
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return IsFFprobeInstalled()
|
||||
}
|
||||
|
||||
func GetBrewPath() string {
|
||||
@@ -255,10 +244,38 @@ func InstallFFmpegWithBrew(progressCallback func(int, string)) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
ffmpegWindowsURL = "https://github.com/afkarxyz/ffmpeg-binaries/releases/download/v8.0/ffmpeg-windows-amd64.zip"
|
||||
ffmpegLinuxURL = "https://github.com/afkarxyz/ffmpeg-binaries/releases/download/v8.0/ffmpeg-linux-amd64.tar.xz"
|
||||
)
|
||||
const ffmpegReleaseBaseURL = "https://github.com/afkarxyz/ffmpeg-binaries/releases/download/v8.1"
|
||||
|
||||
func buildFFmpegReleaseURL(assetName string) string {
|
||||
return ffmpegReleaseBaseURL + "/" + assetName
|
||||
}
|
||||
|
||||
func getFFmpegDownloadURLs() ([]string, []string, error) {
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
return []string{buildFFmpegReleaseURL("ffmpeg-windows.zip")}, []string{buildFFmpegReleaseURL("ffprobe-windows.zip")}, nil
|
||||
case "linux":
|
||||
switch runtime.GOARCH {
|
||||
case "amd64":
|
||||
return []string{buildFFmpegReleaseURL("ffmpeg-linux-amd64.zip")}, []string{buildFFmpegReleaseURL("ffprobe-linux-amd64.zip")}, nil
|
||||
case "arm64":
|
||||
return []string{buildFFmpegReleaseURL("ffmpeg-linux-arm64v8.zip")}, []string{buildFFmpegReleaseURL("ffprobe-linux-arm64v8.zip")}, nil
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unsupported Linux architecture: %s", runtime.GOARCH)
|
||||
}
|
||||
case "darwin":
|
||||
switch runtime.GOARCH {
|
||||
case "amd64":
|
||||
return []string{buildFFmpegReleaseURL("ffmpeg-macos-amd64.zip")}, []string{buildFFmpegReleaseURL("ffprobe-macos-amd64.zip")}, nil
|
||||
case "arm64":
|
||||
return []string{buildFFmpegReleaseURL("ffmpeg-macos-arm64.zip")}, []string{buildFFmpegReleaseURL("ffprobe-macos-arm64.zip")}, nil
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unsupported macOS architecture: %s", runtime.GOARCH)
|
||||
}
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
||||
}
|
||||
}
|
||||
|
||||
func DownloadFFmpeg(progressCallback func(int)) error {
|
||||
|
||||
@@ -276,57 +293,30 @@ func DownloadFFmpeg(progressCallback func(int)) error {
|
||||
return fmt.Errorf("failed to create ffmpeg directory: %w", err)
|
||||
}
|
||||
|
||||
if runtime.GOOS == "darwin" {
|
||||
ffmpegInstalled, _ := IsFFmpegInstalled()
|
||||
ffprobeInstalled, _ := IsFFprobeInstalled()
|
||||
|
||||
isARM := runtime.GOARCH == "arm64"
|
||||
|
||||
var macFFmpegURLs []string
|
||||
var macFFprobeURLs []string
|
||||
|
||||
if isARM {
|
||||
|
||||
macFFmpegURLs = []string{"https://github.com/afkarxyz/ffmpeg-binaries/releases/download/v8.0/ffmpeg-macos-arm64.zip"}
|
||||
macFFprobeURLs = []string{"https://github.com/afkarxyz/ffmpeg-binaries/releases/download/v8.0/ffprobe-macos-arm64.zip"}
|
||||
} else {
|
||||
|
||||
macFFmpegURLs = []string{"https://github.com/afkarxyz/ffmpeg-binaries/releases/download/v8.0/ffmpeg-macos-intel.zip"}
|
||||
macFFprobeURLs = []string{"https://github.com/afkarxyz/ffmpeg-binaries/releases/download/v8.0/ffprobe-macos-intel.zip"}
|
||||
ffmpegURLs, ffprobeURLs, err := getFFmpegDownloadURLs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !ffmpegInstalled && !ffprobeInstalled {
|
||||
if err := downloadWithFallback(macFFmpegURLs, ffmpegDir, progressCallback, 0, 50); err != nil {
|
||||
if err := downloadWithFallback(ffmpegURLs, ffmpegDir, progressCallback, 0, 50); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := downloadWithFallback(macFFprobeURLs, ffmpegDir, progressCallback, 50, 100); err != nil {
|
||||
if err := downloadWithFallback(ffprobeURLs, ffmpegDir, progressCallback, 50, 100); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if !ffmpegInstalled {
|
||||
if err := downloadWithFallback(macFFmpegURLs, ffmpegDir, progressCallback, 0, 100); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if !ffprobeInstalled {
|
||||
if err := downloadWithFallback(macFFprobeURLs, ffmpegDir, progressCallback, 0, 100); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var url string
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
url = ffmpegWindowsURL
|
||||
case "linux":
|
||||
url = ffmpegLinuxURL
|
||||
default:
|
||||
return fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
||||
if !ffmpegInstalled {
|
||||
return downloadWithFallback(ffmpegURLs, ffmpegDir, progressCallback, 0, 100)
|
||||
}
|
||||
|
||||
fmt.Printf("[FFmpeg] Downloading from: %s\n", url)
|
||||
if err := downloadAndExtract(url, ffmpegDir, progressCallback, 0, 100); err != nil {
|
||||
return err
|
||||
if !ffprobeInstalled {
|
||||
return downloadWithFallback(ffprobeURLs, ffmpegDir, progressCallback, 0, 100)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -452,11 +442,14 @@ func downloadAndExtract(url, destDir string, progressCallback func(int), progres
|
||||
}
|
||||
fmt.Printf("[FFmpeg] Extracting...\n")
|
||||
|
||||
if strings.HasSuffix(url, ".tar.xz") || runtime.GOOS == "linux" {
|
||||
if strings.HasSuffix(url, ".tar.xz") {
|
||||
return extractTarXz(tmpFile.Name(), destDir)
|
||||
}
|
||||
if strings.HasSuffix(url, ".zip") {
|
||||
return extractZip(tmpFile.Name(), destDir)
|
||||
}
|
||||
return fmt.Errorf("unsupported archive format for %s", url)
|
||||
}
|
||||
|
||||
func extractZip(zipPath, destDir string) error {
|
||||
r, err := zip.OpenReader(zipPath)
|
||||
|
||||
+10
-19
@@ -5,7 +5,7 @@ import { Search, X, ArrowUp } from "lucide-react";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { getSettings, getSettingsWithDefaults, loadSettings, saveSettings, applyThemeMode, applyFont } from "@/lib/settings";
|
||||
import { applyTheme } from "@/lib/themes";
|
||||
import { OpenFolder, CheckFFmpegInstalled, DownloadFFmpeg, GetBrewPath, GetRecentFetches, InstallFFmpegWithBrew, SaveRecentFetches } from "../wailsjs/go/main/App";
|
||||
import { OpenFolder, CheckFFmpegInstalled, DownloadFFmpeg, GetRecentFetches, SaveRecentFetches } from "../wailsjs/go/main/App";
|
||||
import { EventsOn, EventsOff, Quit } from "../wailsjs/runtime/runtime";
|
||||
import { toastWithSound as toast } from "@/lib/toast-with-sound";
|
||||
import { TitleBar } from "@/components/TitleBar";
|
||||
@@ -153,7 +153,6 @@ function App() {
|
||||
const downloadQueue = useDownloadQueueDialog();
|
||||
const downloadProgress = useDownloadProgress();
|
||||
const [isFFmpegInstalled, setIsFFmpegInstalled] = useState<boolean | null>(null);
|
||||
const [brewPath, setBrewPath] = useState<string>("");
|
||||
const [isInstallingFFmpeg, setIsInstallingFFmpeg] = useState(false);
|
||||
const [ffmpegInstallProgress, setFfmpegInstallProgress] = useState(0);
|
||||
const [ffmpegInstallStatus, setFfmpegInstallStatus] = useState("");
|
||||
@@ -181,8 +180,6 @@ function App() {
|
||||
try {
|
||||
const installed = await CheckFFmpegInstalled();
|
||||
setIsFFmpegInstalled(installed);
|
||||
const brew = await GetBrewPath();
|
||||
setBrewPath(brew);
|
||||
}
|
||||
catch (err) {
|
||||
console.error("Failed to check FFmpeg:", err);
|
||||
@@ -263,7 +260,7 @@ function App() {
|
||||
localStorage.removeItem(HISTORY_KEY);
|
||||
}
|
||||
}, [persistRecentHistory]);
|
||||
const handleInstallFFmpeg = async (useBrew: boolean = false) => {
|
||||
const handleInstallFFmpeg = async () => {
|
||||
setIsInstallingFFmpeg(true);
|
||||
setFfmpegInstallProgress(0);
|
||||
setFfmpegInstallStatus("starting");
|
||||
@@ -280,11 +277,11 @@ function App() {
|
||||
EventsOn("ffmpeg:status", (status: string) => {
|
||||
setFfmpegInstallStatus(status);
|
||||
});
|
||||
const response = useBrew ? await InstallFFmpegWithBrew() : await DownloadFFmpeg();
|
||||
const response = await DownloadFFmpeg();
|
||||
EventsOff("ffmpeg:progress");
|
||||
EventsOff("ffmpeg:status");
|
||||
if (response.success) {
|
||||
toast.success(useBrew ? "FFmpeg installed successfully via Homebrew!" : "FFmpeg installed successfully!");
|
||||
toast.success("FFmpeg installed successfully!");
|
||||
setIsFFmpegInstalled(true);
|
||||
}
|
||||
else {
|
||||
@@ -664,13 +661,9 @@ function App() {
|
||||
FFmpeg Required
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-sm text-foreground/70 leading-relaxed font-normal">
|
||||
{brewPath ? (<>
|
||||
FFmpeg is essential for SpotiFLAC to function properly.
|
||||
Homebrew detected. Recommended: <span className="text-foreground font-semibold">brew install ffmpeg</span>
|
||||
</>) : (<>
|
||||
FFmpeg is essential for SpotiFLAC to function properly.
|
||||
This setup will download about <span className="text-foreground font-semibold">100-200MB</span> of data.
|
||||
</>)}
|
||||
SpotiFLAC checks your system for FFmpeg and FFprobe first.
|
||||
If they are not available, the required binaries will be downloaded from GitHub.
|
||||
This setup downloads about <span className="text-foreground font-semibold">30-40MB</span> of data.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
@@ -698,15 +691,13 @@ function App() {
|
||||
</div>)}
|
||||
</div>)}
|
||||
|
||||
<DialogFooter className={`flex-row gap-3 pt-2 ${brewPath ? 'flex-col' : ''}`}>
|
||||
<DialogFooter className="flex-row gap-3 pt-2">
|
||||
{!isInstallingFFmpeg && (<Button variant="outline" className="flex-1 h-11 text-sm font-bold transition-colors" onClick={() => Quit()}>
|
||||
Exit
|
||||
</Button>)}
|
||||
{brewPath ? (<Button className="flex-1 h-11 text-sm font-bold shadow-lg shadow-primary/10" onClick={() => handleInstallFFmpeg(true)} disabled={isInstallingFFmpeg}>
|
||||
{isInstallingFFmpeg ? "Installing..." : "Install via Homebrew"}
|
||||
</Button>) : (<Button className={`${isInstallingFFmpeg ? 'w-full' : 'flex-1'} h-11 text-sm font-bold shadow-lg shadow-primary/10`} onClick={() => handleInstallFFmpeg(false)} disabled={isInstallingFFmpeg}>
|
||||
<Button className={`${isInstallingFFmpeg ? 'w-full' : 'flex-1'} h-11 text-sm font-bold shadow-lg shadow-primary/10`} onClick={handleInstallFFmpeg} disabled={isInstallingFFmpeg}>
|
||||
{isInstallingFFmpeg ? "Installing..." : "Install now"}
|
||||
</Button>)}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
Reference in New Issue
Block a user