# =====================================================
# amatsukaze_send.ps1 (3:00実行)
# TSファイルをAmatsukazeに投入する
# =====================================================
. "C:\FSW_32\script\amatsukaze_config.ps1"
$LOG = Join-Path $LOG_DIR ((Get-Date -Format "yyyyMM") + "_amatsukaze_send.log")
function Write-Log($msg) {
$line = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') : $msg"
Add-Content $LOG $line
Write-Host $line
}
Write-Log "==== Start (3:00) ===="
Invoke-TsSend
Write-Log "エンコード開始待ち(1分)..."
Start-Sleep -Seconds 60
Write-Log "待機完了"
Write-Log "==== End ===="windows 機で毎朝5時に起動する amatsukaze_send5.ps1 スクリプト作成 Ubuntu Serverでバックアップしたファイルもコピーする
# =====================================================
# amatsukaze_send_5.ps1 (5:00実行)
# Ubuntu Serverバックアップ + immichバックアップ + TSファイル投入
# =====================================================
. "C:\FSW_32\script\amatsukaze_config.ps1"
$LOG = Join-Path $LOG_DIR ((Get-Date -Format "yyyyMM") + "_amatsukaze_send.log")
$IMMICH_SRC = "\\192.168.0.100\ThinkPad_Data\docker\immich\library"
$IMMICH_DST = "D:\JPEG\immich"
$BACKUP_SRC = "\\192.168.0.100\ThinkPad_Data\backup"
$BACKUP_DST = "D:\Ubuntu-sv BackUP"
function Write-Log($msg) {
$line = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') : $msg"
Add-Content $LOG $line
Write-Host $line
}
# robocopyは正常時も戻り値1〜7を返すため終了コードで成否を判定する
function Invoke-Robocopy($src, $dst, $label) {
if (-not (Test-Path $src)) {
Write-Log "ERROR: ${label}元 $src にアクセスできません"
return
}
if (-not (Test-Path $dst)) {
New-Item -ItemType Directory -Path $dst -Force | Out-Null
Write-Log "作成: $dst"
}
robocopy $src $dst /MIR /R:3 /W:10 /LOG+:$LOG /NP /NFL /NDL
# robocopy戻り値: 0=差分なし 1=コピー成功 2〜7=警告あり 8以上=エラー
if ($LASTEXITCODE -ge 8) {
Write-Log "ERROR(${label}): robocopy終了コード $LASTEXITCODE"
} else {
Write-Log "${label}完了: $src -> $dst"
}
}
Write-Log "==== Start (5:00) ===="
# ===================================================
# Ubuntu Server バックアップコピー
# ===================================================
Write-Log "--- Ubuntu Server バックアップ開始 ---"
Invoke-Robocopy $BACKUP_SRC $BACKUP_DST "バックアップ"
Write-Log "--- Ubuntu Server バックアップ終了 ---"
# ===================================================
# immich写真バックアップ
# ===================================================
Write-Log "--- immich バックアップ開始 ---"
Invoke-Robocopy $IMMICH_SRC $IMMICH_DST "immich"
Write-Log "--- immich バックアップ終了 ---"
# ===================================================
# Amatsukaze TSファイル送信
# ===================================================
Invoke-TsSend
Write-Log "エンコード開始待ち(1分)..."
Start-Sleep -Seconds 60
Write-Log "待機完了"
Write-Log "==== End ===="上記二つの共通スクリプト amatsukaze_config.ps1 の作成
# =====================================================
# amatsukaze_config.ps1
# Amatsukaze共通設定・共通関数
# =====================================================
# ===== パス設定 =====
$ADDTASK = "C:\FSW_32\PT2\Amatsukaze\exe_files\AmatsukazeAddTask.exe"
$AMATSUKAZE = "C:\FSW_32\PT2\Amatsukaze"
$TARGET_DIR = "\\192.168.0.100\ThinkPad_Data\PT2"
$OUTPUT_DIR = "E:\TV"
$LOG_DIR = "C:\FSW_32\script\logs"
# ===== Amatsukazeプロファイル設定 =====
# 「自動選択_<名前>」構文は環境依存で確実に動かないため、
# リネーム前のチャンネルタグから直接プロファイル名を決定する
# (画像3の自動選択ルールと同じ振り分け: WOWOW系→デフォルトWOWOW、NHK系→デフォルトNHK、他→デフォルト)
$PROFILE_WOWOW = "デフォルトWOWOW"
$PROFILE_NHK = "デフォルトNHK"
$PROFILE_DEFAULT = "デフォルト"
# ===== WOWOW向けTrim設定 =====
# 録画開始から約35秒の前番組CMをカットする(末尾はそのまま)
# 35秒 * 30000/1001fps ≈ 1048.95 -> 1049フレーム
$WOWOW_TRIM_START_FRAMES = 1049
# リネーム前のチャンネルタグでWOWOW/NHK判定
$WOWOW_PATTERN = 'WOWOW'
$NHK_PATTERN = 'NHK'
# ===== スキップキーワード =====
$SKIP_PATTERNS = @(
@{ Pattern = '連続テレビ小説'; Label = "連続テレビ小説" },
@{ Pattern = 'PR'; Label = "PR" },
@{ Pattern = 'ダイジェスト'; Label = "ダイジェスト" },
@{ Pattern = [regex]::Escape('「ドジャース」'); Label = "ドジャース" }
# JSPORTS は Ubuntu側 encode.sh でスキップ済みのためここでは不要
)
# ===== 除去タグ =====
$REMOVE_TAGS = @(
'\[字\]', '\[解\]', '\[デ\]', '\[無\]', '\[二カ\]',
'\[多\]', '\[新\]', '\[再\]', '\[SS\]', '\[初\]',
'\(秘\)', '\[R15\+\]'
# \[映\] は意図的に残す(映画コンテンツの識別用)
)
# =====================================================
# 共通関数
# =====================================================
# Write-Log はスクリプト側で $LOG を参照するためスクリプト側に定義
# (呼び出し元の $LOG を使うため、ここには定義しない)
function Should-Skip($baseName) {
foreach ($item in $SKIP_PATTERNS) {
if ($baseName -match $item.Pattern) {
return $item.Label
}
}
return $null
}
# リネーム前のチャンネルタグからプロファイル名を決定
function Get-Profile($baseName) {
if ($baseName -match $WOWOW_PATTERN) {
return $PROFILE_WOWOW
}
if ($baseName -match $NHK_PATTERN) {
return $PROFILE_NHK
}
return $PROFILE_DEFAULT
}
function Sanitize-Name($baseName) {
$n = $baseName
# TV局名タグ除去(3文字以上のタグ)
# \[[^\]]{3,}\] は1文字の[映]には絶対マッチしないため、(?!\[映\])は不要
$n = $n -replace '^(\d+\s+)\[[^\]]{3,}\]\s*', '$1'
# 不要タグ除去
foreach ($tag in $REMOVE_TAGS) {
$n = $n -replace $tag, ''
}
# 使用不可文字置換
$n = $n -replace '[/\\|*?"<>]', ' '
$n = $n -replace ':', ':'
$n = $n -replace '\s+', ' '
return $n.Trim()
}
# WOWOW番組向けに .trim.avs を作成する
# 録画開始からの前番組CM部分のみカットし、末尾はそのまま残す
# チャプター・CM解析を無効にしたままでも有効(出力選択:CMをカットが前提)
function Write-WowowTrimAvs($targetPath) {
$avsPath = "$targetPath.trim.avs"
if (Test-Path -LiteralPath $avsPath) {
return
}
"Trim($WOWOW_TRIM_START_FRAMES,0)" | Out-File -LiteralPath $avsPath -Encoding ascii
}
function Get-DoneLog {
return Join-Path $LOG_DIR ((Get-Date -Format "yyyyMM") + "_done.log")
}
function Is-Done($baseName) {
$donePath = Get-DoneLog
if (-not (Test-Path $donePath)) { return $false }
$lines = Get-Content $donePath -ErrorAction SilentlyContinue
return ($lines -contains $baseName)
}
function Add-DoneLog($baseName) {
Add-Content (Get-DoneLog) $baseName
}
# TSファイルをAmatsukazeに投入する共通処理
# 呼び出し元で Write-Log 関数が定義済みであること
function Invoke-TsSend {
if (-not (Test-Path $TARGET_DIR)) {
Write-Log "ERROR: $TARGET_DIR にアクセスできません"
return
}
$files = Get-ChildItem -LiteralPath $TARGET_DIR -Filter "*.ts" -File
if ($files.Count -eq 0) {
Write-Log "処理対象ファイルなし"
return
}
Write-Log "対象: $($files.Count)件"
$count = 0
foreach ($file in $files) {
$baseName = $file.BaseName
Write-Log "Processing: $baseName"
# 2時間未満はスキップ(録画中の可能性)
$age = (Get-Date) - $file.LastWriteTime
if ($age.TotalMinutes -lt 120) {
Write-Log "SKIP(録画中の可能性: $([int]$age.TotalMinutes)分前更新): $baseName"
continue
}
# 投入済みチェック
if (Is-Done $baseName) {
Write-Log "SKIP(投入済み): $baseName"
continue
}
# スキップ判定
$skipReason = Should-Skip $baseName
if ($skipReason) {
Write-Log "SKIP($skipReason): $baseName"
continue
}
# プロファイル判定(リネーム前のチャンネルタグで判定する必要があるため、ここで実施)
$profile = Get-Profile $baseName
# ファイル名整形
$newName = Sanitize-Name $baseName
$newPath = Join-Path $file.DirectoryName ($newName + $file.Extension)
if ($newName -ne $baseName) {
if (-not (Test-Path -LiteralPath $newPath)) {
try {
Rename-Item -LiteralPath $file.FullName -NewName ($newName + $file.Extension)
Write-Log "RENAMED: $baseName -> $newName"
$targetPath = $newPath
} catch {
Write-Log "ERROR(rename): $baseName - $_"
continue
}
} else {
Write-Log "SKIP(exists): $newName"
continue
}
} else {
$targetPath = $file.FullName
}
# --- WOWOWの前番組CM(約35秒)Trimは無効化中 ---
# フォーマット切り替え(PMT更新)を含む長尺映画で
# join_logo_scp.exeの出力AVSファイルが不正です エラーになるため。
# CM解析無効化(プロファイル振り分け)のみ有効。
# if ($baseName -match $WOWOW_PATTERN) {
# Write-WowowTrimAvs $targetPath
# Write-Log "TrimAvs作成: $([System.IO.Path]::GetFileName($targetPath)).trim.avs (先頭${WOWOW_TRIM_START_FRAMES}フレームをカット)"
# }
# Amatsukazeキュー投入
Write-Log "AddTask: $targetPath (profile: $profile)"
& $ADDTASK -r $AMATSUKAZE -f $targetPath -ip "localhost" -p 32768 `
-o $OUTPUT_DIR -s $profile --priority 3 --no-move `
2>&1 | ForEach-Object { Write-Log $_ }
# doneログ記録(リネーム前後の両方)
Add-DoneLog $baseName
$newBaseName = [System.IO.Path]::GetFileNameWithoutExtension($targetPath)
if ($newBaseName -ne $baseName) { Add-DoneLog $newBaseName }
$count++
Start-Sleep -Seconds 2
}
Write-Log "完了: ${count}件追加"
}