Skip to content

Instantly share code, notes, and snippets.

@ijs01140
Last active May 18, 2018 08:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ijs01140/1d90a2f57cd353096fd00f3e52224f34 to your computer and use it in GitHub Desktop.
Save ijs01140/1d90a2f57cd353096fd00f3e52224f34 to your computer and use it in GitHub Desktop.
# _EDCBX_DIRECT_
# _EDCBX_HIDE_
#PostRecEndは視聴予約時にも実行できるので、視聴予約時なら終了
if ($env:RecMode -eq 4) { exit }
#==============ピークシフト機能(大嘘)===============
#時間を取得し、7以上且つ22未満(昼)の場合22時まで待つ
#もちろん言わずもがな夜間料金のため ※処理が追いつかないので中止※
<#
$nowhour=Get-Date -Format 'H'
if ($($nowhour -ge 7) -and $($nowhour -lt 22)) {
#待ち時間の計算
$waittime = 22 - $(Get-Date -Format 'H') * 3600 - $(Get-Date -Format 'm') * 60 - $(Get-Date -Format 's')
start-sleep $waittime
}
#>
#====================環境変数設定====================
#ファイル名をタイトルバーに表示
$myHost = (Get-Host).UI.RawUI
$myHost.WindowTitle = "${env:FileName}.tsをエンコード中..."
#スクリプト類全部入りフォルダ
$ScriptFolder='C:\tools\script'
#ffmpeg.exeがあるフォルダのパス
$FFFolderPATH='C:\tools\ffmpeg'
#TsSplitter.exeのパス
$TSSplitterPath='C:\tools\TsSplitter128\TsSplitter.exe'
#TS分離用のパス
$TempTSPath='D:\temp\ts'
#一時的にmp4を吐き出すフォルダのパス
$MP4FolderPATH='D:\temp\mp4'
#backup and sync用フォルダのパス
$BASFolderPATH='D:\temp\gsync\tv'
#処理が正常終了したTS用フォルダのパス
$treatedTSPATH='D:\treatedTS'
#10GB以上用フォルダのパス
$OtherFolderPATH='D:\temp\sizeover'
#===================Tweet用の関数=====================
#関数は使う前に書かないといけないみたいですね(白目)
function Tweet ($tw) {
#勉強のためにPythonで書いたらなんか速くなった(現状、引数読むので改行等はNG)
Start-Process 'python' -ArgumentList "${ScriptFolder}\arg_tweet.py `"${tw}`"" -NoNewWindow
Write-Output "ツイート完了`:${tw}"
}
#=================環境変数判定========================
if ([string]::isnullorempty($env:FilePath)) {
Write-Output 'エラー:環境変数FilePathが空です'
Write-Output '環境変数の一覧を取得します'
Get-ChildItem env:
Tweet 'エラー:環境変数FilePathが空です #ijsrec_err'
exit 1
}
#====================処理重複判定====================
#判定タイミング重複回避
Start-Sleep -s 10
If (Test-Path -LiteralPath "${env:FilePath}.log"){
Write-Output '録画後起動ps1との処理重複回避のために終了します'
Tweet "${env:FileName}は録画後起動ps1との処理重複回避のためエンコード処理をキャンセルしました。 #ijsrec_info"
exit
}
#====================ログ出力設定====================
Start-Transcript -LiteralPath "${env:FilePath}.log"
#===========TSファイル分離とファイルサイズ判定===========
#TSトリミング用フォルダに生TSをコピーし、処理を行う
Copy-Item -LiteralPath "${env:FilePath}" "${TempTSPath}\temp.ts" -force
#TSSplitterで生TSをバラす(Hd映像のみ残してEPG分割する。一応EMMあたりは残す。)
Start-Process "${TSSplitterPath}" -ArgumentList "-EIT -ECM -EMM -SD -1SEG -SEP `"${TempTSPath}\temp.ts`"" -NoNewWindow -Wait
#最初のTSだけワイルドカードでの列挙で不都合なので、ワイルドカードで引っかるようリネームする
Rename-Item "${TempTSPath}\temp_HD.ts" -NewName "${TempTSPath}\temp_HD-0.ts"
#ワイルドカードでバラシ後のTS列挙し、ファイルサイズ順にソートし、一番でかいファイルだけ選択
$TrimmedTS = $(Get-ChildItem "${TempTSPath}\temp_HD-?.ts" | Sort-Object length -descending | Select-Object -first 1)
#temp.tsにはもう用はないので削除
Remove-Item -LiteralPath "${TempTSPath}\temp.ts" -force
#Write-Output "選ばれたのは、$($TrimmedTS.substring($([string]${TrimmedTS}).length-4,1))番でした" #保留で
Write-Output "選ばれたのは、${TrimmedTS}でした" #とりあえず現行
#ファイルサイズ判定
$TSSize = $(Get-ChildItem -LiteralPath "${TrimmedTS}").Lengt
Write-Output "分割後のTSのサイズは約$([math]::round(${TSSize}/1MB, 2))MB(${TSSize}B)です。"
#==========インタレース解除フィルタを追加==============
$VFilter='bwdif=0:-1:1'
Write-Output 'インタレース自動解除を行います'
#==============24fps化フィルタを追加==================
<#
#ただのネタ(実用性の問題を解決できなかったため)
$decimatechk = $(Get-Content -LiteralPath "${env:FilePath}.program.txt" | Select-String -SimpleMatch '(任意の番組名)' -quiet)
if ($decimatechk -eq $True) {
$VFilter += ',decimate'
Write-Output '(任意の番組名)が検出されたので、24fps化します'
}
#>
#====================ロゴ消し設定====================
#ロゴ消しのため、放送局を判別する
#まだ画像用意できてない場合、エラーの原因になるので(それはそう)、用意できるまでコメントアウトする
$LogoNA=0
switch ($env:ServiceName) {
#BS
"NHKBS1" {$BROADCASTER='nhkbs1'} #ロゴ画像の精度が怪しいので要チェック
"NHKBSプレミアム" {$BROADCASTER='nhkbsp'}
"BS日テレ" {$BROADCASTER='bsntv'}
#"BS朝日1" {$BROADCASTER='bsasahi'}
"BS-TBS" {$BROADCASTER='bstbs'}
"BSジャパン" {$BROADCASTER='bsjapan'} #ロゴ画像の精度が怪しいので要チェック
"BSフジ・181" {$BROADCASTER='bsfuji'} #ロゴ画像の精度、おそらく大丈夫だが要チェック
"BS11イレブン" {$BROADCASTER='bs11'}
"BS12トゥエルビ" {$BROADCASTER='bs12'}
#"ディーライフ" {$HASHTAG='dlife'}
#"BSスカパー!" {$HASHTAG='bssptv'}
#地デジ
"NHK総合1・福岡" {$BROADCASTER='nhk'} #ロゴ画像の精度、おそらく大丈夫、なはず
"NHKEテレ1福岡" {$BROADCASTER='etv'}
"FBS福岡放送1" {$BROADCASTER='fbs'}
"KBCテレビ" {$BROADCASTER='kbc'}
"RKB毎日放送" {$BROADCASTER='rkb'}
"TVQ九州放送1" {$BROADCASTER='tvq'}
"テレビ西日本1" {$BROADCASTER='tnc'}
#その他
default {$LogoNA = 1}
}
if ($LogoNA -eq 0) {
#局別ロゴ消し用画像を使用し、removelogoフィルタを適用する
$VFilter += ",removelogo=${BROADCASTER}.png"
Write-Output "放送局ロゴ消しに${BROADCASTER}.pngが使用されます"
#局別フィルタ用txtファイルが存在する場合、読み込んでフィルタ適用
if (Test-Path "C:\TV\logo\${BROADCASTER}.txt") {
$logofilter = $(Get-Content -LiteralPath "C:\TV\logo\${BROADCASTER}.txt")
$VFilter += $logofilter
Write-Output "ロゴ修正フィルタ適用:${logofilter}"
}
} else {
Write-Output "ロゴ消しは、いたしません"
}
#==========3次元デノイズフィルタを追加=========
$VFilter += ',hqdn3d=4.0'
Write-Output '3次元デノイズフィルタが適用されます'
#==============リサイズフィルタを追加================
#生TSのサイズが1920x1080か1440x1080か調べる]
#以前の方式、たぶんダメだろうと思ってたらやっぱりダメだった(ので、おとなしくテキスト出力)
#.NET Freamworkのオブジェクト取得する方式はスマートに書けるけどスマートに書けなくてめんどくさいからこれまたボツね
Start-Process -FilePath "${FFFolderPATH}\ffprobe.exe" -ArgumentList "`"${env:FilePath}`"" -RedirectStandardError 'D:\temp\temp.txt' -NoNewWindow -Wait
$fhdchk = $(Get-Content -LiteralPath 'D:\temp\temp.txt' | Select-String -SimpleMatch '1920x1080' -quiet)
$ENCPRESET = 'medium'
$ENCFORMAT = 'libx265'
<#オリンピック録画に関する緊急措置は、オリンピック終了に伴い廃止されました
#※※※※※※オリンピック録画に関する緊急措置※※※※※※
$olympicchk = $(Get-Content -LiteralPath "${env:FilePath}.program.txt" | Select-String -SimpleMatch 'オリンピック' -quiet)
if ($olympicchk -eq $True) {
$VFilter +=',scale=1280:720,unsharp=3:3:0.5:3:3:0.5:0'
$ENCPRESET='veryfast'
$ENCFORMAT='libx264'
Write-Output 'オリンピック番組が検出されたので、オリンピック録画に関する緊急措置が発動されます'
} else#>
if ($fhdchk) {
Write-Output '解像度が1920x1080なので、そのまま1080pでエンコします'
} else {
$VFilter += ',scale=1280:720,unsharp=3:3:0.5:3:3:0.5:0'
Write-Output '解像度が1440x1080なので、720pにリサイズされます'
}
#====================tsファイルサイズ判別dev====================
#TSファイルのサイズを環境変数"TSSIZE"に指定
#26GB以下なら-crf 24,より大きいなら-crf 28(エンコ後が10GB以上になるとうp出来ないのでTSが20GB以上なら品質を下げる)
$ENCCRF = 24
if ($TSSize -le 26GB) {
$ENCCRF = 24
} else {
$ENCCRF = 28
}
Write-Output "エンコーダ`:${ENCFORMAT}`nプリセット`:${ENCPRESET}`n`CRF:${ENCCRF}`n"
#==============ffmpegのビデオオプションを設定==============
$VideoOption = "-vf $VFilter -crf $ENCCRF -c:v $ENCFORMAT -preset:v $ENCPRESET -g 300 -bf 16 -refs 16 -b_strategy 1 -pix_fmt yuv420p"
#===========音声形式の判別とオーディオオプションの設定=================
$AudioOption = '-c:a aac' #エンコ後の音声形式をAACに設定(-c:a copyはあまりよろしくないので非採用)
#番組情報の中に"デュアルモノ"という文字列があれば変数"$AudioOption"に"-filter_complex channelsplit"を加え、音声ビットレートを半分にする
$dualmonochk = $(Get-Content -LiteralPath "${env:FilePath}.program.txt" | Select-String -SimpleMatch 'デュアルモノ' -quiet)
if ($dualmonochk) {
Write-Output 'デュアルモノ音声が検出されました'
$AudioOption += ' -b:a 128k -filter_complex channelsplit'
} else {
$AudioOption += ' -b:a 256k'
}
#====================エンコード====================
#ロゴ画像データがあるフォルダにカレントディレクトリを移動
Set-Location 'C:\TV\logo'
$mp4Size = 0
#ループ処理用
#ファイルサイズが0バイトなら失敗とみなしループさせ復旧を試みる
for ($i = 0; $mp4Size -eq 0; $i++) {
#10回までループし,それでもダメなら諦めて無限ループを回避
if ($i -gt 10) {
#エンコに失敗したならtsとmp4とその他関連ファイルを10GB以上用フォルダに移動
Move-Item -LiteralPath "${env:FilePath}" "${OtherFolderPATH}" -force
Move-Item -LiteralPath "${MP4FolderPATH}\${env:FileName}.mp4" "${OtherFolderPATH}" -force
Move-Item -LiteralPath "${env:FilePath}.program.txt" "${OtherFolderPATH}" -force
Move-Item -LiteralPath "${env:FilePath}.err" "${OtherFolderPATH}" -force
Move-Item -LiteralPath 'D:\temp\postrecend_tmp.txt' "${OtherFolderPATH}\${env:FileName}.ffmpeg.txt" -force
#予期せぬエラーが発生したことをツイートで警告
Tweet "${env:FileName}.tsのエンコード失敗 #ijsrec_err"
Write-Output "${env:FileName}.tsのエンコードは異常終了しました。設定を見直しましょう。"
exit 1
}
Write-Output "エンコード${i}回目"
#とりあえずエンコ実行前に10秒待つ
Start-Sleep -s 10
#エンコ
$FFOPTION="-analyzeduration 30M -probesize 100M -loglevel warning -y -fflags +discardcorrupt -i `"${TrimmedTS}`" ${VideoOption} ${AudioOption} -map 0:p:${env:SID10}:0 -map 0:p:${env:SID10}:1 `"${MP4FolderPATH}\${env:FileName}.mp4`""
Write-Output "FFOPTION`:${FFOPTION}"
Start-Process "${FFFolderPATH}\ffmpeg.exe" -ArgumentList "${FFOPTION}" -RedirectStandardError 'D:\temp\postrecend_tmp.txt' -NoNewWindow -Wait #RedirectStandardErrorはなぜかワイルドカードパス扱いされるのでその問題を回避
#エンコ後ファイルのサイズを環境変数"MP4SIZE"に指定
$mp4Size = $(Get-ChildItem -LiteralPath "${MP4FolderPATH}\${env:FileName}.mp4").Length
}
#===============エンコード時間取得===================
#エンコード時間とfpsをffmpegのログから取り出す
$EncodeTimeLine = $(Get-Content -LiteralPath 'D:\temp\postrecend_tmp.txt' | Select-String -Pattern 'encoded' -SimpleMatch) #encodedの含まれる行を抜き出し、変数EncodeTimeLineに格納
#エンコード時間
$EncodeTime = $(-split $EncodeTimeLine)[4] #変数EncodeTimeLineを空白文字で区切り、5つ目を取り出す
$EncodeTimeTrim = $($EncodeTime.substring(0,${EncodeTime}.length-1)) #最後から1文字(s)を除去
#fps
$EncodeFps = $(-split $EncodeTimeLine)[5] #変数EncodeTimeLineを空白文字で区切り、5つ目を取り出す
$EncodeFpsTrim = $($EncodeFps.substring(1,${EncodeFps}.length-1)) #最初から1文字(括弧)を除去
#エンコード時間とfpsを含め、エンコード完了をTweetする
Tweet "${env:FileName}.mp4エンコード完了。エンコードに要した時間は約$([math]::round(${EncodeTimeTrim}/60, 2))分(${EncodeTimeTrim}秒)(${EncodeFpsTrim}fps)です。"
Write-Output "エンコード完了`nエンコード時間:約$([math]::round(${EncodeTimeTrim}/60, 2))分(${EncodeTimeTrim}秒)(${EncodeFpsTrim}fps)`nファイルサイズ${mp4Size}B"
#====================ファイル移動====================
#10GB以下ならbackup and sync用フォルダ,大きいなら10GB以上用フォルダへ(10GB以上はうp出来ない)
if ($mp4Size -le 10GB) {
Write-Output 'エンコ後10GB以内に収まったよ!やったね!'
<#
エンコしたファイルが10GB以下なら
・mp4をbackup and sync用フォルダに移動
・生TSやその関連ファイルを処理済みフォルダに移動
#>
Move-Item -LiteralPath "${MP4FolderPATH}\${env:FileName}.mp4" "${BASFolderPATH}\mp4" -force
Move-Item -LiteralPath "${env:FilePath}" "${treatedTSPATH}" -force
Move-Item -LiteralPath "${env:FilePath}.program.txt" "${treatedTSPATH}" -force
Move-Item -LiteralPath "${env:FilePath}.err" "${treatedTSPATH}" -force
Move-Item -LiteralPath 'D:\temp\postrecend_tmp.txt' "${treatedTSPATH}\${env:FileName}.ffmpeg.txt" -force
#処理が正常終了したことをツイートで報告
Tweet "${env:FileName}.mp4アップロード準備完了。エンコーダは${ENCFORMAT}、ファイルサイズは約$([math]::round(${mp4Size}/1MB, 2))MBです。"
} else {
Write-Output '残念ながら、サイズオーバーです。エンコ設定を見直しましょう。'
#エンコしたファイルが10GBより大きいならmp4とtsとその関連ファイルを10GB以上用フォルダに移動
Move-Item -LiteralPath "${env:FilePath}" "${OtherFolderPATH}" -force
Move-Item -LiteralPath "${MP4FolderPATH}\${env:FileName}.mp4" "${OtherFolderPATH}" -force
Move-Item -LiteralPath "${env:FilePath}.program.txt" "${OtherFolderPATH}" -force
Move-Item -LiteralPath "${env:FilePath}.err" "${OtherFolderPATH}" -force
Move-Item -LiteralPath 'D:\temp\postrecend_tmp.txt' "${OtherFolderPATH}\${env:FileName}.ffmpeg.txt" -force
#10GBより大きいので手動でうpする必要があることをツイートで報告
Tweet "${env:FileName}.mp4は残念ながら、サイズオーバーです。エンコ設定を見直しましょう。 #ijsrec_err"
}
#後のスクリプト実行に備え後片付け
Remove-Item "${TempTSPath}\*.*"
#処理終了をTweetで知らせる
Tweet "${env:FileName}.mp4の処理が終了しました"
Write-Output '処理終了おつかれさん'
exit
@ijs01140
Copy link
Author

TSSplitterでEPG分割を行うことで、録画時の冒頭マージンをカット

@ijs01140
Copy link
Author

予約時に指定した録画後起動ps1との処理重複をとりあえず回避

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment