Compare commits
1 Commits
ci/add-ffm
...
c954bf25d4
| Author | SHA1 | Date | |
|---|---|---|---|
| c954bf25d4 |
47
.github/FFMPEG_GUIDE.md
vendored
47
.github/FFMPEG_GUIDE.md
vendored
@@ -1,47 +0,0 @@
|
||||
# FFmpeg CI Guide
|
||||
|
||||
This file describes how to provide a vetted FFmpeg build to the CI workflow and how the workflow expects archive layouts.
|
||||
|
||||
## Secrets (recommended)
|
||||
- `FFMPEG_URL` — primary URL the workflow will download. Use a stable URL to a signed/hosted FFmpeg build.
|
||||
- `FFMPEG_URL_LINUX` — optional override for Linux runners.
|
||||
- `FFMPEG_URL_WINDOWS` — optional override for Windows runners.
|
||||
- `FFMPEG_URL_MACOS` — optional override for macOS runners.
|
||||
|
||||
If per-OS secrets are present, they take precedence over `FFMPEG_URL`.
|
||||
|
||||
## Recommended FFmpeg sources
|
||||
- Use official static builds from a trusted provider (example):
|
||||
- Windows (ffmpeg.exe): https://www.gyan.dev/ffmpeg/builds/
|
||||
- Linux (static): https://johnvansickle.com/ffmpeg/
|
||||
- macOS (static): https://evermeet.cx/ffmpeg/
|
||||
|
||||
Prefer hosting a copy in your own artifact store (S3, GitHub Releases) so you control the binary used in CI.
|
||||
|
||||
## Expected archive layouts
|
||||
The workflow will attempt to extract common archive formats. Recommended layouts:
|
||||
|
||||
- Zip containing `ffmpeg.exe` at the archive root
|
||||
- Example: `ffmpeg-2025-01-01.zip` -> `ffmpeg.exe` (root)
|
||||
|
||||
- Tar.gz or tar.xz containing an `ffmpeg` binary at the archive root or inside a single top-level folder
|
||||
- Example: `ffmpeg-2025/ffmpeg` or `ffmpeg`
|
||||
|
||||
- Raw binary: a direct link to the `ffmpeg` executable is also supported (the workflow will make it executable).
|
||||
|
||||
If your archive nests the binary deep inside several folders, consider publishing a trimmed archive that places `ffmpeg` at the root for easier CI extraction.
|
||||
|
||||
## Verifying locally
|
||||
To test the workflow steps locally, download your chosen archive and ensure running the binary prints version information:
|
||||
|
||||
```bash
|
||||
# on Linux/macOS
|
||||
./ffmpeg -version
|
||||
|
||||
# on Windows (PowerShell)
|
||||
.\ffmpeg.exe -version
|
||||
```
|
||||
|
||||
## Notes for maintainers
|
||||
- If you need the workflow to handle a custom archive layout, I can update the extraction step (`.github/workflows/ffmpeg-preflight.yml`) to locate the binary path inside the archive and move it to `src-tauri/resources/ffmpeg(.exe)`.
|
||||
- After adding secrets, open a PR to trigger the workflow and verify the `FFmpeg preflight OK` message in the CI logs.
|
||||
129
.github/workflows/ffmpeg-preflight.yml
vendored
129
.github/workflows/ffmpeg-preflight.yml
vendored
@@ -1,129 +0,0 @@
|
||||
name: FFmpeg Preflight and Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, master ]
|
||||
pull_request:
|
||||
branches: [ main, master ]
|
||||
|
||||
jobs:
|
||||
preflight:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
|
||||
env:
|
||||
# Provide a fallback URL via repository secret `FFMPEG_URL_{OS}` or `FFMPEG_URL`.
|
||||
FFMPEG_URL: ${{ secrets.FFMPEG_URL }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
- name: Set up Rust
|
||||
uses: dtolnay/gh-actions-rs@stable
|
||||
|
||||
- name: Determine OS-specific ffmpeg URL
|
||||
id: ffmpeg-url
|
||||
shell: bash
|
||||
run: |
|
||||
echo "RUNNER_OS=${RUNNER_OS}"
|
||||
if [[ "${RUNNER_OS}" == "Windows" ]]; then
|
||||
echo "url=${{ secrets.FFMPEG_URL_WINDOWS || secrets.FFMPEG_URL }}" >> $GITHUB_OUTPUT
|
||||
elif [[ "${RUNNER_OS}" == "macOS" ]]; then
|
||||
echo "url=${{ secrets.FFMPEG_URL_MACOS || secrets.FFMPEG_URL }}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "url=${{ secrets.FFMPEG_URL_LINUX || secrets.FFMPEG_URL }}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Create resources dir
|
||||
run: mkdir -p src-tauri/resources
|
||||
|
||||
- name: Download and install FFmpeg into resources
|
||||
if: steps.ffmpeg-url.outputs.url != ''
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
URL="${{ steps.ffmpeg-url.outputs.url }}"
|
||||
echo "Downloading ffmpeg from: $URL"
|
||||
FNAME="${RUNNER_TEMP}/ffmpeg_bundle"
|
||||
if [[ "${RUNNER_OS}" == "Windows" ]]; then
|
||||
powershell -Command "(New-Object Net.WebClient).DownloadFile('$URL', '$FNAME.zip')"
|
||||
powershell -Command "Expand-Archive -Path '$FNAME.zip' -DestinationPath '${{ github.workspace }}\\src-tauri\\resources'"
|
||||
else
|
||||
curl -sL "$URL" -o "$FNAME"
|
||||
# Attempt to extract common archive formats
|
||||
if file "$FNAME" | grep -q 'Zip archive'; then
|
||||
unzip -q "$FNAME" -d src-tauri/resources
|
||||
elif file "$FNAME" | grep -q 'gzip compressed data'; then
|
||||
tar -xzf "$FNAME" -C src-tauri/resources
|
||||
elif file "$FNAME" | grep -q 'XZ compressed'; then
|
||||
tar -xJf "$FNAME" -C src-tauri/resources
|
||||
else
|
||||
# Assume raw binary
|
||||
mv "$FNAME" src-tauri/resources/ffmpeg
|
||||
chmod +x src-tauri/resources/ffmpeg
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: List resources
|
||||
run: ls -la src-tauri/resources || true
|
||||
|
||||
- name: Locate ffmpeg binary (Linux/macOS)
|
||||
if: runner.os != 'Windows'
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Try to find an ffmpeg executable anywhere under resources
|
||||
BINPATH=$(find src-tauri/resources -type f -iname ffmpeg -print -quit || true)
|
||||
if [ -z "$BINPATH" ]; then
|
||||
BINPATH=$(find src-tauri/resources -type f -iname 'ffmpeg*' -print -quit || true)
|
||||
fi
|
||||
if [ -n "$BINPATH" ]; then
|
||||
echo "Found ffmpeg at $BINPATH"
|
||||
cp "$BINPATH" src-tauri/resources/ffmpeg
|
||||
chmod +x src-tauri/resources/ffmpeg
|
||||
else
|
||||
echo "ffmpeg binary not found in resources"
|
||||
ls -R src-tauri/resources || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Locate ffmpeg binary (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$found = Get-ChildItem -Path src-tauri/resources -Recurse -Filter ffmpeg.exe -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
if (-not $found) {
|
||||
$found = Get-ChildItem -Path src-tauri/resources -Recurse -Filter '*ffmpeg*' -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
}
|
||||
if ($found) {
|
||||
Write-Host "Found ffmpeg at $($found.FullName)"
|
||||
Copy-Item $found.FullName -Destination 'src-tauri\resources\ffmpeg.exe' -Force
|
||||
} else {
|
||||
Write-Host "ffmpeg not found in src-tauri/resources"
|
||||
Get-ChildItem src-tauri\resources -Recurse | Format-List
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Install npm deps
|
||||
run: npm ci
|
||||
|
||||
- name: Copy project FFmpeg helpers
|
||||
run: node tools/copy-ffmpeg.js || true
|
||||
|
||||
- name: Build Rust and run ffmpeg preflight check
|
||||
working-directory: src-tauri
|
||||
run: |
|
||||
set -e
|
||||
cargo build --release
|
||||
cargo run --release --bin check_ffmpeg
|
||||
|
||||
- name: Optional frontend build
|
||||
run: npm run build --if-present || true
|
||||
@@ -1,13 +0,0 @@
|
||||
fn main() {
|
||||
// Call the library's FFmpeg preflight check used by the application.
|
||||
match radio_tauri_lib::player::preflight_ffmpeg_only() {
|
||||
Ok(()) => {
|
||||
println!("FFmpeg preflight OK");
|
||||
std::process::exit(0);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("FFmpeg preflight failed: {}", e);
|
||||
std::process::exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,31 +41,6 @@ function resolveSource() {
|
||||
|
||||
function main() {
|
||||
const name = platformBinName();
|
||||
// If CI or prior steps already placed ffmpeg into resources, prefer that and skip copying.
|
||||
const existingInResources = path.join(resourcesDir, name);
|
||||
if (exists(existingInResources)) {
|
||||
console.log(`FFmpeg already present in resources: ${existingInResources} — skipping copy.`);
|
||||
process.exit(0);
|
||||
}
|
||||
// Also search recursively in resources for any ffmpeg-like file (robustness for nested archives)
|
||||
if (exists(resourcesDir)) {
|
||||
const files = fs.readdirSync(resourcesDir, { withFileTypes: true });
|
||||
const found = (function findRec(dir) {
|
||||
for (const f of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||
const p = path.join(dir, f.name);
|
||||
if (f.isFile() && f.name.toLowerCase().startsWith('ffmpeg')) return p;
|
||||
if (f.isDirectory()) {
|
||||
const r = findRec(p);
|
||||
if (r) return r;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
})(resourcesDir);
|
||||
if (found) {
|
||||
console.log(`Found ffmpeg in resources at ${found} — skipping copy.`);
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
const src = resolveSource();
|
||||
if (!src) {
|
||||
console.log('FFmpeg not provided; skipping copy (set RADIOPLAYER_FFMPEG or place it under tools/ffmpeg/).');
|
||||
|
||||
Reference in New Issue
Block a user