##前回のあらすじ
raspberry pi をラジオサーバにしてラジオ番組のCMカットを企む
および伊集院光のラジオ番組CMカット自動化のための調査結果①~朝のラジオ~および録音したラジオ番組のCMカット~本編とCMをリネーム分離する~の記事の追加です。本記事では前回までの内容を前提に話を進めます。
#raspberrypiよりもコスパのいいデバイスでラジオ録音がしたい
日本ではraspberrypiの価格が割高なので、orangepiやnanopiなどのコスパのいいデバイスでラジオ録音やストレージサーバ運用が出来たらいいなと思い、実施してみました。
前回記事ではごく当たり前のように導入できたrec_radikoが、swfの終了に伴い利用できなくなってしまったので、そのあたりも含めて過去記事の情報をもとに更新しました。
※一応、swftoolsを自前でビルドすればrec_radikoでも動作しましたが、わざわざフラッシュを使い続けるメリットもないので、ボツにしました。
armbianのインストール
ラズパイや後述のデバイスのcpuであるarmは、我々がよく目にするcpuであるx86やx64とは異なります。このため、windowsや通常のlinuxOSをインストールすることができません。
このため、これらのデバイスではarmに特化したdebianライクOSであるarmbianを導入します。
なおraspberrypiOSは元の名前がraspbianであったことから分かる通り、このarmbianが元になっています。
armbianはデバイスごとにOSが特化しており、デバイスに合わせたOSをインストールすることが推奨されます。
orangepiやnanopiでのarmbianのインストールは、Orange Pi Zero に Armbian をインストールしてみたを参考に、OSインストールしてください。
注意点として、ラズパイと違ってこれらのデバイスは技適認証を受けていないので、必ずwifiを停止させてください。
wifiが使いたければ大人しく割高なラズパイを購入しましょう。
下準備:有線lanのipアドレスとmacアドレスを見つける
armbianでは、raspberrypiOSとは異なり、デフォルトでavahi-daemonが導入されていないため、まずはルーターのDHCPリース設定からipアドレスを探す必要があります。
デバイスの電源を入れてから、ルーターのDHCPリース設定に新しいipアドレスが登録されるまで5分程度かかったので、気長に待ちましょう。
OSをインストールするたびにルーターにアクセスしてipアドレスを探すのは思った以上にしんどいので、一度見つけたら有線のmacアドレスを控えておきましょう。
インストール直後は有線lanでのアクセスのみが見つかるはずなので、後の無線macアドレスが見つけやすくなります。
例)
有線macアドレス 02:42:a1:b1:c1:d1
無線macアドレス 12:42:a1:b1:c1:d1
みたいな感じで、有線lanと無線lanのmacアドレスは、上一桁以外は同じになります。
有線で該当のipアドレスに対してteraterm等を用いてターミナルアクセスをしてください。
最初にrootのパスワードが求められますが、デフォルトのパスワードは「1234」で、最初のログイン時にそのパスワードの変更およびroot以外のユーザの作成を求められます。
ここではraspberrypiに合わせて、ユーザ名を「pi」として話を進めます。
①ホスト名をセットする
armbianにおけるデフォルトでのホスト名は、デバイスと商品型名に依存するようです。orangepizeroであれば、orangepizeroが割り振られています。このままではちょっと味気ないので、まずはホスト名を変更します。armbian-configで設定したほうが簡単ですが、ここではサーバ操作で解説を行います。
$ sudo apt update -y #ホスト変更後にこれをやると設定が初期化される恐れがあるため、必ず最初に行います。
$ sudo apt upgrade -y
$ sudo vim /etc/hostname # hostnameファイルには、ホスト名のみが記述されているため、自分の好きなホスト名に書き換えてください。
$ sudo vim /etc/hosts # 127.0.0.1に紐づくホスト名を変更してください
$ sudo /etc/init.d/networking restart
#②ホスト名でアクセスできるようにする
raspberrypiOSでは、インストール直後にデフォルトでraspberrypi.localでアクセスできます。これは先述の通りraspberrypiOSにはavahi-daemonがデフォルトで導入されているからです。armbianでは自分で設定する必要があります。
$ sudo apt install -y avahi-daemon libnss-mdns
$ sudo systemctl enable avahi-daemon
$ sudo systemctl start avahi-daemon
$ ps -ef |grep radio #hostをradioに設定した場合
avahi 12345 1 0 07:04 ? 00:00:00 avahi-daemon: running [radio.local]
$ sudo reboot
※何度再インストールしてもホスト名でアクセスできない場合、アクセス元のpcにおけるホスト名解決のアプリであるBonjour等に問題がある可能性があります。アクセス元のpcを再起動してみてください。
#③ラジオ録音ツールまたは放送済み番組ダウンロードツールを導入する
この辺りの解説は前述の通り、過去記事の方法ではもう録音できません。
フラッシュのサポート終了に伴い、録音形式が変更されたためです。
Raspberry Pi4 でラジオ録音サーバーを構築するを参考に、radi.shまたはrec_radiko_ts.shを導入してください。
-
- radi.shはrec_radikoと同様にラジオ番組のオンライン録音が可能です。ラジコ以外のインターネットサイマルラジオに対応しているので、NHK らじる★らじる、ListenRadio、JCBAインターネットサイマルラジオ、渋谷のラジオを録音したい場合は、こちらを選択してください。
-
- rec_radiko_ts.shはラジコのタイムフリー機能を利用して、放送済みのラジオ番組をダウンロードする方法です。オンタイムのラジオ録音とは異なり、単純にm4aファイルで音声ファイルをダウンロードするだけなので、2時間半の番組であっても数分でダウンロード可能です。しかも一週間分の番組を遡って聞くことができるので、録音したいラジオがラジコのみの場合は、こちらを利用するのがオススメです。
下記ではrec_radiko_ts.shを利用して放送済みのradikoをダウンロードしてみます。
$ sudo apt install -y curl libxml2-utils ffmpeg
$ git clone https://github.com/uru2/rec_radiko_ts.git
$ mv rec_radiko_ts/rec_radiko_ts.sh .
$ chmod 755 rec_radiko_ts.sh
$ rm rec_radiko_ts/ -rf
$ ./rec_radiko_ts.sh -s TBS -f "`date +\%Y\%m\%d`0000" -t "`date +\%Y\%m\%d`0001" # ためしにTBSラジオを当日の00:00から00:01までの1分ダウンロードする
$ ls # TBSラジオが1分録音したm4aファイルが出来ていればok
#④sambaをインストールする
sambaの導入は、aptで行う事が可能ですが、sambaユーザの作成や公開ディレクトリの設定は手動で行う必要があります。
armbian-configのsoftyで設定したほうが簡単ですが、コマンドも簡単なので紹介を兼ねて説明します。
$ sudo apt install -y samba
$ mkdir /home/pi/samba
$ mkdir /home/pi/samba/radio
$ sudo chmod 755 /home/pi/samba
$ sudo pdbedit -a pi #ユーザ追加
$ sudo vim/etc/samba/smb.conf
最終行に下記を追加
[pi]
comment = Share
path = /home/pi/samba
public = no
read only = no
browsable = yes
force user = pi
$ sudo systemctl restart smbd nmbd
上記の設定で、共有サーバ「\\radio.local」にアクセスすればsambaの共有ディレクトリを確認できます。
#⑤一週間分のラジオを録音できるツールを導入する(rec_radiko_ts限定)
さて、せっかく一週間分のラジオ番組がダウンロードできるようになったので、放送局と曜日と時間を指定して番組がダウンロードできるようにしてみようと思います。
ついでに、rec_radiko_tsは必ずm4aファイルでダウンロードしてしまう仕様があるため、これをmp3に変換します。
さらについでにCMカットもやってみます。※倍速設定は等倍にしています
bashファイル内に録音の設定を書くのがイマイチではありますが、分かり易さを重視してここに記述するようにしました。
#!/bin/bash
# rec_radiko_ts.shのpath
rec_shell_path=/home/pi/rec_radiko_ts.sh
# 出力対象ディレクトリのpath
output_dir=/home/pi/samba/radio
# DLしたm4aや分割前のmp3を削除するかどうか
is_delete_m4a=false
is_delete_mp3=false
# 録音設定 ※スペース区切りで7つの設定をダブルクォーテーションで囲う
# 第0設定:ラジオ局 例)TBS ※ラジコにおける放送局アルファベット
# 第1設定:曜日 例)TUE ※曜日3文字アルファベット
# 第2設定:開始日時 例)0100 ※hhmm
# 第3設定:録音時間 例)120 ※分
# 第4設定:タイトル 例)伊集院光・深夜の馬鹿力 ※スペース利用不可
# 第5設定:CM対象無音時間 例)1.6 ※この秒数を上回る無音でファイルが区切られる
# 第6設定:CM対象ファイルサイズ 例)0 ※無音時間でsplitされたmp3ファイルのうち、このサイズを下回ったファイルについてはCMとみなし、ファイル名の頭に「_」を付与します。
settings=(
"TBS MON 0830 150 伊集院光とらじおと 1.2 1000000"
"TBS TUE 0100 120 伊集院光・深夜の馬鹿力 1.6 0"
"TBS TUE 0830 150 伊集院光とらじおと 1.2 1000000"
"TBS WED 0830 150 伊集院光とらじおと 1.2 1000000"
"TBS THU 0830 150 伊集院光とらじおと 1.2 1000000"
)
today=`date +"%Y%m%d"`
# 曜日の判定。当日から6日間遡って対象番組をダウンロードする
week_num=`date -d ${today} '+%w'`
sun=`date -d "${today} $((week_num - 0 < 0 ? week_num + 0 : week_num - 0)) days ago" +%Y%m%d`
mon=`date -d "${today} $((week_num - 1 < 0 ? week_num + 6 : week_num - 1)) days ago" +%Y%m%d`
tue=`date -d "${today} $((week_num - 2 < 0 ? week_num + 5 : week_num - 2)) days ago" +%Y%m%d`
wed=`date -d "${today} $((week_num - 3 < 0 ? week_num + 4 : week_num - 3)) days ago" +%Y%m%d`
thu=`date -d "${today} $((week_num - 4 < 0 ? week_num + 3 : week_num - 4)) days ago" +%Y%m%d`
fri=`date -d "${today} $((week_num - 5 < 0 ? week_num + 2 : week_num - 5)) days ago" +%Y%m%d`
sat=`date -d "${today} $((week_num - 6 < 0 ? week_num + 1 : week_num - 6)) days ago" +%Y%m%d`
echo sun=${sun}
echo mon=${mon}
echo tue=${tue}
echo wed=${wed}
echo thu=${thu}
echo fri=${fri}
echo sat=${sat}
for ((i=0; ${#settings[*]}>$i; i++))
do
tmp=(${settings[$i]})
# 第0設定:ラジオ局 例)TBS ※ラジコにおける放送局アルファベット
station=${tmp[0]}
# 第1設定:曜日 例)TUE ※曜日3文字アルファベット
dayOfWeek=${tmp[1]}
if [ ${dayOfWeek} = "SUN" ] ; then
day=${sun}
elif [ ${dayOfWeek} = "MON" ] ; then
day=${mon}
elif [ ${dayOfWeek} = "TUE" ] ; then
day=${tue}
elif [ ${dayOfWeek} = "WED" ] ; then
day=${wed}
elif [ ${dayOfWeek} = "THU" ] ; then
day=${thu}
elif [ ${dayOfWeek} = "FRI" ] ; then
day=${fri}
elif [ ${dayOfWeek} = "SAT" ] ; then
day=${sat}
fi
# 第2設定:開始日時 例)0100 ※hhmm
startTime=${tmp[2]}
# 第3設定:録音時間 例)120 ※分
recTime=${tmp[3]}
nowRecSecond=`date +"%s"`
endRecSecond=`date -d "${day} ${startTime:0:2}:${startTime:2:2} ${recTime} minutes" "+%s"`
if [ $nowRecSecond -lt $endRecSecond ]; then
day=`date -d "$day 7 days ago" +"%Y%m%d"`
echo "Target is ${day}"
fi
startRec=${day}${startTime}
# 第4設定:タイトル 例)伊集院光・深夜の馬鹿力 ※スペース利用不可
title=${tmp[4]}
echo ${title}_"recTime=$startRec"_`date -d "${day} ${startTime:0:2}:${startTime:2:2} ${recTime} minutes" "+%Y%m%d%H%M"`
# 第5設定:CM対象無音時間 例)2.0
skip_silence_time=${tmp[5]}
# 第6設定:CM対象ファイルサイズ 例)0 ※深夜の馬鹿力は、構成スタッフの交代により、無音時間が増えてしまったためなのか正しいCMカットが出来なくなっているので、暫定的にCMカットを省いています。
cm_file_size=${tmp[6]}
# m4aファイルサイズ ※ダウンロードしたm4aファイルのサイズ確認です。このサイズを超えていればダウンロードに成功したと判断します。1分あたり345kbぐらいです。
m4a_file_size=$((${recTime} * 345 * 1000))
# mp3ファイルサイズ ※変換したmp3ファイルのサイズ確認です。このサイズを超えていれば変換に成功したと判断します。1分あたり935kbぐらいです。
mp3_file_size=$((${recTime} * 935 * 1000))
# 分割mp3出力対象ディレクトリ
target_dir=${output_dir}/${title}_${day}
# DLしたラジオ番組
m4a_file=${output_dir}/${title}_${day}.m4a
# mp3化したラジオ番組
mp3_file=${output_dir}/${title}_${day}.mp3
# 前回実施m4aファイルの存在およびファイルサイズ判定
if [ -f ${m4a_file} ]; then
# 前回実施m4aファイルが存在していても、ファイルが指定バイトより小さい場合は削除して作り直す
if [ `wc -c ${m4a_file} | awk '{print $1}'` -lt ${m4a_file_size} ]; then
echo rm -f ${m4a_file}
rm -f ${m4a_file}
fi
fi
# 前回実施mp3ファイルの存在およびファイルサイズ判定
if [ -f ${mp3_file} ]; then
# 前回実施mp3ファイルが存在していても、ファイルが指定バイトより小さい場合は削除して作り直す
if [ `wc -c ${mp3_file} | awk '{print $1}'` -lt ${mp3_file_size} ]; then
echo rm -f ${mp3_file}
rm -f ${mp3_file}
fi
fi
# 分割済みディレクトリが存在しない場合のみ実行
if [ ! -d ${target_dir} ]; then
# m4aファイルが存在しない場合のみDL実行
if [ ! -f ${m4a_file} ]; then
# ラジオ番組m4aファイルのダウンロード開始
echo sh ${rec_shell_path} -s ${station} -f ${startRec} -d ${recTime} -o ${m4a_file}
sh ${rec_shell_path} -s ${station} -f ${startRec} -d ${recTime} -o ${m4a_file}
fi
# 既にmp3ファイルが存在する場合、ファイルは指定バイトを満たしているはずなのでスルー
if [ ! -f ${mp3_file} ]; then
# ダウンロードしたm4aファイルが指定バイトを満たしている場合のみ実行する
if [ `wc -c ${m4a_file} | awk '{print $1}'` -ge ${m4a_file_size} ]; then
# ラジオ番組m4aファイルをmp3に変換する
echo ffmpeg -i "${m4a_file}" -vf setpts=PTS/1.0 -af atempo=1.0 -write_xing 0 -id3v2_version 0 "${mp3_file}"
ffmpeg -i "${m4a_file}" -vf setpts=PTS/1.0 -af atempo=1.0 -write_xing 0 -id3v2_version 0 "${mp3_file}"
fi
fi
# mp3ファイルの分割を行う
if [ -f ${mp3_file} ]; then
# mp3分割の開始
echo mp3splt -sn -p th=-50,min=${skip_silence_time},shot=10 -d "${target_dir}" "${mp3_file}"
mp3splt -sn -p th=-50,min=${skip_silence_time},shot=10 -d "${target_dir}" "${mp3_file}"
# 分割後ディレクトリを777に
echo chmod -R 777 "${target_dir}"
chmod -R 777 "${target_dir}"
fi
# m4aファイルの削除
if "${is_delete_m4a}" ; then
echo rm -f ${m4a_file}
rm -f ${m4a_file}
fi
# mp3ファイルの削除
if "${is_delete_mp3}" ; then
echo rm -f ${mp3_file}
rm -f ${mp3_file}
fi
fi
if [ -d ${target_dir} ]; then
# 指定ファイルバイトを下回っているmp3ファイル名の頭に「_」をつける
for file in `find "${target_dir}" -type f`
do
if [[ ! ${file##*/} =~ ^\_.*$ ]]; then
fsize=`wc -c ${file} | awk '{print $1}'`
if [ ${fsize} -lt ${cm_file_size} ]; then
mv "${file}" "${target_dir}/_${file##*/}"
fi
fi
done
fi
done
#⑥cronの設定
cronは、放送前や放送中でさえなければ、いつ実行しても大丈夫です。
その日の録音予約の番組が終了した後に動作するように設定しましょう。
週に1度実行するもよし、念のため毎日実行するもよし、です。
毎日実行する場合、無音分割後のディレクトリがあれば再取得はしません。
ディレクトリが存在しない場合でも、mp3とm4aが規定バイト数を満たしている場合は再取得や再変換を行いません。
$ su - # chownが入るので、suで行う必要がある
$ crontab -e
SHELL=/bin/bash
0 12 * * * /home/pi/radiko_dl.bash
0 15 * * * /home/pi/radiko_dl.bash
0 18 * * * /sbin/shutdown -r now