radiko.jpをデバイスを指定して再生する

2017年9月5日一部を追記しました
この記事を書いた当初、booskaさんのスプリクトを参照して記事を書いた為booskaさんのスプリクトの公開が終了した事で記事が継ぎ接ぎなってしまいました。申し訳ございません。

前回の記事で仮想オーディオデバイスを追加したり

仮想オーディオデバイスWsAudioDeviceSを追加する


録音ソフトを検証したりした

radiko.jpのタイムフリーの録音ソフトを検証する


前回の記事で仮想オーディオデバイスを指定してradiko.jpを指定して再生すれば5局まで同時録音できることを説明したが今回、デバイスを指定して再生する事を記事にしたい。

デバイスを指定して再生するにはrtmpdumpとmplayerをコマンドプロンプトで使用する

rtmpdump
https://github.com/K-S-V/Scripts/releases

mplayer
http://mplayerwin.sourceforge.net/downloads.html

-追記-

利用にあたって
wget.exe
https://eternallybored.org/misc/wget/

swfextract.exe
http://www.swftools.org/download.html
swfextract.exeはSWFToolsをインストールしたフォルダにあります。

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

フォルダを作成して解凍して同じ場所に配置する

-追記- 旧型なので飛ばしてください
listen_radiko_TBS.bat

set ch=TBS
for /f %%i in ('AYTHKeyGet.bat') do SET AUTHTOKEN=%%i

rtmpdump -q -flashVer "適当な文字列" -vr "rtmpe://w-radiko.smartstream.ne.jp:1935/%ch%/_definst_/simul-stream.stream" -f " " -C S:"" -C S:"" -C S:"" -C S:%AUTHTOKEN% | mplayer -cache 128 -ao dsound:device=6 )

-追記-AYTHKeyGet.vbs対応の修正版です。
listen_radiko_TBS.bat

set RTMPDUMP=rtmpdump
REM set RTMPSERVER=rtmpe://w-radiko.smartstream.ne.jp:1935
set RTMPSERVER=rtmpe://f-radiko.smartstream.ne.jp:1935
set MPLAYER=mplayer
set AYTHKeyGet=AYTHKeyGet.vbs
set MPLAYER_OPT=-cache 128 -ao dsound:device=1
REM TBS|QRR|LFR|NSB|INT|FMT|FMJ
set ch=TBS
for /f %%i in ('CScript %AYTHKeyGet% %ch%') do SET AUTHTOKEN=%%i
%RTMPDUMP% -q -flashVer "適当な文字列" -vr "%RTMPSERVER%/%ch%/_definst_/simul-stream.stream" -f " " -C S:"" -C S:"" -C S:"" -C S:%AUTHTOKEN% | %MPLAYER% %MPLAYER_OPT% -
)

上記のバッチファイルを作成する
set ch=TBSでチャンネル設定。
AYTHKeyGet.batでAuthTokenの取得を行う。詳しくは後ほど説明する。
set MPLAYER_OPT=-cache 128 -ao dsound:device=1 の任意の数字でデバイスを指定する。サウンドの設定で番号はコロコロ変わるので注意必要だ

-追記-AYTHKeyGet.batは不要になりました。

AYTHKeyGet.vbs

Option Explicit

Dim argStation,argDebug,argSilent,cookiefile,mail,pass,checkfile,loginfile,PROXY,PROXY_T

'radiko premium
mail = ""
pass = ""
'mail = ""pass = ""

'PROXY = ""
PROXY = "" 'プロキシサーバー 例:xx.xx.xx.xx.xx:8080 

argStation = "TBS"	'引数1(i):radiko.jp内の放送局のid
argDebug = "no"		'"yes"なら、動作の途中経過を逐次表示する
argSilent = "yes"	'"yes"なら、外部コマンドであるwgetやrtmpdumpの実行プロンプトを表示しない
loginfile = "login.txt"
cookiefile = "cookie.txt"
checkfile = "pre_check.txt"

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

