Upload recorded files to Google Drive (use with Mirakurun + EPGStation + rclone)
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
#某所のチューニングです 各自地上波は再設定して下さい | |
#UHFチャンネルナンバーではなくch13を0と見たときの数字です | |
- name: NHK総合・大阪 | |
type: GR | |
channel: '11' | |
- name: NHKテレ・大阪 | |
type: GR | |
channel: '0' | |
#- name: サンテレビ | |
# type: GR | |
# channel: '13' | |
- name: KBS京都 | |
type: GR | |
channel: '10' | |
- name: MBS毎日放送 | |
type: GR | |
channel: '3' | |
- name: ABCテレビ | |
type: GR | |
channel: '2' | |
- name: テレビ大阪 | |
type: GR | |
channel: '5' | |
- name: 関西テレビ | |
type: GR | |
channel: '4' | |
- name: 読売テレビ | |
type: GR | |
channel: '1' | |
#==================================== | |
#BS | |
#radi-sh製BonDriver_BDAを使用する場合S.iniに記載されているCHナンバーを使用すること | |
- name: NHK BS1 | |
type: BS | |
channel: '017' | |
serviceId: 101 | |
- name: NHK BS1 (サブ) | |
type: BS | |
channel: '017' | |
serviceId: 102 | |
- name: NHK BSプレミアム | |
type: BS | |
channel: '018' | |
serviceId: 103 | |
- name: NHK BSプレミアム (サブ) | |
type: BS | |
channel: '018' | |
serviceId: 104 | |
- name: BS日テレ | |
type: BS | |
channel: '015' | |
serviceId: 141 | |
- name: BS日テレ (サブ) | |
type: BS | |
channel: '015' | |
serviceId: 142 | |
- name: BS朝日 | |
type: BS | |
channel: '000' | |
serviceId: 151 | |
- name: BS朝日 (サブ) | |
type: BS | |
channel: '000' | |
serviceId: 152 | |
- name: BS-TBS | |
type: BS | |
channel: '001' | |
serviceId: 161 | |
- name: BSジャパン | |
type: BS | |
channel: '003' | |
serviceId: 171 | |
- name: BSフジ | |
type: BS | |
channel: '016' | |
serviceId: 181 | |
- name: WOWOWプライム | |
type: BS | |
channel: '002' | |
serviceId: 191 | |
isDisabled: true | |
- name: WOWOWライブ | |
type: BS | |
channel: '004' | |
serviceId: 192 | |
isDisabled: true | |
- name: WOWOWシネマ | |
type: BS | |
channel: '005' | |
serviceId: 193 | |
isDisabled: true | |
- name: スター・チャンネル1 | |
type: BS | |
channel: '010' | |
serviceId: 200 | |
isDisabled: true | |
- name: スター・チャンネル2 | |
type: BS | |
channel: '006' | |
serviceId: 201 | |
isDisabled: true | |
- name: スター・チャンネル3 | |
type: BS | |
channel: '006' | |
serviceId: 202 | |
isDisabled: true | |
- name: BS11 | |
type: BS | |
channel: '009' | |
serviceId: 211 | |
isDisabled: true | |
- name: TwellV | |
type: BS | |
channel: '011' | |
serviceId: 222 | |
- name: 放送大学BS1 | |
type: BS | |
channel: '014' | |
serviceId: 231 | |
- name: 放送大学BS2 | |
type: BS | |
channel: '014' | |
serviceId: 232 | |
- name: 放送大学BS3 | |
type: BS | |
channel: '014' | |
serviceId: 233 | |
- name: グリーンチャンネル | |
type: BS | |
channel: '021' | |
serviceId: 234 | |
isDisabled: true | |
- name: BSアニマックス | |
type: BS | |
channel: '007' | |
serviceId: 236 | |
isDisabled: true | |
- name: FOXスポーツ&エンターテイメント | |
type: BS | |
channel: '012' | |
serviceId: 238 | |
isDisabled: true | |
- name: BSスカパー! | |
type: BS | |
channel: '013' | |
serviceId: 241 | |
isDisabled: true |
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
- name: PX-W3U4-S0 | |
types: | |
- BS | |
command: D:\DTV\bin\BonRecTest\BonRecTest.exe --decoder D:\DTV\bin\BonRecTest\B25Decoder.dll --driver D:\DTV\bin\BonRecTest\BonDriver_PX_x3U4_S.dll --space <satelite> --channel <channel> --output - | |
decoder: ~ | |
isDisabled: false | |
- name: PX-W3U4-S1 | |
types: | |
- BS | |
command: D:\DTV\bin\BonRecTest\BonRecTest.exe --decoder D:\DTV\bin\BonRecTest\B25Decoder.dll --driver D:\DTV\bin\BonRecTest\BonDriver_PX_x3U4_S.dll --space <satelite> --channel <channel> --output - | |
decoder: ~ | |
isDisabled: false | |
- name: PX-W3U4-T0 | |
types: | |
- GR | |
command: D:\DTV\bin\BonRecTest\BonRecTest.exe --decoder D:\DTV\bin\BonRecTest\B25Decoder.dll --driver D:\DTV\bin\BonRecTest\BonDriver_PX_x3U4_T.dll --output - --channel <channel> | |
decoder: ~ | |
isDisabled: false | |
- name: PX-W3U4-T1 | |
types: | |
- GR | |
command: D:\DTV\bin\BonRecTest\BonRecTest.exe --decoder D:\DTV\bin\BonRecTest\B25Decoder.dll --driver D:\DTV\bin\BonRecTest\BonDriver_PX_x3U4_T.dll --output - --channel <channel> | |
decoder: ~ | |
isDisabled: false |
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
#config.jsonの変更が必要です | |
#識別するため%ID%をファイル名の最後に追加 | |
#"recordedFormat": "%YEAR%年%MONTH%月%DAY%日%HOUR%時%MIN%分- | |
#Googleドライブでは.m2ts拡張子でないとエンコードされません | |
#"fileExtension": ".m2ts", | |
#プログラムID | |
$program_id = "$env:PROGRAMID" | |
#今日の月 | |
$this_month = Get-Date -UFormat "%Y年%m月" | |
#====================ユーザ設定==================== | |
#--------------------Google ドライブへアップロード-------------------- | |
#0=無効、1=有効 | |
$gdrive_toggle = 1 | |
#アップロード用ディレクトリ | |
$bas_folder_path = 'D:\DTV\upload' | |
#アップロード中の一時ディレクトリ | |
$tmp_bas_folder_path = 'D:\DTV\uploadtmp\' | |
#rclone.exeのパス | |
$rclone_path = 'D:\DTV\bin\rclone\rclone.exe' | |
#rcloneの設定ファイルのパス | |
#あらかじめrclone configで認証を済ませてください | |
$config_path = 'C:\Users\user\.config\rclone\rclone.conf' | |
#アップロード先のフォルダ指定 | |
#driveはrclone configで設定したremoteの名前です | |
$dest_folder_path = "drive:@録画/${this_month}" | |
#--------------------一時パスやログなどの設定-------------------- | |
#実行日時 | |
$run_datetime = Get-Date -UFormat "%Y%m%d-%H%M%S" | |
#$run_datetime="20180602-231420" | |
#一時フォルダのパス | |
$tmp_folder_path = "${tmp_bas_folder_path}${run_datetime}" | |
# ログのパスと名前 | |
$log_path = "D:\DTV\logs" | |
$log_file = "${log_path}\uploadlog_${run_datetime}.txt" | |
#ログ取得開始 | |
Start-transcript -path "${log_file}" | |
#"--------環境変数--------" | |
#Get-ChildItem env: | |
#"--------環境変数--------" | |
Write-Output "プログラムID: $program_id" | |
#====================ファイルがロックされているか確認する==================== | |
#Thanks guitarrapc! | |
#https://github.com/guitarrapc/PowerShellUtil/blob/master/Test-FileLock/Test-FileLock.psm1 | |
function Filelock { | |
# ファイルロック中のファイルを検査する | |
param ( | |
[parameter( | |
position = 0, | |
mandatory | |
)] | |
[System.IO.FileInfo] | |
$Path | |
) | |
try { | |
# initialise variables | |
$script:filelocked = $false | |
# attempt to open file and detect file lock | |
$script:fileInfo = New-Object System.IO.FileInfo $Path | |
$script:fileStream = $fileInfo.Open([System.IO.FileMode]::OpenOrCreate, | |
[System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None) | |
# close stream if not lock | |
$f1 = $fileStream | |
Write-Host $f1 | |
$f2 = $filelocked | |
if ($fileStream) { | |
$fileStream.Close() | |
$f3 = $fileStream | |
$f4 = $filelocked | |
} | |
} | |
catch { | |
# catch fileStream had falied | |
$filelocked = $true | |
} | |
finally { | |
# return result | |
[PSCustomObject]@{ | |
path = $Path | |
filelocked = $filelocked | |
} | |
} | |
} | |
function Test-FileLock { | |
param ( | |
[parameter( | |
position = 0, | |
mandatory | |
)] | |
[string] | |
$Path | |
) | |
try { | |
if (Test-Path -LiteralPath $Path) { | |
if ((Get-Item -path $path) -is [System.IO.FileInfo]) { | |
return (filelock -Path $Path).filelocked | |
} | |
elseif ((Get-Item -LiteralPath $Path) -is [System.IO.DirectoryInfo]) { | |
Write-Verbose "[$Path] detect as $((Get-Item -LiteralPath -path $Path).GetType().FullName). | |
Skip cehck." | |
} | |
} | |
else { | |
Write-Error "[$Path] could not find. | |
+ CategoryInfo : ObjectNotFound: ($Path), ItemNotFoundException | |
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand" | |
} | |
} | |
catch { | |
Write-Error $_ | |
} | |
} | |
#====================8.3形式のファイル名を取得する==================== | |
Function Get-ShortPath { | |
Param([string]$name) | |
BEGIN { $fso = New-Object -ComObject Scripting.FileSystemObject } | |
PROCESS { | |
try { | |
$fsi = (Get-Item -LiteralPath $name -ErrorAction Stop) | |
} | |
catch { | |
return $name | |
} | |
$fullname = $fsi.FullName | |
if ($fsi.psiscontainer) { | |
return $fso.GetFolder($fullname).ShortPath | |
} | |
else { | |
return $fso.GetFile($fullname).ShortPath | |
} | |
} | |
} | |
#====================アップロードできなかった時のアラートメール==================== | |
Function Send-Aleart { | |
$mail = @{ | |
from = "XXXXXXXXXX@example.com"; | |
to = "XXXXXXXXXX@example.com"; | |
smtp_server = "smtp.gmail.com"; | |
smtp_port = 587; | |
user = "XXXXXXXXXX@example.com"; | |
password = "XXXXXXXXXX"; | |
} | |
$password = ConvertTo-SecureString $mail["password"] -AsPlainText -Force | |
$credential = New-Object System.Management.Automation.PSCredential $mail["user"], $password | |
Send-MailMessage -To $mail["to"] ` | |
-From $mail["from"] ` | |
-SmtpServer $mail["smtp_server"] ` | |
-Credential $credential ` | |
-Port $mail["smtp_port"] ` | |
-Subject "録画鯖 アップロード失敗" ` | |
-Body "録画したファイルをアップロードできませんでした。" ` | |
-Encoding UTF8 ` | |
-UseSsl | |
} | |
#====================ファイルがロックされていないか確認する==================== | |
#mp4ファイルが存在する = エンコードした場合 | |
Write-Output "Checking MP4 file..." | |
if ( Test-Path "${bas_folder_path}\*${program_id}.mp4" ) { | |
#録画したファイルのパスを取得する | |
$mp4_file = Get-ChildItem -LiteralPath "${bas_folder_path}" | where { $_.Name -match "${program_id}.mp4"} | |
$mp4_file_83path = Get-ShortPath("${bas_folder_path}\${mp4_file}") | |
#エンコード完了するまで待機する | |
Write-Output "Wait for file to be freed by process..." | |
while (Test-FileLock -Path "${mp4_file_83path}") { Start-Sleep 10 } | |
Write-Output "MP4 file ready!" | |
} | |
#念のため5秒待機 | |
Write-Output "Waiting..." | |
Start-Sleep 5 | |
#m2tsファイルが存在する = エンコードしていないかTS削除しなかった場合 | |
Write-Output "Checking TS file..." | |
if ( Test-Path "${bas_folder_path}\*${program_id}.m2ts" ) { | |
#録画したファイルのパスを取得する | |
$ts_file = Get-ChildItem -LiteralPath "${bas_folder_path}" | where { $_.Name -match "${program_id}.m2ts"} | |
$ts_file_83path = Get-ShortPath("${bas_folder_path}\${ts_file}") | |
#使用中かどうか確認し、使用中なら10秒待機して再確認する | |
Write-Output "Wait for file to be freed by process..." | |
while (Test-FileLock -Path "${ts_file_83path}") { Start-Sleep 10 } | |
Write-Output "TS file ready!" | |
} | |
#====================Google ドライブへアップロードする==================== | |
#Google ドライブの指定したフォルダへアップロード後、削除する | |
if ("${gdrive_toggle}" -eq "1") { | |
#一時フォルダを作成 | |
Write-Output "Creating temp folder..." | |
New-Item "${tmp_folder_path}" -itemType Directory -Force | |
#念のため10秒待機 | |
Write-Output "Waiting..." | |
Start-Sleep 10 | |
#出力されたファイルを一時フォルダへ移動 | |
Write-Output "Moving files to temp folder..." | |
Get-ChildItem "${bas_folder_path}" | where { $_.Name -match "${program_id}"} | Move-Item -Destination "${tmp_folder_path}" | |
Write-Output "Uploading..." | |
$arg = "copy ${tmp_folder_path} ${dest_folder_path} -v --config ${config_path}" | |
$proc = Start-Process -FilePath "${rclone_path}" -ArgumentList ${arg} -PassThru -NoNewWindow | |
#タイムアウトの初期化 | |
$timeouted = $null | |
#3時間 (10800秒) 経ってもアップロード完了していなければエラーで止まったと見なす | |
#Google ドライブは通常13GBのファイルを30分程度でアップロードできる | |
#よほど遅い回線か、長時間番組を録らない限り大丈夫なはず | |
$proc | Wait-Process -Timeout 10800 -ea 0 -ev timeouted | |
if ( $timeouted ) { | |
Write-Output "Upload failed with timeout..." | |
#プロセスを終了する | |
$proc | kill | |
#アラートメールを送信する | |
Send-Aleart | |
} | |
elseif ($proc.ExitCode -eq 0) { | |
#Google ドライブへのアップロードが完了したら一時フォルダを削除 | |
Write-Output "Upload completed!" | |
Write-Output "Cleaning temp folder..." | |
Remove-Item "${tmp_folder_path}" -Recurse | |
} | |
#空フォルダを削除 | |
Set-Location ${tmp_bas_folder_path} | |
Get-ChildItem -Recurse | Where-Object { $_.GetType().Name -eq "DirectoryInfo" -and $_.GetFiles().Count -eq 0 } | Remove-Item -Recurse | |
#ログ取得終了 | |
Stop-transcript | |
#古いログファイルを最終更新日順に並べ、最新30個は除外して削除する | |
Get-ChildItem "${log_path}" | | |
Sort-Object LastWriteTime -Descending | | |
Select-Object -Skip 30 | | |
foreach {Remove-Item $_.FullName} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment