2013/06/29

RaspberryPiでRadikoを録音する

さて、久々にピコピコな感じの話題を書きます。

最近はまってるのは、RaspberryPiです。知ってるでしょうか?
http://www.raspberrypi.org

こういうルックスのもので、名刺サイズの基板というヤツです。

なんなのかというと、SDカードにimageファイルを入れるとlinuxやAndroidとして起動できるコンピュータです。



ちょっと起動のシーンだけ動画アップします。

Linuxで起動してるところです。

なんとこのLinuxマシン、3000円ぐらいで買えちゃうんです。
amazonでも買えますが、海外から買うとやや安く買えます。
https://www.modmypi.com

活用方法を考える

活用事例はネットにいろいろ上がっています。その中でも、簡単に試せてかつ便利なRadikoを録音するサーバーにしてしまうというのを紹介します。

用意するもの

僕の場合は、無線LANで使いたかったので、以下のような構成です。
  • RaspberryPi本体 512MBのBタイプ
  • SDカード4GB以上
  • ケース
  • microUSBケーブル
  • スマホ充電器
  • USBのWiFiアダプタ(買ったのはGW-USValue-EZ)
  • USBキーボードとマウス

手順1 まずRaspberryPiにOSを入れる

これはいろんなところで紹介されてるので、それを見てください。
ここがわかりやすいです。

手順2 初期の設定

OSを入れたRaspberryPiをモニターにつなぎ、電源ケーブルを挿すと起動します。
そうすると、BIOSの設定画面風の設定画面が出てきます。
ここで操作するのは、以下のことです。
  • SDカードの領域全体を活用できるようにパーティションを広げる(項目選ぶと勝手にやってくれる)
  • TimezoneをTokyoに設定(Change Timezoneという項目がある)
  • Keyboardのレイアウトを設定(使うキーボードに合わせておく。一応)
で終了すると、再起動されます。

手順3 WiFiの設定

WiFiの設定は、GUIの画面でやると手軽です。

再起動したRaspberryPiにまずログインします。
デフォルトのユーザーはpi、パスワードはraspberryです。
ログインできたら、早速
>startx
と入力しGUI画面を表示します。

するとこんな感じの画面がでてきます。

ここでWiFi Configというアイコンをダブルクリックします。
この画面から、Scanをクリックし、接続したいWiFiのSSIDを探し、パスワードを入力してEnterを押します。

これで無事に接続できると思います。
USBのWiFiアダプタをいきなり認識してるあたりが驚きですよね。

手順4 Radikoを録音するプログラムをインストールする

なんとRadikoを録音するスクリプトを書いて公開してくれてる方がいます。なのでそれを活用させてもらいます。

事前に必要なプログラムを入れてrec_radiko.sh本体もとってきます。

$ sudo apt-get install rtmpdump swftools libxml2-utils ffmpeg
$ cd ~/bin
$ wget https://gist.github.com/raw/3956266/0dc83895770e26a7c37104d896a150c8bb1dffbb/rec_radiko.sh
$ chmod +x rec_radiko.sh

ホームディレクトリの下にbinディレクトリを作ると、一応パスが通るのでそこに入れてます。

早速テストしてみます。

$ mkdir ~/radio
$ rec_radiko.sh TBS 1 ~/radio

これで、ホームディレクトリの下にradioディレクトリを作り、そこにTBSラジオの今の放送を1分間録音するというのが実行されます。

手順5 録音したものはDropboxにアップしたい

録音したら自動でDropboxにアップしたいです。
そこで、Dropbox-Uploaderというスクリプトをダウンロードしてきて使います。
$ cd
$ git clone https://github.com/andreafabrizi/Dropbox-Uploader.git
$ cd Dropbox-Uploader
$ chmod 755 dropbox_uploader.sh
$ mv dropbox_uploader.sh ~/bin/
$ cd ..
$ rm -rf Dropbox-Uploader