'プロキシサーバー
If not PROXY = "" Then
  PROXY = " -e HTTP_PROXY=" & PROXY

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 playerurl,pSwfPlayer,pKeyFile,RtnCD,auth1_fms,auth2_fms
  'playerurl = "http://radiko.jp/player/swf/player_4.0.0.00.swf"
  playerurl = "http://radiko.jp/apps/js/flash/myplayer-release.swf"

  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

  'radiko premium
  if not (mail = "") then
    RtnCD = WSHShell.run("wget.exe -q --save-cookie=" & cookiefile _
        & " --keep-session-cookies" & PROXY _
        & " --post-data=""mail=" & mail & "&pass=" & pass & """" _
        & " -O " & loginfile & PROXY _
        & " https://radiko.jp/ap/member/login/login",gShellStyle,True)
    If RtnCD <> 0 Then
      GetRadikoCmd = "error 認証ステップ0:radiko premiumの取得失敗!"
      premiumLogoutCmd()
      Exit Function
    Else
      If argDebug = "yes" Then WScript.Echo "認証ステップ0:radiko premiumの取得成功"
    End If

    WScript.Sleep 2000
    if not objFso.FileExists(cookiefile) then
      WScript.Echo "failed login1"
      premiumLogoutCmd()
      Exit Function
    End IF
  End IF


  'check login
  if not (mail = "") then
    RtnCD = WSHShell.run("wget.exe -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 " & checkfile & PROXY _
        & " https://radiko.jp/ap/member/webapi/member/login/check",gShellStyle,True)
    If RtnCD <> 0 Then
      GetRadikoCmd = "error 認証ステップ0:radiko premiumの取得失敗!"
      premiumLogoutCmd()
      Exit Function
    Else
      If argDebug = "yes" Then WScript.Echo "認証ステップ0:radiko premiumの取得成功"
    End If

    WScript.Sleep 2000 
    if not objFso.FileExists(checkfile) then
      WScript.Echo "failed login2"
      premiumLogoutCmd()
      Exit Function
    End IF
  End IF

  '認証ステップ1:Radikoのswfプレイヤーをplayer.swfというファイル名でダウンロード
  RtnCD = WSHShell.run("wget.exe -q --timeout=60 --tries=10 -O """ & pSwfPlayer & """ """ & playerurl & """" & PROXY ,gShellStyle,True)
  If RtnCD <> 0 Then
    GetRadikoCmd = "error 認証ステップ1:player.swfの取得失敗!"
    premiumLogoutCmd()
    Exit Function
  Else
    If argDebug = "yes" Then WScript.Echo "認証ステップ1:player.swfの取得成功"
  End If

  '認証ステップ2:player.swfからauthkey.pngを抜き出す
  RtnCD = WSHShell.run("swfextract.exe" & " -b 12 """ & pSwfPlayer & """ -o """ & pKeyFile & """",gShellStyle,True)
  If RtnCD <> 0 Then
    GetRadikoCmd = "error 認証ステップ2:authkey.pngの抜き出し失敗!"
    premiumLogoutCmd()
    Exit Function
  Else
    If argDebug = "yes" Then WScript.Echo "認証ステップ2:authkey.pngの抜き出し成功"
  End If

  '認証ステップ3:auth1_fmsを取得
  RtnCD = WSHShell.run("wget.exe -q --timeout=60 --tries=10" _
      & " --header=""pragma: no-cache""" _
      & " --header=""X-Radiko-App: pc_ts""" _
      & " --header=""X-Radiko-App-Version: 4.0.0""" _
      & " --header=""X-Radiko-User: test-stream""" _
      & " --header=""X-Radiko-Device: pc""" _
      & " --post-data=""\r\n""" _
      & " --no-check-certificate" _
      & " --load-cookies " & cookiefile _
      & " --save-headers https://radiko.jp/v2/api/auth1_fms" _
      & " -O """ & auth1_fms & """" & PROXY ,gShellStyle,True)
  If RtnCD <> 0 Then
    GetRadikoCmd = "error 認証ステップ3:auth1_fmsファイルの取得失敗!"
    premiumLogoutCmd()
    Exit Function
  Else
    If argDebug = "yes" Then WScript.Echo "認証ステップ3:auth1_fmsファイルの取得成功"
  End If

  '認証ステップ4:auth1_fmsから、authtoken,length,offsetを読み取る
  Dim pFile
  Dim pLine
  Dim pAuthtoken,pLength,pOffset
  Set pFile = WSHFS.OpenTextFile(auth1_fms,1)
  Do While pFile.AtEndOfStream = False
    pLine = pFile.ReadLine
    If InStr(LCase(pLine),"x-radiko-authtoken=") <> 0 Then
      pAuthtoken = mid(pLine,InStr(pLine,"=")+1,len(pLine)-InStr(pLine,"="))
    ElseIf InStr(LCase(pLine),"x-radiko-keylength=") <> 0 Then
      pLength = mid(pLine,InStr(pLine,"=")+1,len(pLine)-InStr(pLine,"="))
    ElseIf InStr(LCase(pLine),"x-radiko-keyoffset=") <> 0 Then
      pOffset = mid(pLine,InStr(pLine,"=")+1,len(pLine)-InStr(pLine,"="))
    End If
  Loop
  pFile.Close

  If argDebug = "yes" Then WScript.Echo "認証ステップ4:x-radiko-authtoken=" & pAuthtoken & " ,x-radiko-keylength=" & pLength & " ,x-radiko-keyoffset=" & pOffset

  '認証ステップ5:authkey.pngのoffsetのlengthの内容から、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

  If argDebug = "yes" Then WScript.Echo "認証ステップ5:partialkey=" & partialkey

  '認証ステップ6:上記で求めたキーからauthtokenとpartialkeyをradikoに送り認証を成立させる
  Dim key
  RtnCD = WSHShell.run("wget.exe -q --timeout=60 --tries=10" _
        & " --header=""pragma: no-cache""" _
        & " --header=""X-Radiko-App: pc_ts""" _
        & " --header=""X-Radiko-App-Version: 4.0.0""" _
        & " --header=""X-Radiko-User: test-stream""" _
        & " --header=""X-Radiko-Device: pc""" _
        & " --header=""X-Radiko-Authtoken: " & pAuthtoken & """"_
        & " --header=""X-Radiko-Partialkey: " & partialkey & """"_
        & " --post-data=""\r\n""" _
        & " --load-cookies " & cookiefile _
        & " --no-check-certificate" _
        & " https://radiko.jp/v2/api/auth2_fms" _
        & " -O """ & auth2_fms & """" & PROXY ,gShellStyle,True)
  If RtnCD <> 0 Then
    GetRadikoCmd = "error 認証ステップ6:authtokenとpartialkeyの失敗!"
    premiumLogoutCmd()
    Exit Function
  Else
    If argDebug = "yes" Then WScript.Echo "認証ステップ6:authtokenとpartialkeyの送信成功"
  End If
  'テンポラリファイルを消す
  If argDebug <> "yes" Then
    WSHFS.DeleteFile pSwfPlayer, True
    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

    End If
  End If

        WScript.Echo(pAuthtoken)

  premiumLogoutCmd()

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" & PROXY _
      & " 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

上記のスプリクトファイルを作成する

–2016年12月15日修正–
元のRadikoを録音するWSHが公開を停止したためソースを削除しました。下記の記事でAYTHKeyGet.vbsを公開してますので参照してください。
–2017年09月05日修正–
改めてAYTHKeyGet.vbsを記載しました。

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

 

上記のスプリクトは前回の記事で紹介したスプリクトのAuthTokenの取得だけ切り取ってAuthTokenを返すようにしてある

radiko.jpを録音する


こちらの記事の
Radikoを録音するWSH
https//gist.github.com/booska/8861693
から引用した。
もちろんこのスプリクトの指示通りswfextract.exeやwget.exe を取得して使える状態にする必要がある。

これらのファイルを用意してlisten_radiko_TBS.batを実行すると仮想オーディオデバイスにTBSラジオが再生される。もちろん地域によって聞けるチャンネルは違うので任意のチャンネルを指定してください。

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

-2017年09月05日追記-
listen_radiko_TBS.batの
set RTMPSERVER=rtmpe://w-radiko.smartstream.ne.jp:1935が古いURLでした。
正しくは
set RTMPSERVER=rtmpe://f-radiko.smartstream.ne.jp:1935です。
修正してお詫び申し上げます。

-関連記事-

radiko.jpのHLS形式ストリーミングをデバイスを指定して再生する

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)