Time.vbsにバグがありました


Time.vbsは録音時間計算のスプリクトです。バッチファイルで時間計算は大変なのでWSHで処理します。
しかし終了時間0時近辺の録音が停止しないバグがあったので調べました。

以前の Time.vbs

' CScript Time.vbs /r:0:01:00
' CScript Time.vbs /d:2016/12/14 /t:00:01:00

Option Explicit
Dim argRecTime
Dim value
dim gRecTime
dim argDay
dim argTime
Dim aNamed
Set aNamed = WScript.Arguments.Named

argRecTime = WScript.Arguments.Named.Item("r")
argDay = WScript.Arguments. Named.Item("d")
argTime = WScript.Arguments. Named.Item("t")

if not (argRecTime = "") Then

  '引数で指定の録音時間を日時属性に変換
  gRecTime = TimeValue(argRecTime)

  '録音終了日時を求める
  Dim gEndDate
  gEndDate = Now() + gRecTime
  WScript.Echo gEndDate
End If

if not (argTime = "") Then

  '引数で指定の録音時間を日時属性に変換
  argRecTime = TimeValue(argTime)
  argDay = DateValue(argDay)

  argRecTime = argDay + argRecTime

  '録音秒数をrtmpdumpの引数形式(秒数)にする
  gRecTime = argRecTime - Now()
  if (gRecTime > 0) Then
    gRecTime = Hour(gRecTime) * 60 * 60 + Minute(gRecTime) * 60 + Second(gRecTime) + 20
    '20秒ほどマージンを設けることで録音終了時の誤差でリトライにいってしまうことを防止する。
  Else
    gRecTime ="EXIT"
  End If
  WScript.Echo gRecTime

End If

このスプリクトだと録音終了日時が0:00:00だと省略されて日付のみ返す事がわかりました。秒に直すと文字列を返さないため永遠に録音されます。

新しい Time.vbs

' CScript Time.vbs /r:0:01:00
' CScript Time.vbs /d:2016/12/14 /t:18:47:44

Option Explicit
Dim argRecTime
Dim value
dim gRecTime
dim argDay
dim argTime
Dim aNamed
Set aNamed = WScript.Arguments.Named

argRecTime = WScript.Arguments.Named.Item("r")
argDay = WScript.Arguments. Named.Item("d")
argTime = WScript.Arguments. Named.Item("t")

if not (argRecTime = "") Then

    '引数で指定の録音時間を日時属性に変換
    gRecTime = TimeValue(argRecTime)

    '録音終了日時を求める
    Dim gEndDate
    gEndDate = Now() + gRecTime
    WScript.Echo gEndDate

End If

if not (argDay = "") Then

    '引数で指定の録音時間を日時属性に変換

    argDay = DateValue(argDay)

    if (argTime = "") Then
        argRecTime = argDay
    Else
        argRecTime = TimeValue(argTime)
        argRecTime = argDay + argRecTime
    End If

    '録音秒数をrtmpdumpの引数形式(秒数)にする
    gRecTime = argRecTime - Now()
    if (gRecTime > 0) Then
        gRecTime = Hour(gRecTime) * 60 * 60 + Minute(gRecTime) * 60 + Second(gRecTime) + 20
        '20秒ほどマージンを設けることで録音終了時の誤差でリトライにいってしまうことを防止する。
    Else
        gRecTime ="EXIT"
    End If
    WScript.Echo gRecTime

End If

そこで0:00:00で空欄の場合、秒計算で時間の引数を計算しないようにしました

 


らじる★らじるをバッチファイルとWSHで録音する


以前の記事でらじる★らじるを録音する方法を記事にした。
-注意-
今回はNHKラジオのらじる★らじるを録音する記事です

その時、github.comのbooskaのらじる★らじるを録音するWSHのスプリクトを利用することで録音することを紹介していた。しかし、booskaさんのソースは公開中止になってしまった。

いろいろ検討した結果、booskaさんのスプリクトを参照してバッチファイルとWSHで作成した。現在動作確認中だがほぼ利用可能な状況になったのでここに紹介することにする

おまけでコミュニティFMのJCBA系列と超A&G!が録音できます。

作成はWindows 10環境で作成しています。動作確認はWindows 7です。

利用にあたって
rtmpdump.exe
https://github.com/K-S-V/Scripts/releases

ffmpeg.exe
http://hp.vector.co.jp/authors/VA020429/ffmpeg/ffmpeg.html
https://ffmpeg.org/

各種実行ファイルを集めて一つのフォルダに置いてください

RajiruRec.bat

@echo off

REM rtmpdumpなどの位置のドライブ
set drive=D:

REM rtmpdumpなどの位置(最後に\を)
set DFDirectory=D:\RajiruRec\

REM 録音ファイルの保存のドライブ
set argdrive=D:

REM 録音ファイルの保存先(最後に\を)
set argDirectory=D:\RajiruRec\rec\

set RTMPDUMP=rtmpdump.exe
set argOut = "out"

%drive%
cd %DFDirectory%

rem 録音ファイルの保存先フォルダチェックと作成
IF NOT EXIST "%argDirectory%" (md %argDirectory%)
IF NOT EXIST "%argDirectory%OLD" (md %argDirectory%OLD)

set ch=%1
if "%1"=="" goto usage
if not "%2"=="" set argSTOPSEC=%2
if "%2"=="" goto usage
if not "%3"=="" set argOut=%3

rem 録音終了日時を求める
for /f "tokens=1,2" %%i in ('CScript Time.vbs /r:%argSTOPSEC%') do (
    SET AUTHTOKEN_D=%%i
    SET AUTHTOKEN_T=%%j
)

REM NHKの連想配列
REM R1東京
if %ch%==R1 (
    set aaNHK_r=rtmpe://netradio-r1-flash.nhk.jp
    set aaNHK_y=NetRadio_R1_flash@63346
    )
REM R2東京
if %ch%==R2 (
    set aaNHK_r=rtmpe://netradio-r2-flash.nhk.jp
    set aaNHK_y=NetRadio_R2_flash@63342
    )
REM FM東京
if %ch%==FM (
    set aaNHK_r=rtmpe://netradio-fm-flash.nhk.jp
    set aaNHK_y=NetRadio_FM_flash@63343
    )
REM R2東京
if %ch%==JOAB (
    set aaNHK_r=rtmpe://netradio-r2-flash.nhk.jp
    set aaNHK_y=NetRadio_R2_flash@63342
    )
REM R1東京
if %ch%==JOAK (
    set aaNHK_r=rtmpe://netradio-r1-flash.nhk.jp
    set aaNHK_y=NetRadio_R1_flash@63346
    )
REM R1仙台
if %ch%==JOHK (
    set aaNHK_r=rtmpe://netradio-hkr1-flash.nhk.jp
    set aaNHK_y=NetRadio_HKR1_flash@108442
    )
REM R1名古屋
if %ch%==JOCK (
    set aaNHK_r=rtmpe://netradio-ckr1-flash.nhk.jp
    set aaNHK_y=NetRadio_CKR1_flash@108234
    )
REM R1大阪
if %ch%==JOBK (
    set aaNHK_r=rtmpe://netradio-bkr1-flash.nhk.jp
    set aaNHK_y=NetRadio_BKR1_flash@108232
    )
REM FM東京
if %ch%==JOAK-FM (
    set aaNHK_r=rtmpe://netradio-fm-flash.nhk.jp
    set aaNHK_y=NetRadio_FM_flash@63343
    )
REM FM仙台
if %ch%==JOHK-FM (
    set aaNHK_r=rtmpe://netradio-hkfm-flash.nhk.jp
    set aaNHK_y=NetRadio_HKFM_flash@108237
    )
REM FM名古屋
if %ch%==JOCK-FM (
    set aaNHK_r=rtmpe://netradio-ckfm-flash.nhk.jp
    set aaNHK_y=NetRadio_CKFM_flash@108235
    )
REM FM大阪
if %ch%==JOBK-FM (
    set aaNHK_r=rtmpe://netradio-bkfm-flash.nhk.jp
    set aaNHK_y=NetRadio_BKFM_flash@108233
    )

REM JCBAの連想配列
REM 参考URL https://radioserver2.jimdo.com/
REM はっぴぃ!FM
if %ch%==JOZZ0BE-FM (
    set aaJCBA=rtmpe://jcbasimul061-live1.sp1.fmslive.stream.ne.jp/jcbasimul061-live1/_definst_/jcbasimul061-live
)
REM FM西東京
if %ch%==JOZZ3AU-FM (
    set aaJCBA=rtmp://jcbasimul003-live1.sp1.fmslive.stream.ne.jp/jcbasimul003-live1/_definst_/jcbasimul003-live
)
REM むさしのFM
if %ch%==JOZZ3AG-FM (
    set aaJCBA=rtmp://jcbasimul032-live1.sp1.fmslive.stream.ne.jp/jcbasimul032-live1/_definst_/jcbasimul032-live
)
REM FMえどがわ
if %ch%== JOZZ3AS-FM (
    set aaJCBA=rtmp://jcbasimul033-live1.sp1.fmslive.stream.ne.jp/jcbasimul033-live1/_definst_/jcbasimul033-live
)
REM 超A&G!の録音パラメータ
if %ch%== AG (
    set aaJCBA=rtmp://fms-base1.mitene.ad.jp/agqr/aandg22
)

set loopck=0

:loop

rem 録音時間を秒に変換
for /f %%i in ('CScript Time.vbs /d:%AUTHTOKEN_D% /t:%AUTHTOKEN_T%') do SET AUTHTOKEN_END=%%i
set STOPSEC=--stop %AUTHTOKEN_END%

if "%loopck%" == "0" set FLV_loop=
if "%loopck%" geq "1" set FLV_loop=(%loopck%)

set yyyymmdd=%date: =0%
set hhmmss=%time: =0%
set YMD=%yyyymmdd:~0,4%%yyyymmdd:~5,2%%yyyymmdd:~8,2%_%hhmmss:~0,2%%hhmmss:~3,2%%hhmmss:~6,2%
set FLV=%YMD%_%ch%_%argOut%

set RADI_PASS=

REM らじる★らじるの録音パラメータ
if not "%aaNHK_r%"=="" (
set RADI=%RTMPDUMP% -flashVer "WIN 15,0,0,152" --rtmp "%aaNHK_r%" --timeout 10 --playpath "%aaNHK_y%" --app ""live"" -W ""http://www3.nhk.or.jp/netradio/files/swf/rtmpe.swf"" --live -o "%argDirectory%%FLV%%FLV_loop%.flv" %STOPSEC%
    set RADI_PASS=1
)
REM JCBAの録音パラメータ
if not "%aaJCBA%"=="" (
    set RADI=%RTMPDUMP% --quiet -flashVer "WIN 15,0,0,152" --rtmp "%aaJCBA%" --timeout 10 --live -o "%argDirectory%%FLV%%FLV_loop%.flv" %STOPSEC%
    set RADI_PASS=1
)

if "%RADI_PASS%"=="" goto usage

echo 録音開始%date%_%time%_"%~3" >> log.txt
echo 「%ch%」の「%argOut%」を録音開始、録音時間は「%argSTOPSEC%」
echo %RADI%
%RADI%
echo 録音停止%date%_%time%_"%~3" >> log.txt

for /f %%i in ('CScript Time.vbs /d:%AUTHTOKEN_D% /t:%AUTHTOKEN_T%') do SET AUTHTOKEN_EXIT=%%i
if "%AUTHTOKEN_EXIT%" == "EXIT" goto loopEXIT
if "%loopck%" geq "20" goto loopEXIT
set /a loopck=loopck+1

REM Sleep[15秒数]
set /a wtime=15*1000
echo WScript.Sleep %wtime% > tmp.vbs
cscript //NoLogo tmp.vbs
del tmp.vbs
set wtime=
REM ***

goto loop

:loopEXIT

%argdrive%
cd %argDirectory%
for %%F in (*.flv) do goto FILE_EXIST
echo エラーファイルが無い%date%_%time%_%argOut% >> %DFDirectory%log.txt
goto end

:FILE_EXIST
echo MP3変換開始%date%_%time%_"%argOut%" >> %DFDirectory%log.txt
REN *"%argOut%"*.flv *.m4a
for %%i in (*"%argOut%"*.m4a) do %DFDirectory%ffmpeg.exe  -y -i "./%%~ni.m4a" -vn -acodec libmp3lame -strict unofficial "./%%~ni.mp3"
move *"%argOut%"*.m4a OLD\ >> %DFDirectory%log.txt
echo MP3変換完了%date%_%time%_"%argOut%" >> %DFDirectory%log.txt
goto end

:usage
echo "RajiruRec.bat JOAK 0:01:00 NHK深夜便"
echo "RajiruRec.bat JOZZ3AU-FM 0:01:00 JCBA_FM西東京"
echo "RajiruRec.bat AG 0:01:00 超A&G!"

:end

D:\RajiruRec\にて実行する設定になっています
途中で回線が切断されても時間計算して再録音し最後にmp3に変換するようになっています。
-起動例-
RajiruRec.bat JOAK 1:00:00 NHK深夜便
RajiruRec.bat JOAK 録音時間1時間 録音番組名(ファイル名に含まれます)
コールサインが引数になってます。
R1東京はJOAK、R2東京はJOAB
JCBA系列のFM西東京はJOZZ3AU-FM
他のエリアは下記のURLを参考にバッチファイルを変更してください
参考URL https://radioserver2.jimdo.com/
超A&G!はAGです

Time.vbs

' CScript Time.vbs /r:0:01:00
' CScript Time.vbs /d:2016/12/14 /t:18:47:44

Option Explicit
Dim argRecTime
Dim value
dim gRecTime
dim argDay
dim argTime
Dim aNamed
Set aNamed = WScript.Arguments.Named

argRecTime = WScript.Arguments.Named.Item("r")
argDay = WScript.Arguments. Named.Item("d")
argTime = WScript.Arguments. Named.Item("t")

if not (argRecTime = "") Then

    '引数で指定の録音時間を日時属性に変換
    gRecTime = TimeValue(argRecTime)

    '録音終了日時を求める
    Dim gEndDate
    gEndDate = Now() + gRecTime
    WScript.Echo gEndDate

End If

if not (argDay = "") Then

    '引数で指定の録音時間を日時属性に変換

    argDay = DateValue(argDay)

    if (argTime = "") Then
        argRecTime = argDay
    Else
        argRecTime = TimeValue(argTime)
        argRecTime = argDay + argRecTime
    End If

    '録音秒数をrtmpdumpの引数形式(秒数)にする
    gRecTime = argRecTime - Now()
    if (gRecTime > 0) Then
        gRecTime = Hour(gRecTime) * 60 * 60 + Minute(gRecTime) * 60 + Second(gRecTime) + 20
        '20秒ほどマージンを設けることで録音終了時の誤差でリトライにいってしまうことを防止する。
    Else
        gRecTime ="EXIT"
    End If
    WScript.Echo gRecTime

End If

録音時間計算のスプリクトです。バッチファイルで時間計算は大変なのでWSHで処理します

2016年12月28日 修正しました

Time.vbsにバグがありました

 

schtasks.bat

goto kome

/sc 種類 	スケジュールの種類を指定する。指定できる種類は次の通り。
種類 	内容
MINUTE 	分単位でスケジュールを指定
HOURLY 	時間単位でスケジュールを指定
DAILY 	日単位でスケジュールを指定
WEEKLY 	週単位でスケジュールを指定
MONTHLY 	月単位でスケジュールを指定
ONCE 	指定した日時に一回限り実行
ONSTART 	システム起動ごとに実行
ONLOGON 	ログオンごとに実行
ONIDLE 	アイドル状態が一定時間続いた場合に実行

/d 日 	曜日または日にちを指定する。 スケジュールの種類が「WEEKLY」、または「MONTHLY」の場合に有効。
曜日は以下のように3文字で表す。
値 	内容
MON 	月曜日
TUE 	火曜日
WED 	水曜日
THU 	木曜日
FRI 	金曜日
SAT 	土曜日
SUN 	日曜日
スケジュールの種類と指定できる値は次の通り。
WEEKLYの場合 MON~SUN、あるいは「*(毎日)」。 省略時は「/d MON」を指定したとみなされる。
MONTHLYの場合 1~31の数字。省略時は「/d 1」 を指定したとみなされる。「/mo」オプションに
FIRST、SECOND、THIRD、FOURTH、LAST が指定されている場合は、必ず「/d」オプションで曜日を指定する。

SCHTASKS /CREATE /TN "NHK今日は一日アニソン三昧" /TR "D:\RajiruRec\RajiruRec.bat JOAK-FM 16:04:00 NHK今日は一日アニソン三昧" /sd 2016/04/30 /st 08:58 /sc once

:kome
SCHTASKS /CREATE /TN "NHK深夜便0005" /TR "D:\RajiruRec\RajiruRec.bat JOAK 0:57:00 NHK深夜便" /SC WEEKLY /d * /ST 00:04

pause

タスクスケジューラを使って予約する為のバッチファイル
(schtasks.batは管理者として実行してください)

以上2つの実行ファイルと2つのバッチファイルと1つのvbsファイルと同じフォルダに置いて(上記の例ではD:\RajiruRec)
schtasks.batに録音したい番組を記入してタスクスケジューラに登録して実行する形になります。
タスクスケジューラにて実行するため後日動作確認する時用に実行フォルダにLOGを残す動きになっています。時々ファイルを削除してください

このスプリクトは試験的なもので要望など、いかなるサポートも行いません。 録音失敗や何らかの、いかなる損害が発生しても、苦情などを一切受け付けません。全て自己責任で利用してください。

関連記事

radiko.jpをバッチファイルとWSHで録音する


radiko.jpを録音する


–2016年12月15日追記–

radiko.jpをバッチファイルとWSHで録音する

–2016年12月10日追記–
Radikoを録音するWSHが公開中止になりました
後日別の方法で録音する記事を書く予定です
申し訳ございません

 

2016021101.jpg
前回のらじる★らじるがうまくいったのでradiko.jpを録音も挑戦することにした
2016021102.jpg
現在、Radikaで録音しているがアプリの更新が終わってしまって
普通の手段では使えない
つくったもの公開所
http://koukaijo.seesaa.net/

そこで前回のらじる★らじるを録音するで使用したスプリクトと
同様のスプリクトを使用した
Radikoを録音するWSH
https://gist.github.com/booska/8861693
前回同様、コピペして必要なツールを用意して動作を確認する
前回同様、SCHTASKSを使用してタスクスケジューラに
登録して録音予約


この様にバッチファイルで引数を渡す
ファイル名 schtasks.bat
SCHTASKS /CREATE /TN “QRR_音楽リッスン?2-3小松未可子” /TR “D:\RadikoRec\RadikoRec.bat QRR 1:01:00 音楽リッスン?2-3小松未可子” /SC WEEKLY /d TUE /ST 01:59

タスクスケジューラを使用すると直接csript.exeを実行しにくい
バッチファイルで起動して引数を渡す事にした

その為、バッチファイルで起動して引数を渡すも同様
ファイル名RadikoRec.bat
D:
CD \RadikoRec
echo 録音開始
cscript RadikoRec.vbs /i:”%~1″ /t:”%~2″ /d:”rec\” /o:”%~3″ /s:No
echo 録音停止
cd D:\RadikoRec\rec\
for %%F in (*.flv) do goto FILE_EXIST
echo エラーファイルが無い
goto END
:FILE_EXIST
echo MP3変換開始
REN *”%~3″*.flv *.m4a
for %%i in (*”%~3″*.m4a) do D:\RadikoRec\bin\ffmpeg.exe -y -i “./%%~ni.m4a” -vn -acodec libmp3lame -strict unofficial “./%%~ni.mp3”
move D:\RadikoRec\rec\*”%~3″*.m4a D:\RadikoRec\rec\OLD\
echo MP3変換完了
:END

この様にバッチファイルで引数を渡す
ここまでは順調通り動作
数日間様子を見ていた
しかし、ラジオ番組は00:00から一時間との様に
一斉に他チャンネルも録音する
同時に録音開始するとRadiko.jpの独自認証
のダウンロードでバッティングするみたいだ
重複しないテンポラリファイル名を生成して
るらしいが同時間では重複するみたいだ
そこでRadikoRec.vbsを修正する。
ファイル名RadikoRec.vbs
‘同時複数起動でのファイル名バッティング対策で、重複しないテンポラリファイル名を生成する

Dim pTmpName
pTmpName = WSHFS.GetTempName()
pSwfPlayer = “tmp\player_” & pTmpName & “.swf”
pKeyFile = “tmp\authkey_” & pTmpName & “.png”
auth1_fms = “tmp\auth1_fms_” & pTmpName
auth2_fms = “tmp\auth2_fms_” & pTmpName
この行に
pSwfPlayer = “tmp\player_” & argStation & pTmpName & “.swf”
pKeyFile = “tmp\authkey_” & argStation & pTmpName & “.png”
auth1_fms = “tmp\auth1_fms_” & argStation & pTmpName
auth2_fms = “tmp\auth2_fms_” & argStation & pTmpName

とargStationを追加する修正をした
argStationは’引数1(i):radiko.jp内の放送局のidなので
ファイル名にTBSなどの文字列が追加される
同じ局で同タイミングでの録音は無いと思うのでこれで対応する
これで今晩も録音しながら様子を見る

2016年10月12日修正点が発生しました

radiko.jpのタイムフリー対応による録音ツールの変更について