radiko.jpのタイムフリーを一括ダウンロードバッチ2022年10月修正
以前に記事にしたradiko.jpのタイムフリーを一括ダウンロードバッチのラジコプレミアムのログイン仕様が変更されたので対応版を作りました。
しかしまだ不明点があって後日修正するかもしれません。
今はこのブログでの活動時間があまりなく更新も時間差があります。
よく調査してないので不十分な点があります。
それでも良ければお付き合いください
利用にあたって
wget.exe
https://eternallybored.org/misc/wget/
ffmpeg.exe
https://ffmpeg.org/
新たにXMLの検証の為xmllintを使います
Windows版xmllintは、
このサイトの
https://www.zlatkovic.com/libxml.en.html
の
Win32 binaries (HTTP)
から、libxml2 バイナリをダウンロードしてください。
iconv-1.9.2.win32.zip
libxml2-2.7.8.win32.zip
zlib-1.2.5.win32.zip
をダウンロードして(将来ファイル名のバージョンは変わるかも)
iconv.dll
libxml2.dll
zlib1.dll
xmllint.exe
を置いてください
各種実行ファイルを集めて一つのフォルダに置いてください
ここでの例としてD:\RadikoRecに置いてます
以下のテキストソースも集めて一つのフォルダに置いてください
AYTHKeyGet.vbs
Option Explicit Dim argStation,argDebug,argSilent,cookiefile,mail,pass,checkfile,loginfile 'radiko premium mail = "" pass = "" argStation = "TBS" '引数1(i):radiko.jp内の放送局のid argDebug = "no" '"yes"なら、動作の途中経過を逐次表示する argSilent = "yes" '"yes"なら、外部コマンドであるwgetの実行プロンプトを表示しない Dim i Dim strCmd Dim objFSO Set objFSO = WScript.CreateObject("Scripting.FileSystemObject") Dim aUnnamed Set aUnnamed = WScript.Arguments.Unnamed If aUnnamed.Count > 0 Then For i = 0 To aUnnamed.Count - 1 Select Case i Case 0 argStation = aUnnamed.Item(i) End Select Next End If 'シェル起動オブジェクトを生成 Dim WSHShell,gShellStyle Set WSHShell = WScript.CreateObject("WScript.Shell") If argSilent = "yes" Then gShellStyle = 7 Else gShellStyle = 10 End IF 'ファイルシステム用オブジェクトを生成(ラジコ独自認証でファイルを利用) Dim WSHFS Set WSHFS = CreateObject("Scripting.FileSystemObject") strCmd = GetRadikoCmd() WScript.Quit(0) 'Radiko.jpの独自認証を行う Function GetRadikoCmd() Dim pSwfPlayer,pKeyFile,RtnCD,auth1_fms,auth2_fms Dim pTmpName pTmpName = WSHFS.GetTempName() pSwfPlayer = "player_" & argStation & pTmpName & ".swf" pKeyFile = "authkey_" & argStation & pTmpName & ".png" auth1_fms = "auth1_fms_" & argStation & pTmpName auth2_fms = "auth2_fms_" & argStation & pTmpName loginfile = "login_" & argStation & pTmpName & ".txt" cookiefile = "cookie_" & argStation & pTmpName & ".txt" checkfile = "pre_check_" & argStation & pTmpName & ".txt" 'radiko premium if not (mail = "") then RtnCD = WSHShell.run("wget.exe -q --save-cookie=" & cookiefile _ & " --keep-session-cookies" _ & " --post-data=""mail=" & mail & "&pass=" & pass & """" _ & " -O " & loginfile _ & " https://radiko.jp/v4/api/member/login",gShellStyle,True) If RtnCD <> 0 Then GetRadikoCmd = "error 認証ステップ0:radiko premiumの取得失敗!" premiumLogoutCmd() Exit Function Else If argDebug = "yes" Then WScript.Echo "認証ステップ0" End If WScript.Sleep 2000 if not objFso.FileExists(cookiefile) then WScript.Echo "failed login1" premiumLogoutCmd() Exit Function End IF End IF Dim pFile Dim pLine Dim pLine1 Dim radiko_session,areafree Dim aryStrings Dim s Set pFile = WSHFS.OpenTextFile(loginfile,1) Do While pFile.AtEndOfStream = False pLine1 = pFile.ReadLine aryStrings = Split(pLine1, ",") For Each s In aryStrings pLine = s pLine =Replace(pLine,"}","") pLine =Replace(pLine,Chr(34),"") If InStr(LCase(pLine),"radiko_session") <> 0 Then radiko_session = mid(pLine,InStr(pLine,":")+1,len(pLine)-InStr(pLine,":")) ElseIf InStr(LCase(pLine),"areafree") <> 0 Then areafree = mid(pLine,InStr(pLine,":")+1) End If Next Loop pFile.Close '認証ステップ1:Radikoのauth1をダウンロード RtnCD = WSHShell.run("wget.exe -q --timeout=60 --tries=10" _ & " --header ""X-Radiko-App: pc_html5""" _ & " --header ""X-Radiko-App-Version: 0.0.1""" _ & " --header ""X-Radiko-Device: pc""" _ & " --header ""X-Radiko-User: dummy_user""" _ & " --save-headers " _ & " -O " & checkfile _ & " https://radiko.jp/v2/api/auth1",gShellStyle,True) If RtnCD <> 0 Then GetRadikoCmd = "error 認証ステップ1:auth1の取得失敗!" premiumLogoutCmd() Exit Function Else If argDebug = "yes" Then WScript.Echo "認証ステップ1" End If '認証ステップ2:RadikoのplayerCommon.jsをダウンロード RtnCD = WSHShell.run("wget.exe -q --timeout=60 --tries=10" _ & " -O """ & auth1_fms & """" _ & " http://radiko.jp/apps/js/playerCommon.js",gShellStyle,True) If RtnCD <> 0 Then GetRadikoCmd = "error 認証ステップ2:playerCommon.jsの取得失敗!" premiumLogoutCmd() Exit Function Else If argDebug = "yes" Then WScript.Echo "認証ステップ2" End If '認証ステップ3:checkfileから、・X-Radiko-AuthToken・X-Radiko-KeyLength・X-Radiko-KeyOffset を読み取る Dim pAuthtoken,pLength,pOffset Set pFile = WSHFS.OpenTextFile(checkfile,1) Do While pFile.AtEndOfStream = False pLine = pFile.ReadLine If InStr(LCase(pLine),"x-radiko-authtoken:") <> 0 Then pAuthtoken = mid(pLine,InStr(pLine,":")+2,len(pLine)-InStr(pLine,":")) ElseIf InStr(LCase(pLine),"x-radiko-keylength:") <> 0 Then pLength = mid(pLine,InStr(pLine,":")+2,len(pLine)-InStr(pLine,":")) ElseIf InStr(LCase(pLine),"x-radiko-keyoffset:") <> 0 Then pOffset = mid(pLine,InStr(pLine,":")+2,len(pLine)-InStr(pLine,":")) End If Loop pFile.Close '認証ステップ4:playerCommon.jsから文字列取得 Dim radikojsplayer Set pFile = WSHFS.OpenTextFile(auth1_fms,1) Do While pFile.AtEndOfStream = False pLine = pFile.ReadLine If InStr(LCase(pLine),"new radikojsplayer") <> 0 Then radikojsplayer = mid(pLine,65,40) End If Loop pFile.Close Dim fso Set fso = WScript.CreateObject("Scripting.FileSystemObject") Dim outputFile Set outputFile = fso.OpenTextFile(pKeyFile, 2, True) outputFile.WriteLine radikojsplayer outputFile.Close '認証ステップ5:playerCommon.jsの内容から、base64の値であるpartialkeyを求める Dim pXmldom,pB64,pStream,partialkey Set pXmldom = CreateObject("Microsoft.XMLDOM") Set pB64 = pXmldom.CreateElement("work") pB64.DataType = "bin.base64" Set pStream = CreateObject("ADODB.Stream") pStream.Type = 1 pStream.Open pStream.LoadFromFile pKeyFile pStream.position = pOffset pB64.NodeTypedValue = pStream.Read(pLength) partialkey = pB64.Text pStream.Close Set pStream = Nothing '認証ステップ6:上記で求めたキーからauthtokenとpartialkeyをradikoに送り認証を成立させる Dim auth2_url_param auth2_url_param = "?radiko_session=" & radiko_session RtnCD = WSHShell.run("wget.exe -q --timeout=60 --tries=10" _ & " --header ""X-Radiko-Device: pc""" _ & " --header=""X-Radiko-Authtoken: " & pAuthtoken & """" _ & " --header=""X-Radiko-Partialkey: " & partialkey & """" _ & " --header ""X-Radiko-User: dummy_user"""_ & " https://radiko.jp/v2/api/auth2" & auth2_url_param _ & " -O """ & auth2_fms & """" ,gShellStyle,True) If RtnCD <> 0 Then GetRadikoCmd = "error 認証ステップ6:authtokenとpartialkeyの失敗!" premiumLogoutCmd() Exit Function Else If argDebug = "yes" Then WScript.Echo "認証ステップ6" End If 'テンポラリファイルを消す If argDebug <> "yes" Then WSHFS.DeleteFile pKeyFile, True WSHFS.DeleteFile auth1_fms, True WSHFS.DeleteFile auth2_fms, True if not (mail = "") then WSHFS.DeleteFile loginfile, True WSHFS.DeleteFile checkfile, True WSHFS.DeleteFile cookiefile, True End If End If WScript.Echo(pAuthtoken) End Function Function premiumLogoutCmd() Dim RtnCD 'radiko premium Logout if not (mail = "") then RtnCD = WSHShell.run("wget -q" _ & " --header=""pragma: no-cache""" _ & " --header=""Cache-Control: no-cache""" _ & " --header=""Expires: Thu, 01 Jan 1970 00:00:00 GMT""" _ & " --header=""Accept-Language: ja-jp""" _ & " --header=""Accept-Encoding: gzip, deflate""" _ & " --header=""Accept: application/json, text/javascript, */*; q=0.01""" _ & " --header=""X-Requested-With: XMLHttpRequest""" _ & " --no-check-certificate "_ & " --load-cookies cookiefile "_ & " --save-headers "_ & " -O logoutfile" _ & " https://radiko.jp/ap/member/webapi/member/logout",gShellStyle,True) If RtnCD <> 0 Then GetRadikoCmd = "error radiko premiumのLogout失敗!" Exit Function Else If argDebug = "yes" Then WScript.Echo "radiko premiumのLogout取得成功" End If if objFso.FileExists(cookiefile) then WSHFS.DeleteFile cookiefile, True End IF End IF End Function
date.vbs
' CScript date.vbs w ' CScript date.vbs /d:-6 Option Explicit dim argDay Dim aNamed Set aNamed = WScript.Arguments.Named argDay = WScript.Arguments. Named.Item("d") Dim strFormattedDate Dim argC Dim i Dim strCmd Dim objFSO Set objFSO = WScript.CreateObject("Scripting.FileSystemObject") Dim aUnnamed Set aUnnamed = WScript.Arguments.Unnamed argC = "" If aUnnamed.Count > 0 Then For i = 0 To aUnnamed.Count - 1 Select Case i Case 0 argC = aUnnamed.Item(i) End Select Next End If if not (argDay = "") Then dim strNow strNow = Now() strFormattedDate = DateAdd("d",argDay,strNow) strFormattedDate = Left(strFormattedDate, 10) strFormattedDate = Replace(strFormattedDate, "/", "") WScript.Echo strFormattedDate End If if (argC = "w") Then WScript.Quit(WeekDay(Date)) End If
日付計算のためのスプリクトです。
timeshift_get.bat
D: cd \RadikoRec set F=./rec/ REM TBS,QRR,LFR,RN1,RN2,INT,FMT,FMJ,JORF,BAYFM78,NACK5,YFM,HOUSOU-DAIGAKU goto DAY :MON for /f %%i in ('CScript date.vbs /d:%dayC%') do SET D=%%i call :get_ts BAYFM78 %D%130000 %D%160000 %F%%D%1300_it exit /b :TUE for /f %%i in ('CScript date.vbs /d:%dayC%') do SET D=%%i call :get_ts BAYFM78 %D%130000 %D%160000 %F%%D%1300_it exit /b :WED for /f %%i in ('CScript date.vbs /d:%dayC%') do SET D=%%i call :get_ts BAYFM78 %D%130000 %D%160000 %F%%D%1300_it exit /b :THU for /f %%i in ('CScript date.vbs /d:%dayC%') do SET D=%%i call :get_ts BAYFM78 %D%130000 %D%160000 %F%%D%1300_it exit /b :FRI for /f %%i in ('CScript date.vbs /d:%dayC%') do SET D=%%i call :get_ts BAYFM78 %D%130000 %D%160000 %F%%D%1300_KISS&SMILE exit /b :SAT for /f %%i in ('CScript date.vbs /d:%dayC%') do SET D=%%i call :get_ts TBS %D%010000 %D%030000 %F%%D%0100_JUNK_バナナマンのバナナムーンGOLD exit /b :SUN for /f %%i in ('CScript date.vbs /d:%dayC%') do SET D=%%i call :get_ts TBS %D%130000 %D%170000 %F%%D%1300_爆笑問題の日曜サンデー exit /b REM ここから処理部分 :DAY cscript /b date.vbs w if %errorlevel%==7 set WDAY=SAT if %errorlevel%==6 set WDAY=FRI if %errorlevel%==5 set WDAY=THU if %errorlevel%==4 set WDAY=WED if %errorlevel%==3 set WDAY=TUE if %errorlevel%==2 set WDAY=MON if %errorlevel%==1 set WDAY=SUN if "%WDAY%" == "MON" ( set /a dayC=-6 call :TUE set /a dayC=-5 call :WED set /a dayC=-4 call :THU set /a dayC=-3 call :FRI set /a dayC=-2 call :SAT set /a dayC=-1 call :SUN set /a dayC=0 call :MON goto end ) if "%WDAY%" == "TUE" ( set /a dayC=-6 call :WED set /a dayC=-5 call :THU set /a dayC=-4 call :FRI set /a dayC=-3 call :SAT set /a dayC=-2 call :SUN set /a dayC=-1 call :MON set /a dayC=0 call :TUE goto end ) if "%WDAY%" == "WED" ( set /a dayC=-6 call :THU set /a dayC=-5 call :FRI set /a dayC=-4 call :SAT set /a dayC=-3 call :SUN set /a dayC=-2 call :MON set /a dayC=-1 call :TUE set /a dayC=0 call :WED goto end ) if "%WDAY%" == "THU" ( set /a dayC=-6 call :FRI set /a dayC=-5 call :SAT set /a dayC=-4 call :SUN set /a dayC=-3 call :MON set /a dayC=-2 call :TUE set /a dayC=-1 call :WED set /a dayC=0 call :THU goto end ) if "%WDAY%" == "FRI" ( set /a dayC=-6 call :SAT set /a dayC=-5 call :SUN set /a dayC=-4 call :MON set /a dayC=-3 call :TUE set /a dayC=-2 call :WED set /a dayC=-1 call :THU set /a dayC=0 call :FRI goto end ) if "%WDAY%" == "SAT" ( set /a dayC=-6 call :SUN set /a dayC=-5 call :MON set /a dayC=-4 call :TUE set /a dayC=-3 call :WED set /a dayC=-2 call :THU set /a dayC=-1 call :FRI set /a dayC=0 call :SAT goto end ) if "%WDAY%" == "SUN" ( set /a dayC=-6 call :MON set /a dayC=-5 call :TUE set /a dayC=-4 call :WED set /a dayC=-3 call :THU set /a dayC=-2 call :FRI set /a dayC=-1 call :SAT set /a dayC=0 call :SUN goto end ) echo date.vbs処理エラー pause :get_ts set ch=%1 set ft=%2 set to=%3 set AYTHKeyGet=AYTHKeyGet.vbs del timeshift.m3u8 for /f %%i in ('CScript %AYTHKeyGet% %ch%') do SET AUTHTOKEN=%%i wget "https://radiko.jp/v3/station/stream/pc_html5/%ch%.xml" for /f %%i in ('xmllint --xpath "/urls/url[@areafree=1][@timefree=1][1]/playlist_create_url/text()" %ch%.xml') do SET PLAYLIST_URL=%%i DEL %ch%.xml DEL %ch%.xml.? ffmpeg -headers "X-Radiko-AuthToken: %AUTHTOKEN%" -i "%PLAYLIST_URL%?station_id=%ch%&start_at=%ft%&ft=%ft%&end_at=%to%&to=%to%&l=15&lsid=99999999999999999999999999999999&type=c" "%4.ts" exit /b :end
注意点
ffmpegの行の
lsid=99999999999999999999999999999999
は何のためのIDか不明です。9の文字はダミーです。
しかしこのIDを付加しないと400 Bad Requestになります。
将来の個人特定のIDかもしれませんが
今の所モニターしている限り固定値です
基本的にブラウザーのネットワークモニターで
m3u8ファイルを監視して
lsid=をコピペしたほうが無難です
xmllintでURLを抽出するターゲットとして
[@areafree=1][@timefree=1]
を指定してますエリアフリーなら1を
タイムフリーなら1を指定してください
XMLファイルからURLを抽出して
ダウンロードするように変更しましたが
このURLでダウンロードすると1倍速でダウンロードされて
時間がかかるようになりました
かなり不便になりました
不明な点が多いですがもし指摘点がございましたらコメントください
注意点終わり
毎日いつ実行してもいい状況を想定して書いてあります。
F=./rec/は録音ファイルのフォルダー名です。
MON(月)TUE(火)WED(水)THU(木)FRI(金)SAT(土)SUN(日)
なと曜日でダウンロードしたい日に番組を指定していきます。
get_ts 局名 開始時間 終了時間 録音ファイル名 です
EXITでバッチが終了します。
タイムフリーは一週間分しかダウンロードできません。
ラジコプレミアムに加入してればどの地域の人でも
ダウンロードできます。