|
| 1 | +# Script to install ffmpeg on Windows with timeout and retry |
| 2 | +# Usage: install-ffmpeg-windows.ps1 |
| 3 | + |
| 4 | +$ErrorActionPreference = "Stop" |
| 5 | + |
| 6 | +$TIMEOUT_SECONDS = 120 |
| 7 | +$URL = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip" |
| 8 | + |
| 9 | +Write-Host "Downloading and installing ffmpeg for Windows..." |
| 10 | + |
| 11 | +# Function to install ffmpeg with timeout |
| 12 | +function Install-Ffmpeg { |
| 13 | + param([int]$TimeoutSeconds = 120) |
| 14 | + |
| 15 | + $tempDir = New-Item -ItemType Directory -Path (Join-Path $env:TEMP "ffmpeg-temp-$(Get-Random)") |
| 16 | + $zipPath = Join-Path $tempDir "ffmpeg.zip" |
| 17 | + |
| 18 | + try { |
| 19 | + # Download with timeout |
| 20 | + Write-Host "Downloading ffmpeg..." |
| 21 | + $job = Start-Job -ScriptBlock { |
| 22 | + param($url, $zipPath) |
| 23 | + Invoke-WebRequest -Uri $url -OutFile $zipPath |
| 24 | + } -ArgumentList $URL, $zipPath |
| 25 | + |
| 26 | + if (Wait-Job -Job $job -Timeout $TimeoutSeconds) { |
| 27 | + Receive-Job -Job $job |
| 28 | + Remove-Job -Job $job -Force |
| 29 | + |
| 30 | + # Extract with timeout |
| 31 | + Write-Host "Extracting ffmpeg..." |
| 32 | + $extractJob = Start-Job -ScriptBlock { |
| 33 | + param($zipPath, $tempDir) |
| 34 | + Expand-Archive -Path $zipPath -DestinationPath $tempDir -Force |
| 35 | + } -ArgumentList $zipPath, $tempDir |
| 36 | + |
| 37 | + if (Wait-Job -Job $extractJob -Timeout $TimeoutSeconds) { |
| 38 | + Receive-Job -Job $extractJob |
| 39 | + Remove-Job -Job $extractJob -Force |
| 40 | + |
| 41 | + # Find and move ffmpeg.exe to PATH |
| 42 | + $ffmpegDir = Get-ChildItem -Path $tempDir -Directory -Filter "ffmpeg-*" | Select-Object -First 1 |
| 43 | + if (-not $ffmpegDir) { |
| 44 | + Write-Host "Error: ffmpeg directory not found in archive" |
| 45 | + return $false |
| 46 | + } |
| 47 | + $ffmpegExe = Join-Path (Join-Path $ffmpegDir.FullName "bin") "ffmpeg.exe" |
| 48 | + if (-not (Test-Path $ffmpegExe)) { |
| 49 | + Write-Host "Error: ffmpeg.exe not found at $ffmpegExe" |
| 50 | + return $false |
| 51 | + } |
| 52 | + |
| 53 | + # Copy to a location in PATH (using GitHub Actions runner's bin directory) |
| 54 | + $targetBin = $null |
| 55 | + if ($env:GITHUB_PATH) { |
| 56 | + # In GitHub Actions, add to GITHUB_PATH |
| 57 | + $binDir = Join-Path $env:RUNNER_TEMP "bin" |
| 58 | + New-Item -ItemType Directory -Force -Path $binDir | Out-Null |
| 59 | + Copy-Item -Path $ffmpegExe -Destination (Join-Path $binDir "ffmpeg.exe") -Force |
| 60 | + Add-Content -Path $env:GITHUB_PATH -Value $binDir |
| 61 | + $targetBin = Join-Path $binDir "ffmpeg.exe" |
| 62 | + Write-Host "Added $binDir to PATH via GITHUB_PATH" |
| 63 | + } else { |
| 64 | + # For local testing, copy to a user directory |
| 65 | + # Note: You may need to add this directory to your PATH manually |
| 66 | + # In PowerShell: $env:PATH += ";$env:USERPROFILE\bin" |
| 67 | + # Or permanently: [Environment]::SetEnvironmentVariable("Path", $env:Path + ";$env:USERPROFILE\bin", [System.EnvironmentVariableTarget]::User) |
| 68 | + $localBin = Join-Path $env:USERPROFILE "bin" |
| 69 | + New-Item -ItemType Directory -Force -Path $localBin | Out-Null |
| 70 | + Copy-Item -Path $ffmpegExe -Destination (Join-Path $localBin "ffmpeg.exe") -Force |
| 71 | + $targetBin = Join-Path $localBin "ffmpeg.exe" |
| 72 | + Write-Host "Installed to $localBin" |
| 73 | + Write-Host "IMPORTANT: Add this directory to your PATH if not already present:" |
| 74 | + Write-Host " PowerShell: `$env:PATH += ';$localBin'" |
| 75 | + Write-Host " Permanent: [Environment]::SetEnvironmentVariable('Path', `$env:Path + ';$localBin', [System.EnvironmentVariableTarget]::User)" |
| 76 | + } |
| 77 | + |
| 78 | + # Verify installation using full path |
| 79 | + & $targetBin -version | Select-Object -First 1 |
| 80 | + if ($LASTEXITCODE -eq 0) { |
| 81 | + return $true |
| 82 | + } else { |
| 83 | + Write-Host "Error: ffmpeg verification failed" |
| 84 | + return $false |
| 85 | + } |
| 86 | + } else { |
| 87 | + Stop-Job -Job $extractJob |
| 88 | + Remove-Job -Job $extractJob -Force |
| 89 | + return $false |
| 90 | + } |
| 91 | + } else { |
| 92 | + Stop-Job -Job $job |
| 93 | + Remove-Job -Job $job -Force |
| 94 | + return $false |
| 95 | + } |
| 96 | + } finally { |
| 97 | + # Cleanup temp directory |
| 98 | + if (Test-Path $tempDir) { |
| 99 | + Remove-Item -Recurse -Force $tempDir -ErrorAction SilentlyContinue |
| 100 | + } |
| 101 | + } |
| 102 | +} |
| 103 | + |
| 104 | +# First attempt |
| 105 | +Write-Host "Attempting to download ffmpeg (attempt 1)..." |
| 106 | +if (Install-Ffmpeg -TimeoutSeconds $TIMEOUT_SECONDS) { |
| 107 | + Write-Host "ffmpeg installed successfully on first attempt" |
| 108 | +} else { |
| 109 | + Write-Host "First attempt failed or timed out, retrying..." |
| 110 | + |
| 111 | + # Clean up any stale temp directories |
| 112 | + Get-ChildItem -Path $env:TEMP -Directory -Filter "ffmpeg-temp-*" -ErrorAction SilentlyContinue | |
| 113 | + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue |
| 114 | + |
| 115 | + # Retry |
| 116 | + Write-Host "Attempting to download ffmpeg (attempt 2)..." |
| 117 | + if (Install-Ffmpeg -TimeoutSeconds $TIMEOUT_SECONDS) { |
| 118 | + Write-Host "ffmpeg installed successfully on second attempt" |
| 119 | + } else { |
| 120 | + Write-Host "ffmpeg installation failed after 2 attempts" |
| 121 | + exit 1 |
| 122 | + } |
| 123 | +} |
| 124 | + |
| 125 | +Write-Host "ffmpeg installation complete" |
0 commit comments