RTMPDUMPによるradikoの録音
June 6, 2011 – 3:04 pm radikoのRTMPDUMPによる録音方法についてメモしておいた。
以前、「RTMPDUMPによるストリーミングデータのダウンロード」で書いた方法で録音することができたものが、3月半ばから認証手続きの変更により録音できなくなっていた。
最近になってWeb上で関連情報をさがしてみたところ、新しい認証方法について記述したサイトが見つかった、この方法を参考に我がLinuxサーバー上で録音可能なことを確かめることができた。
注) 2012/10/26にradikoの仕様が変更された。修正版の shell script を参照のこと。
録音方法が掲載されていたサイトのURLは“https://gist.github.com/875864”. このページにradiko録音用のshell scriptが掲げられている。このshell scriptがCentOS5.6上で正常に動作することを確認した。
このshell scriptの動作には、その前提として、rtmpdumpに加えてSWF操作用のツール群swftoolsに含まれるswfextractが必要である。Swftoolsについては、現時点での最新版0.9.1を使用したが、この版のLinux版はソースからビルドしたものを使用している。
Radikoを動作させた環境は、OSはCentOS5.6、RTMPDump, swftoolsのバージョンはそれぞれv2.3、v0.9.1である。
swftoolsのインストール: 上記のshell scriptを動作させるのに手こずったのは、swftoolsのインストールであった。これを乗り切れば、radikoの録音は難なく行うことができる。
インストールの手順を簡単に示すと以下になる:
- swftools(現行での最新版swftools-0,9,1)のダウンロードと展開
[root@ ]# wget http://www.swftools.org/swftools-0.9.1.tar.gz --2011-06-06 14:04:44-- http://www.swftools.org/swftools-0.9.1.tar.gz www.swftools.org をDNSに問いあわせています... 212.112.241.67 www.swftools.org|212.112.241.67|:80 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 2649789 (2.5M) [application/x-gzip] `swftools-0.9.1.tar.gz' に保存中 100%[=========================================================================>] 2,649,789 277K/s 時間 10s 2011-06-06 14:04:56 (248 KB/s) - `swftools-0.9.1.tar.gz' へ保存完了 [2649789/2649789] [root@ ]# tar xvfz swftools-0.9.1.tar.gz swftools-0.9.1/src/swfcombine.1 swftools-0.9.1/src/swfstrings.1 swftools-0.9.1/src/swfdump.1 swftools-0.9.1/src/swfextract.1 ( 以下 省 略 )
- コンパイルに必要なgcc及びライブラリ等(automake, zlib-devel, libjpeg-devel, fiflib-devel, freetyp-devel)のインストール
[root@ ]# yum install gcc* automake zlib-devel libjpeg-devel giflib-devel freetype-devel Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile * addons: www.ftp.ne.jp * base: www.ftp.ne.jp * extras: www.ftp.ne.jp * updates: www.ftp.ne.jp addons | 951 B 00:00 base | 1.1 kB 00:00 extras | 2.1 kB 00:00 updates | 1.9 kB 00:00 Setting up Install Process Package automake-1.9.6-2.3.el5.noarch already installed and latest version Package zlib-devel-1.2.3-3.i386 already installed and latest version Resolving Dependencies --> Running transaction check ---> Package freetype-devel.i386 0:2.2.1-28.el5_5.1 set to be updated --> Processing Dependency: freetype = 2.2.1-28.el5_5.1 for package: freetype-devel ---> Package gcc.i386 0:4.1.2-50.el5 set to be updated --> Processing Dependency: cpp = 4.1.2-50.el5 for package: gcc --> Processing Dependency: libgcc >= 4.1.2-50.el5 for package: gcc ---> Package gcc-c++.i386 0:4.1.2-50.el5 set to be updated --> Processing Dependency: libstdc++-devel = 4.1.2-50.el5 for package: gcc-c++ --> Processing Dependency: libstdc++ = 4.1.2-50.el5 for package: gcc-c++ ---> Package gcc-gfortran.i386 0:4.1.2-50.el5 set to be updated --> Processing Dependency: libgfortran = 4.1.2-50.el5 for package: gcc-gfortran --> Processing Dependency: libgfortran.so.1 for package: gcc-gfortran ---> Package gcc-gnat.i386 0:4.1.2-50.el5 set to be updated --> Processing Dependency: libgnat = 4.1.2-50.el5 for package: gcc-gnat --> Processing Dependency: libgnat-4.1.so for package: gcc-gnat --> Processing Dependency: libgnarl-4.1.so for package: gcc-gnat ---> Package gcc-java.i386 0:4.1.2-50.el5 set to be updated --> Processing Dependency: libgcj-devel = 4.1.2-50.el5 for package: gcc-java --> Processing Dependency: libgcj = 4.1.2-50.el5 for package: gcc-java ---> Package gcc-objc.i386 0:4.1.2-50.el5 set to be updated --> Processing Dependency: libobjc = 4.1.2-50.el5 for package: gcc-objc --> Processing Dependency: libobjc.so.1 for package: gcc-objc ---> Package gcc-objc++.i386 0:4.1.2-50.el5 set to be updated ---> Package gcc44.i386 0:4.4.4-13.el5 set to be updated --> Processing Dependency: libgomp = 4.4.4-13.el5 for package: gcc44 ---> Package gcc44-c++.i386 0:4.4.4-13.el5 set to be updated --> Processing Dependency: libstdc++44-devel = 4.4.4-13.el5 for package: gcc44-c++ ---> Package gcc44-gfortran.i386 0:4.4.4-13.el5 set to be updated --> Processing Dependency: libgfortran44 = 4.4.4-13.el5 for package: gcc44-gfortran --> Processing Dependency: libgfortran.so.3 for package: gcc44-gfortran ---> Package giflib-devel.i386 0:4.1.3-7.3.3.el5 set to be updated --> Processing Dependency: giflib = 4.1.3-7.3.3.el5 for package: giflib-devel ---> Package libjpeg-devel.i386 0:6b-37 set to be updated --> Running transaction check ---> Package cpp.i386 0:4.1.2-50.el5 set to be updated ---> Package freetype.i386 0:2.2.1-28.el5_5.1 set to be updated ---> Package giflib.i386 0:4.1.3-7.3.3.el5 set to be updated ---> Package libgcc.i386 0:4.1.2-50.el5 set to be updated ---> Package libgcj.i386 0:4.1.2-50.el5 set to be updated ---> Package libgcj-devel.i386 0:4.1.2-50.el5 set to be updated ---> Package libgfortran.i386 0:4.1.2-50.el5 set to be updated ---> Package libgfortran44.i386 0:4.4.4-13.el5 set to be updated ---> Package libgnat.i386 0:4.1.2-50.el5 set to be updated ---> Package libgomp.i386 0:4.4.4-13.el5 set to be updated ---> Package libobjc.i386 0:4.1.2-50.el5 set to be updated ---> Package libstdc++.i386 0:4.1.2-50.el5 set to be updated ---> Package libstdc++-devel.i386 0:4.1.2-50.el5 set to be updated ---> Package libstdc++44-devel.i386 0:4.4.4-13.el5 set to be updated --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================== Package Arch Version Repository Size ============================================================================================================== Installing: freetype-devel i386 2.2.1-28.el5_5.1 base 148 k gcc-c++ i386 4.1.2-50.el5 base 3.4 M gcc-gfortran i386 4.1.2-50.el5 base 3.1 M gcc-gnat i386 4.1.2-50.el5 base 11 M gcc-java i386 4.1.2-50.el5 base 2.9 M gcc-objc i386 4.1.2-50.el5 base 2.5 M gcc-objc++ i386 4.1.2-50.el5 base 2.7 M gcc44 i386 4.4.4-13.el5 base 9.5 M gcc44-c++ i386 4.4.4-13.el5 base 4.6 M gcc44-gfortran i386 4.4.4-13.el5 base 4.6 M giflib-devel i386 4.1.3-7.3.3.el5 updates 103 k libjpeg-devel i386 6b-37 base 105 k Updating: gcc i386 4.1.2-50.el5 base 5.2 M Installing for dependencies: libgcj-devel i386 4.1.2-50.el5 base 1.4 M libgfortran i386 4.1.2-50.el5 base 232 k libgfortran44 i386 4.4.4-13.el5 base 256 k libgnat i386 4.1.2-50.el5 base 981 k libobjc i386 4.1.2-50.el5 base 104 k libstdc++-devel i386 4.1.2-50.el5 base 2.8 M libstdc++44-devel i386 4.4.4-13.el5 base 4.0 M Updating for dependencies: cpp i386 4.1.2-50.el5 base 2.7 M freetype i386 2.2.1-28.el5_5.1 base 312 k giflib i386 4.1.3-7.3.3.el5 updates 39 k libgcc i386 4.1.2-50.el5 base 96 k libgcj i386 4.1.2-50.el5 base 16 M libgomp i386 4.4.4-13.el5 base 72 k libstdc++ i386 4.1.2-50.el5 base 362 k Transaction Summary ============================================================================================================== Install 19 Package(s) Upgrade 8 Package(s) Total download size: 80 M Is this ok [y/N]: y Downloading Packages: (1/27): giflib-4.1.3-7.3.3.el5.i386.rpm | 39 kB 00:00 <省 略> (27/27): libgcj-4.1.2-50.el5.i386.rpm | 16 MB 00:06 -------------------------------------------------------------------------------------------------------------- Total 2.2 MB/s | 80 MB 00:36 Running rpm_check_debug Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction Installing : libjpeg-devel 1/35 <省 略> Installed: freetype-devel.i386 0:2.2.1-28.el5_5.1 gcc-c++.i386 0:4.1.2-50.el5 gcc-gfortran.i386 0:4.1.2-50.el5 gcc-gnat.i386 0:4.1.2-50.el5 gcc-java.i386 0:4.1.2-50.el5 gcc-objc.i386 0:4.1.2-50.el5 gcc-objc++.i386 0:4.1.2-50.el5 gcc44.i386 0:4.4.4-13.el5 gcc44-c++.i386 0:4.4.4-13.el5 gcc44-gfortran.i386 0:4.4.4-13.el5 giflib-devel.i386 0:4.1.3-7.3.3.el5 libjpeg-devel.i386 0:6b-37 Dependency Installed: libgcj-devel.i386 0:4.1.2-50.el5 libgfortran.i386 0:4.1.2-50.el5 libgfortran44.i386 0:4.4.4-13.el5 libgnat.i386 0:4.1.2-50.el5 libobjc.i386 0:4.1.2-50.el5 libstdc++-devel.i386 0:4.1.2-50.el5 libstdc++44-devel.i386 0:4.4.4-13.el5 Updated: gcc.i386 0:4.1.2-50.el5 Dependency Updated: cpp.i386 0:4.1.2-50.el5 freetype.i386 0:2.2.1-28.el5_5.1 giflib.i386 0:4.1.3-7.3.3.el5 libgcc.i386 0:4.1.2-50.el5 libgcj.i386 0:4.1.2-50.el5 libgomp.i386 0:4.4.4-13.el5 libstdc++.i386 0:4.1.2-50.el5 Complete!
- コンパイルとビルド
[root@ ]# cd swftools-0.9.1 [root@ swftools-0.9.1]# ./configure checking build system type... i686-pc-linux-gnu checking host system type... i686-pc-linux-gnu checking for gcc... gcc <省 略> [root@ swftools-0.9.1]# make making all in m4... cd m4;make all <省 略> [root@ swftools-0.9.1]# make install <省 略>
以上の手続きで、swftoolsのコマンド群(swfextractなど)は/usr/localbin配下に生成される。
なお、コンパイル時、変数の型にかかわる問題など若干のWarningなどがみられるが、ここで目的とするswfextractは正常に動作する。
Radiko録音用 shell script: 今回、radikoの録音を実験的に確かめるために使用したshell scriptを以下に示しておいた。
#!/bin/sh date=`date '+%Y-%m-%d-%H:%M'` playerurl=http://radiko.jp/player/swf/player_2.0.1.00.swf playerfile=./player.swf keyfile=./authkey.png if [ $# -eq 2 ]; then station=$1 DURATION=`expr $2 \* 60` else echo "usage : $0 station_name duration(minuites)" exit 1 fi # # get player # if [ ! -f $playerfile ]; then wget -q -O $playerfile $playerurl if [ $? -ne 0 ]; then echo "failed get player" exit 1 fi fi # # get keydata (need swftool) # if [ ! -f $keyfile ]; then swfextract -b 5 $playerfile -o $keyfile if [ ! -f $keyfile ]; then echo "failed get keydata" exit 1 fi fi if [ -f auth1_fms ]; then rm -f auth1_fms fi # # access auth1_fms # wget -q \ --header="pragma: no-cache" \ --header="X-Radiko-App: pc_1" \ --header="X-Radiko-App-Version: 2.0.1" \ --header="X-Radiko-User: test-stream" \ --header="X-Radiko-Device: pc" \ --post-data='\r\n' \ --no-check-certificate \ --save-headers \ https://radiko.jp/v2/api/auth1_fms if [ $? -ne 0 ]; then echo "failed auth1 process" exit 1 fi # # get partial key # authtoken=`perl -ne 'print $1 if(/x-radiko-authtoken: ([\w-]+)/i)' auth1_fms` offset=`perl -ne 'print $1 if(/x-radiko-keyoffset: (\d+)/i)' auth1_fms` length=`perl -ne 'print $1 if(/x-radiko-keylength: (\d+)/i)' auth1_fms` partialkey=`dd if=$keyfile bs=1 skip=${offset} count=${length} 2> /dev/null | base64` echo "authtoken: ${authtoken} \noffset: ${offset} length: ${length} \npartialkey: $partialkey" rm -f auth1_fms if [ -f auth2_fms ]; then rm -f auth2_fms fi # # access auth2_fms # wget -q \ --header="pragma: no-cache" \ --header="X-Radiko-App: pc_1" \ --header="X-Radiko-App-Version: 2.0.1" \ --header="X-Radiko-User: test-stream" \ --header="X-Radiko-Device: pc" \ --header="X-Radiko-Authtoken: ${authtoken}" \ --header="X-Radiko-Partialkey: ${partialkey}" \ --post-data='\r\n' \ --no-check-certificate \ https://radiko.jp/v2/api/auth2_fms if [ $? -ne 0 -o ! -f auth2_fms ]; then echo "failed auth2 process" exit 1 fi echo "authentication success" areaid=`perl -ne 'print $1 if(/^([^,]+),/i)' auth2_fms` echo "areaid: $areaid" rm -f auth2_fms # # rtmpdump # /opt/rtmpdump-2.3/rtmpdump -v \ -r "rtmpe://radiko.smartstream.ne.jp" \ --playpath "simul-stream" \ --app "${station}/_defInst_" \ -W $playerurl \ -C S:"" -C S:"" -C S:"" -C S:$authtoken \ --live \ --stop $DURATION \ -o "/tmp/${1}_${date}" ffmpeg -y -i "/tmp/${1}_${date}" -acodec libmp3lame "/var/www/test/audio/${1}_${date}.mp3" rm "/tmp/${1}_${date}"
12 Responses to “RTMPDUMPによるradikoの録音”
はじめまして。
rtmpdumpを用いたradikoの録音、シェルスクリプトを使って実装されているんですね。私はPythonを使って実装したので、大変興味深く読みました。
録音されたファイルの管理はどうされていますか?mp3ファイルのまま貯めこんでいく感じですか?
By yussi on Aug 21, 2011
録音したファイルは、現状では、そのままためこんでいます。今後、システム化を図りたいとは思っています・・。
By yama on Aug 22, 2011
情報有難うございます。とても参考になりました。
が、rtmpdumpのmake/make installやスクリプトの作成まではうまく行ったのですが、スクリプト中のwgetコマンドが
“URLがありません”
でエラーになります。
いろいろググったりして探しては見たのですが、解決方法が分かりません。お時間のあるときにご教示いただければ幸いです。
By Hiroyuki Nakamura on Apr 28, 2012
お騒がせしましたが解決しました。
紹介されていたhttps://gist.github.com/875864のShell ScriptをDLしてflvからmp3にコンバートする行を書き加えると見事に動いてくれました。ありがとございました。
#一応動いたscriptとdiffを取りましたがURLは同じなので何故こちらでないと動かないのかはわかりませんでした^_;
By Hiroyuki Nakamura on Apr 30, 2012
あっ、因みにfedora16で試しましたが、swftools,rtmpdump共にyumでインストール可能でした。
#実際にはmakeしたあとで気がついたんですが・・
By Hiroyuki Nakamura on Apr 30, 2012
Nakamuraさん
しばらくcomment がチェックできない状態で、ご質問にお答えできませんでした。申し訳ない。
ともあれ、うまく動作してよかったです。
わがほうでも、ポストしたもので試したのですが、特段の問題はありませんでした。wgetのエラーなんだったんでしょうね?
愛読感謝です。
By yama on May 2, 2012