これでスクリプトの準備はできました。 Dropbox側にアプリの登録をしないと使えないので、その手続きをします。 PC等のブラウザでDropboxのDeveloperサイトを開きます。 https://www.dropbox.com/developers/apps

ログインした後CreateAppをクリックし、上記のような感じで設定しCreateAppを押します。
そうするとApp keyとApp secretが表示されるのでメモっておいてください。

次に、Dropbox-Uploaderの初期設定をします。

RaspberryPiでdropbox_uploader.shを起動します。

$ ./dropbox-uploader.sh 

 This is the first time you run this script.
 Please open this URL from your Browser, and access using your account:

 -> https://www2.dropbox.com/developers/apps

 If you haven't already done, click "Create an App" and fill in the
 form with the following data:

  App name: MyUploader1544822689
  App type: Core
  Permission type: App folder or Full Dropbox

 Now, click on the "Create" button.

 When your new App is successfully created, please type the
 App Key, App Secret and the Access level:

 # App key: 

App keyとSecretを順に入力します。
# Access level you have chosen, App folder or Full Dropbox [a/f]: f

 > App key is 2ujbx3j9eykglb1, App secret is ghdx1wfrsbjbh4q and Access level is Full Dropbox, it's ok? [y/n]y

 > Token request... OK

 Please visit this URL from your Browser, and allow Dropbox Uploader
 to access your DropBox account:

 --> https://www2.dropbox.com/1/oauth/authorize?oauth_token=*********

Press enter when done...

上記のように答えていくと、URLが表示されるので、そこにPCのブラウザからアクセスします。

そうするとこんな感じの画面がでるので、許可を押します。
その後、RaspberryPiの画面にもどって、Enterを押します。

> Access Token request... OK

 Setup completed!

これで設定は完了です。
使い方は簡単です。

$ dropbox_uploader.sh upload [LOCAL_FILE] [remote_file]
とするとLOCAL_FILEで指定したファイルを、remote_fileで指定したパスに保存されます。 たとえば、こうします。
$ dropbox_uploader.sh upload ~/radio/TBS.mp3 /radio/TBS.mp3

手順6 一連の流れをスクリプトで自動化する

指定した選曲の指定した時間の録音をして、自動で結果をdropboxの/radioフォルダにアップロードするという流れをスクリプトに書いてみます。
bashで書いてみました。

#!/bin/bash

#パラメータをチェック
if [ $# -ne 2 ]
then
        echo 'need channel and time parameter'
        exit 1
fi

#録音開始
echo rec $1 $2
/home/pi/bin/rec_radiko.sh $1 $2 /home/pi/radio

#録音されたファイルが保存される階層のファイルを全部dropboxにアップして消す
files="/home/pi/radio/*"
for filepath in ${files}
do
        #アップロード
        echo ${filepath}
        name=`basename ${filepath}`
        echo 'upload ' ${name} ' to DropBox/radio/' ${name}
        rep=`/home/pi/bin/dropbox_uploader.sh upload ${filepath} /radio/${name}`

        #削除
        case {$rep} in
                *"> DONE"*)
                        echo delete local file ${name}
                        rm ${filepath}
                        ;;
        esac
done

これをvimとかで作成して~/binディレクトリにrecAndUp.shのファイル名で保存します。

$ chmod 755 ~/recAndUp.sh

実行できるようにしておきます。
$ chmod 755 recAndUp.sh

手順7 微調整

僕の場合は毎週録音したのは、爆笑問題のカーボーイというTBSラジオの番組です。これは毎週水曜のAM1時から2時間の放送です。毎週2時間の録音をするので、DropBoxの圧迫も心配なので、できるだけ音質を下げて保存しておきたいです。あとファイル名もデフォルトのrec_radiko.shではコロンとか使ってて表示がおかしくなるので、そこの調整もしておきたいです。
そこで、ソースコード直しました。面倒なので丸ごと貼り付けておきます。

#!/bin/bash

pid=$$
date=`date '+%Y%m%d%H%M'`
playerurl=http://radiko.jp/player/swf/player_3.0.0.01.swf
playerfile="/tmp/player.swf"
keyfile="/tmp/authkey.png"

