gongxiangp2/scripts/batch-retranscode-all-videos.ps1

203 lines
6.6 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 批量转码所有视频素材脚本
# 用途:一次性任务,将所有视频素材重新转码为新标准(720P + H.265)
# 注意:转码完成后,旧的预览文件会自动清理
param(
[Parameter(Mandatory=$false)]
[switch]$DryRun = $false,
[Parameter(Mandatory=$false)]
[int]$BatchSize = 1000, # 每批处理数量(最大1000)
[Parameter(Mandatory=$false)]
[string]$BaseUrl = "http://localhost:3000" # API 基础URL
)
# 颜色输出函数
function Write-ColorOutput($ForegroundColor) {
$fc = $host.UI.RawUI.ForegroundColor
$host.UI.RawUI.ForegroundColor = $ForegroundColor
if ($args) {
Write-Output $args
}
$host.UI.RawUI.ForegroundColor = $fc
}
function Write-Info { Write-ColorOutput Cyan $args }
function Write-Success { Write-ColorOutput Green $args }
function Write-Warning { Write-ColorOutput Yellow $args }
function Write-Error { Write-ColorOutput Red $args }
Write-Info "=========================================="
Write-Info "批量转码所有视频素材"
Write-Info "=========================================="
if ($DryRun) {
Write-Info "模式: 试运行 (Dry Run)"
} else {
Write-Info "模式: 实际执行"
}
Write-Info "批次大小: $BatchSize"
Write-Info "API URL: $BaseUrl"
Write-Info ""
# 检查是否需要管理员认证
# 注意:实际使用时需要提供管理员 session cookie 或 API key
# 这里假设通过环境变量或配置文件提供认证信息
$headers = @{
"Content-Type" = "application/json"
}
# 如果需要认证,可以添加:
# $headers["Cookie"] = "next-auth.session-token=YOUR_SESSION_TOKEN"
# 或者使用 API key(如果实现了)
# 第一步:统计需要转码的素材数量
Write-Info "📊 第一步:统计需要转码的素材数量..."
$dryRunBody = @{
limit = $BatchSize
status = "any" # 转码所有状态的视频(done、failed、null等)
dryRun = $true
} | ConvertTo-Json
try {
$response = Invoke-RestMethod -Uri "$BaseUrl/api/admin/video-retranscode" `
-Method POST `
-Headers $headers `
-Body $dryRunBody `
-ErrorAction Stop
$totalCount = $response.matched
Write-Success "✓ 找到 $totalCount 个视频素材需要转码"
if ($totalCount -eq 0) {
Write-Warning "没有找到需要转码的视频素材"
exit 0
}
Write-Info "前10个素材预览:"
if ($response.sample) {
$response.sample | ForEach-Object {
Write-Info " - ID: $($_.id), 产品: $($_.productModel), 状态: $($_.status)"
}
}
} catch {
Write-Error "❌ 统计失败: $($_.Exception.Message)"
if ($_.Exception.Response) {
$reader = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream())
$responseBody = $reader.ReadToEnd()
Write-Error "响应: $responseBody"
}
exit 1
}
if ($DryRun) {
Write-Info ""
Write-Warning "⚠️ 这是试运行模式,未执行实际转码"
Write-Info "如需执行实际转码,请运行:"
Write-Info " .\scripts\batch-retranscode-all-videos.ps1 -DryRun:`$false"
exit 0
}
# 第二步:确认执行
Write-Info ""
Write-Warning "⚠️ 警告:即将开始批量转码 $totalCount 个视频素材"
Write-Warning " 转码是异步执行的,会进入队列处理"
Write-Warning " 转码完成后,旧的预览文件会自动清理"
Write-Info ""
$confirm = Read-Host "确认继续?(yes/no)"
if ($confirm -ne "yes") {
Write-Info "已取消操作"
exit 0
}
# 第三步:分批执行转码
Write-Info ""
Write-Info "🚀 开始批量转码..."
$totalBatches = [Math]::Ceiling($totalCount / $BatchSize)
Write-Info "预计需要 $totalBatches 个批次"
$totalQueued = 0
$totalFailed = 0
for ($batch = 1; $batch -le $totalBatches; $batch++) {
Write-Info ""
Write-Info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
Write-Info "批次 $batch/$totalBatches"
Write-Info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
$body = @{
limit = $BatchSize
status = "any"
dryRun = $false
} | ConvertTo-Json
try {
$response = Invoke-RestMethod -Uri "$BaseUrl/api/admin/video-retranscode" `
-Method POST `
-Headers $headers `
-Body $body `
-ErrorAction Stop
$queued = $response.queued
$failed = $response.failed
$matched = $response.matched
$totalQueued += $queued
$totalFailed += $failed
Write-Success "✓ 批次 $batch 完成: 已排队 $queued 个,失败 $failed 个"
if ($response.details -and $response.details.Count -gt 0) {
$failedDetails = $response.details | Where-Object { -not $_.ok }
if ($failedDetails.Count -gt 0) {
Write-Warning "失败详情(前5个):"
$failedDetails | Select-Object -First 5 | ForEach-Object {
Write-Warning " - ID: $($_.id), 状态: $($_.status), 错误: $($_.message)"
}
}
}
# 如果这一批匹配的数量少于批次大小,说明已经处理完所有素材
if ($matched -lt $BatchSize) {
Write-Info "已处理完所有素材"
break
}
# 批次间稍作延迟,避免请求过快
if ($batch -lt $totalBatches) {
Write-Info "等待 2 秒后继续下一批次..."
Start-Sleep -Seconds 2
}
} catch {
Write-Error "❌ 批次 $batch 失败: $($_.Exception.Message)"
if ($_.Exception.Response) {
$reader = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream())
$responseBody = $reader.ReadToEnd()
Write-Error "响应: $responseBody"
}
# 继续处理下一批次
continue
}
}
# 总结
Write-Info ""
Write-Info "=========================================="
Write-Info "批量转码完成"
Write-Info "=========================================="
Write-Success "✓ 总计已排队: $totalQueued 个"
if ($totalFailed -gt 0) {
Write-Warning "⚠️ 总计失败: $totalFailed 个"
}
Write-Info ""
Write-Info "📝 说明:"
Write-Info " - 转码是异步执行的,会进入队列处理"
Write-Info " - 实际并发数由服务器配置控制(VIDEO_TRANSCODE_MAX_CONCURRENT)"
Write-Info " - 转码成功后,旧的预览文件会自动清理"
Write-Info " - 可以在管理员页面查看转码进度和状态"
Write-Info ""