Tauri v2 + SolidJS + SQLite + ffmpeg 사이드카로 구현한 크로스플랫폼 사진·영상 관리 앱. 로컬/NAS(SFTP·WebDAV·FTP) 소스, 가상 그리드, 인앱 재생, 태그/이동/삭제/undo, 중복 탐지, 포터블 배포. - archive-db: SQLite 스키마·마이그레이션·단일 writer 스레드 + FTS5 trigram - archive-vfs: VFS 4백엔드(local/sftp/ftp/webdav) + 자격증명(키체인/볼트) - archive-indexer: 스캔·해시·썸네일·중복탐지·태그·파일작업·유지보수 - archive-media: localhost HTTP 미디어 서버(Range) + ffmpeg 스트림 잡 - 프론트: 3-pane UI, justified 가상 그리드, 라이트박스, 중복 검토 패널 Rust 테스트 49개 통과. CI: win x64/arm64 포터블 zip + macOS universal dmg. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
61 lines
2.8 KiB
PowerShell
61 lines
2.8 KiB
PowerShell
# ffmpeg/ffprobe 사이드카 다운로드 (BtbN FFmpeg-Builds, LGPL 정적 빌드)
|
|
# 사용: .\scripts\fetch-ffmpeg.ps1 [-Target win64|winarm64]
|
|
# 결과: src-tauri\binaries\ffmpeg-<triple>.exe, ffprobe-<triple>.exe + manifest
|
|
param(
|
|
[ValidateSet("win64", "winarm64")]
|
|
[string]$Target = "win64"
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
$repo = "BtbN/FFmpeg-Builds"
|
|
$triple = if ($Target -eq "win64") { "x86_64-pc-windows-msvc" } else { "aarch64-pc-windows-msvc" }
|
|
$root = Split-Path $PSScriptRoot -Parent
|
|
$binDir = Join-Path $root "src-tauri\binaries"
|
|
New-Item -ItemType Directory -Force $binDir | Out-Null
|
|
|
|
if ((Test-Path "$binDir\ffmpeg-$triple.exe") -and (Test-Path "$binDir\ffprobe-$triple.exe")) {
|
|
Write-Host "[fetch-ffmpeg] 이미 존재: $triple — 건너뜀 (강제 갱신은 파일 삭제 후 재실행)"
|
|
exit 0
|
|
}
|
|
|
|
Write-Host "[fetch-ffmpeg] BtbN 'latest' 릴리스 자산 조회..."
|
|
$release = Invoke-RestMethod "https://api.github.com/repos/$repo/releases/tags/latest" -Headers @{ "User-Agent" = "archive-build" }
|
|
|
|
# 버전 브랜치(nX.Y) LGPL 정적 zip 우선, 없으면 master
|
|
$pattern = "^ffmpeg-n[\d\.]+-latest-$Target-lgpl-[\d\.]+\.zip$"
|
|
$asset = $release.assets | Where-Object { $_.name -match $pattern } | Sort-Object name -Descending | Select-Object -First 1
|
|
if (-not $asset) {
|
|
$asset = $release.assets | Where-Object { $_.name -eq "ffmpeg-master-latest-$Target-lgpl.zip" } | Select-Object -First 1
|
|
}
|
|
if (-not $asset) { throw "LGPL $Target 자산을 찾을 수 없습니다" }
|
|
|
|
Write-Host "[fetch-ffmpeg] 다운로드: $($asset.name) ($([math]::Round($asset.size / 1MB, 1)) MB)"
|
|
$tmp = Join-Path $env:TEMP "ffmpeg-fetch"
|
|
New-Item -ItemType Directory -Force $tmp | Out-Null
|
|
$zipPath = Join-Path $tmp $asset.name
|
|
Invoke-WebRequest $asset.browser_download_url -OutFile $zipPath -UseBasicParsing
|
|
|
|
$sha256 = (Get-FileHash $zipPath -Algorithm SHA256).Hash
|
|
Write-Host "[fetch-ffmpeg] SHA256: $sha256"
|
|
|
|
$extract = Join-Path $tmp "extract"
|
|
Remove-Item -Recurse -Force $extract -ErrorAction SilentlyContinue
|
|
Expand-Archive $zipPath -DestinationPath $extract
|
|
|
|
$ffmpeg = Get-ChildItem $extract -Recurse -Filter "ffmpeg.exe" | Select-Object -First 1
|
|
$ffprobe = Get-ChildItem $extract -Recurse -Filter "ffprobe.exe" | Select-Object -First 1
|
|
if (-not $ffmpeg -or -not $ffprobe) { throw "zip 안에서 ffmpeg/ffprobe.exe를 찾지 못함" }
|
|
|
|
Copy-Item $ffmpeg.FullName "$binDir\ffmpeg-$triple.exe" -Force
|
|
Copy-Item $ffprobe.FullName "$binDir\ffprobe-$triple.exe" -Force
|
|
|
|
@{
|
|
asset = $asset.name
|
|
sha256 = $sha256
|
|
target = $Target
|
|
triple = $triple
|
|
fetched = (Get-Date).ToString("o")
|
|
} | ConvertTo-Json | Set-Content "$binDir\manifest-$Target.json" -Encoding utf8
|
|
|
|
Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue
|
|
Write-Host "[fetch-ffmpeg] 완료: $binDir\ffmpeg-$triple.exe" |