気象通報、午後 16 時の放送のみに減らされてから、リアルタイムで聞ける機会が減って、リアルタイムで天気図を書くことが難しくなりましたね。ということで、気象通報を録音することにしました、って言う話。
らじる★らじるを録音する
らじる★らじるは、ラジオ放送をオンラインでストリーミング配信するサービスですが、HLS (HTTP Live Streaming) というプロトコルを用いています。詳しくは以下のサイトが参考になります。
第95回 「らじる☆らじる」をHLS経由で:玩式草子─ソフトウェアとたわむれる日々|gihyo.jp … 技術評論社
HLS に触れてみる
HLS は動画(らじる★らじるの場合は音声だけですが)を 10 秒程度の塊(MPEG2 TS (Transport Stream))に分けて、それを順に配信することで、ライブストリーミングを実現しています。そして、この形式でライブストリーミングを実現するためには、配信された TS ファイルをどの順で再生するかを指定することが重要になります。
再生順を指定するために、HLS では M3U という形式のプレイリストのフォーマットを用いています。M3U 自体は、HLS 特有のフォーマットではなく、他のメディアプレイヤーアプリでも用いられている形式です。すでに広まっている形式のプレイリストに則ることで、様々なメディアプレイヤーが HLS に対応しやすくなるという算段ですね。
とりあえず、らじる★らじるの HLS 形式の配信元は、この XML ファイルに書いてあるので、例えば、札幌の NHK 第 2 放送を取得してみましょう。
上のリンクをそのまま開くと、ライブストリーミングが開始されます(動作はブラウザによると思われますが、macOS の Safari ではストリーミングが開始されました)。この URL が本当に M3U 形式であるか確認するために、wget
してみましょう。
% wget https://nhkradioakr2-i.akamaihd.net/hls/live/511929/1-r2/1-r2-01.m3u8
--2019-06-16 22:20:47-- https://nhkradioakr2-i.akamaihd.net/hls/live/511929/1-r2/1-r2-01.m3u8
nhkradioakr2-i.akamaihd.net (nhkradioakr2-i.akamaihd.net) をDNSに問いあわせています... 58.159.200.101, 58.159.200.117
nhkradioakr2-i.akamaihd.net (nhkradioakr2-i.akamaihd.net)|58.159.200.101|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 1002 [application/x-mpegURL]
`1-r2-01.m3u8' に保存中
1-r2-01.m3u8 100%[===============================================>] 1002 --.-KB/s 時間 0s
2019-06-16 22:20:47 (28.1 MB/s) - `1-r2-01.m3u8' へ保存完了 [1002/1002]
中身を確認します。
% less 1-r2-01.m3u8
#EXTM3U
#EXT-X-VERSION:2
#EXT-X-TARGETDURATION:11
#EXT-X-MEDIA-SEQUENCE:4655832
#EXTINF:10,
1-r2-20171211T180234-01-2327/1832.ts
#EXTINF:10,
1-r2-20171211T180234-01-2327/1833.ts
#EXTINF:10,
1-r2-20171211T180234-01-2327/1834.ts
#EXTINF:10,
1-r2-20171211T180234-01-2327/1835.ts
#EXTINF:10,
1-r2-20171211T180234-01-2327/1836.ts
#EXTINF:10,
1-r2-20171211T180234-01-2327/1837.ts
(以下略)
ここに書かれている ts ファイルを wget
してみましょう。(ここに書いてあるコマンドをそのまま実行しても、もとの M3U プレイリストは時間ごとに更新されるので、実行できないと思われます。落としてきたプレイリストの中身を見て、wget する先を書き直してください)
% wget https://nhkradioakr2-i.akamaihd.net/hls/live/511929/1-r2/1-r2-20171211T180234-01-2327/1832.ts
--2019-06-16 22:23:59-- https://nhkradioakr2-i.akamaihd.net/hls/live/511929/1-r2/1-r2-20171211T180234-01-2327/1832.ts
nhkradioakr2-i.akamaihd.net (nhkradioakr2-i.akamaihd.net) をDNSに問いあわせています... 58.159.200.117, 58.159.200.101
nhkradioakr2-i.akamaihd.net (nhkradioakr2-i.akamaihd.net)|58.159.200.117|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 87044 (85K) [video/MP2T]
`1832.ts' に保存中
1832.ts 100%[===============================================>] 85.00K --.-KB/s 時間 0.03s
2019-06-16 22:23:59 (2.98 MB/s) - `1832.ts' へ保存完了 [87044/87044]
ダウンロードされた TS ファイルを開いてみると、音声ファイルであることがわかります。macOS ならば、open 1832.ts
とすれば、端末上からアプリケーションを起動できるので便利です。
ということで、配信元の実体は、テキストベースの M3U プレイリストであることがわかりました。
ffmpeg に録音させる
ということで、某のアプリケーションに、HLS をダウンロードさせると、らじる★らじるを録音できる、という結論になります。
そして、ffmpeg の入力先(-i
オプション)に HLS の URL を指定すると、ダウンロードできます。試しに、30 秒ほどデータをダウンロードさせましょう。-t
オプションが、ダウンロードする時間の指定になります。
% ffmpeg -i https://nhkradioakr2-i.akamaihd.net/hls/live/511929/1-r2/1-r2-01.m3u8 -t 30 -movflags faststart -c copy -bsf:a aac_adtstoasc test.m4a
test.m4a
を開くと、ダウンロードできていることが確認できます。
ということで、気象通報を録音するためには、毎日 16 時にこのコマンドを実行すればよいということがわかりました。今後のことを考えて、これをシェルスクリプト化します。とりあえず、~/radio/
以下に音声を保存することにして、スクリプトもそこに置くことにします。以下のシェルスクリプトでは、次のように変更しています。
- 配信に遅延が発生することも考慮して、録音時間を 22 分間としている。
- ファイル名を日付にしている。
$(date -I)
で、date -I
の結果がそこに入ります。
#! /bin/bash
ffmpeg -i https://nhkradioakr2-i.akamaihd.net/hls/live/511929/1-r2/1-r2-01.m3u8 -t 1320 -movflags faststart -c copy -bsf:a aac_adtstoasc ~/radio/$(date -I).m4a
実行権を与えるのを忘れてはいけません。
% chmod 744 rec.sh
指定時刻にコマンドを実行する。
指定時間にコマンドを実行するためには、cron
を使いましょう。cron
は、設定ファイルで指定さた時刻に、指定されたコマンドを実行してくれます。
まず、自分が cron
で実行するようにしていたコマンドがあるかを確認してみましょう。
% crontab -l
crontab: no crontab for hitomisan
設定ファイルを書き換えるためには、-e
オプションを使います。
% crontab -e
crontab: no crontab for hitomisan - using an empty one
なにが easiest じゃ。 pic.twitter.com/FGk2ui3Gnc
— ひとみさん🤮 a.k.a. Carele Smith (@CareleSmith9) June 15, 2019
作成する crontab の内容は次のようになります。一番最後の行以外は、初回作成時に勝手に書き込まれています。
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
59 15 * * * ~/radio/rec.sh
ここで、59 15 * * * ~/radio/rec.sh
は、「59 分」「15 時」「毎日」「毎月」「すべての曜日」に「~/radio/rec.sh
」を実行するという設定になります。1 分早く録音を開始されるのは、ほかのコマンドとバッティングしないようにするためです。一般的に、0 分に cron するのは避けるべきと言われています。
あとは録音されるのを待つだけ
ここまで設定を済ませると、あとは勝手に録音が行われます、やったね。
しかし、録音させるためには、録音開始の時点で、設定したパソコンが起動していて、設定したユーザーがログインしている必要があります。