if [ $# -eq 2 ]; then
  channel=$1
  DURATION=`expr $2 \* 60`
  outdir="."
elif [ $# -eq 3 ]; then
  channel=$1
  DURATION=`expr $2 \* 60`
  outdir=$3
else
  echo "usage : $0 channel_name duration(minuites) [outputdir]"
  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 14 $playerfile -o $keyfile

  if [ ! -f $keyfile ]; then
    echo "failed get keydata"
    exit 1
  fi
fi

if [ -f auth1_fms_${pid} ]; then
  rm -f auth1_fms_${pid}
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 \
     -O auth1_fms_${pid} \
     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_${pid}`
offset=`perl -ne 'print $1 if(/x-radiko-keyoffset: (\d+)/i)' auth1_fms_${pid}`
length=`perl -ne 'print $1 if(/x-radiko-keylength: (\d+)/i)' auth1_fms_${pid}`

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_${pid}

if [ -f auth2_fms_${pid} ]; then
  rm -f auth2_fms_${pid}
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 \
     -O auth2_fms_${pid} \
     https://radiko.jp/v2/api/auth2_fms

if [ $? -ne 0 -o ! -f auth2_fms_${pid} ]; then
  echo "failed auth2 process"
  exit 1
fi

echo "authentication success"

areaid=`perl -ne 'print $1 if(/^([^,]+),/i)' auth2_fms_${pid}`
echo "areaid: $areaid"

rm -f auth2_fms_${pid}

#
# get stream-url
#

if [ -f ${channel}.xml ]; then
  rm -f ${channel}.xml
fi

wget -q "http://radiko.jp/v2/station/stream/${channel}.xml"

stream_url=`echo "cat /url/item[1]/text()" | xmllint --shell ${channel}.xml | tail -2 | head -1`
url_parts=(`echo ${stream_url} | perl -pe 's!^(.*)://(.*?)/(.*)/(.*?)$/!$1://$2 $3 $4!'`)

rm -f ${channel}.xml

#
# rtmpdump
#
rtmpdump -v \
         -r ${url_parts[0]} \
         --app ${url_parts[1]} \
         --playpath ${url_parts[2]} \
         -W $playerurl \
         -C S:"" -C S:"" -C S:"" -C S:$authtoken \
         --live \
         --stop ${DURATION} \
         --flv "/tmp/${channel}_${date}"

ffmpeg -y -i "/tmp/${channel}_${date}" -acodec libmp3lame -ac 1 -ar 32000 -ab 24k "${outdir}/${channel}_${date}.mp3"
if [ $? = 0 ]; then
  rm -f "/tmp/${channel}_${date}"
fi

これで、保存名はTBS_201306260100.mp3などになり、モノラルのサンプリングレート32kHzのビットレートは24kbpsになりファイルサイズをかなり節約できます。音質はAMよりも上、FMよりもやや下というニュアンスかな?ちがうかな。

手順8 cronで自動化

最後にタイマー設定です。linuxにはcronという便利な仕組みがあって、Raspbianにも標準で入ってます。

$ crontab -e

このコマンドでcronの編集画面になります。nanoで開かれます。

0 1 * * 3 /home/pi/bin/recAndUp.sh TBS 120
この一文を最後に追加します。保存し閉じます。
分、時、日、月、曜日、コマンドの順です。
つまり、これで、毎週水曜日の午前1時0分にTBSラジオを120分録音するということになります。

この時点で、cronも有効になりますので、RaspberryPiを立ち上げっぱなしにしておけば自動で録音されて自動でDropboxにアップされます。

終わり

説明すると長いっすね。。
作業自体はサクっと終わると思うんですが、説明するのが難しい。。
今度からはGitHubとかにソースアップしておきます。。。

1 件のコメント:

  1. 参考になりました。
    ビーグルボーンで画像アップロードの方法が分からなくってここにたどり着き
    ソースまで書いてあったので助かりました。

    返信削除