Last active
May 18, 2018 08:01
-
-
Save ijs01140/1d90a2f57cd353096fd00f3e52224f34 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# _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 |
予約時に指定した録画後起動ps1との処理重複をとりあえず回避
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TSSplitterでEPG分割を行うことで、録画時の冒頭マージンをカット