ubuntu
カテゴリ
TV録画後にAmatsukazeへ Windowsの設定1
2026/04/18 22時tv
windows 機で毎朝3時に起動する amatsukaze_send.ps1 スクリプト作成
# =====================================================
# 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}件追加"
}
注意事項:ps1ファイルのエンコードの種類は UTF-8 BOM付きにする。
記事一覧