玩式草子─ソフトウェアとたわむれる日々

第74回「らじる☆らじる」rtmpdumpで

当初、今回は前回の続きでスキャンした「お講」文書を読解する話の予定だったものの、本連載で以前に紹介した「らじる☆らじる」の録音スクリプトが9月1日から急に動かなくなるという問題が生じたため、予定を変更して「らじる☆らじる」録音スクリプトを改修した話題を紹介することにしました。

「らじる☆らじる」の配信方式

NHKラジオの番組を放送と同時にインターネットでも配信する「らじる☆らじる」については、2011年に始まったころからとりあげてきました。開始当初、⁠らじる☆らじる」は、Adobe Flashplayerを利用する配信方式と共に、Windows Media Playerで再生できる方式(WMA:Window Media Audio)でも配信されていました。

Adobe社が配布しているAdobe Flashplayer(libflash.so)を利用すれば、Linux上のFirefoxからでも「らじる☆らじる」を再生することはできるものの、バイナリでしか配布されないlibflash.soはOSSではありませんし、Adobe Flashplayerにはしばしばセキュリティ上の問題が指摘されます。一方、Adobe FlashをやりとりするRTMP(Real Time Media Protocol)をOSSとして実装したrtmpdumpコマンドは、⁠らじる☆らじる」の配信が始まった2011年当時、まだ機能や信頼性に欠けていました。

そのため、自作の録音用スクリプトではmplayer経由でWMA形式の音声をダウンロードするような形にしていたものの、⁠らじる☆らじる」におけるWMA配信は次第に脇に追いやられ、2015年度から「試行の最終段階」として利用者の聴取状況把握にAdobe Analyticsを使うようになったのに合わせ、目の不自由な人の「読み上げ用」として残されていた配信も8月末で完全に終了してしまいました。

WMA形式での配信が終了してしまったので「らじる☆らじる」の録音を続けるにはスクリプトをAdobe Flashに対応させるしかありません。そこで急遽録音用スクリプトの改修に取りかかりました。

録音用スクリプトの改修

「らじる☆らじる」がどのようなURLで番組を配信しているかは、スマホ用アプリなどが参照するconfig_pc.xmlというファイルで定義されています。

config_pc.xml(一部)
<?xml version="1.0" encoding="UTF-8"?>
<radiru_config>
      <!-- お知らせ情報テキスト(中身はHTML) -->
      <info><![CDATA[/netradio/files/include/oshirase.txt]]></info>
      <!-- 各地域のストリームURL -->
      <stream_url>
             <data>
                      <areajp>仙台</areajp>
                      <area>sendai</area>
                      <apikey>600</apikey>
                      <r1><![CDATA[rtmpe://netradio-hkr1-flash.nhk.jp/live/NetRadio_HKR1_flash@108442]]></r1>
                      <r2><![CDATA[rtmpe://netradio-r2-flash.nhk.jp/live/NetRadio_R2_flash@63342]]></r2>
                      <fm><![CDATA[rtmpe://netradio-hkfm-flash.nhk.jp/live/NetRadio_HKFM_flash@108237]]></fm>
                      <oshirase><![CDATA[/netradio/files/include/oshirase_sendai.txt]]></oshirase>
                      <banners><![CDATA[/netradio/files/include/banners_sendai.txt]]></banners>
              </data>
              <data>
                      <areajp>東京</areajp>
                      <area>tokyo</area>
                      <apikey>001</apikey>
                      <r1><![CDATA[rtmpe://netradio-r1-flash.nhk.jp/live/NetRadio_R1_flash@63346]]></r1
...

このファイルを見ると、NHK仙台放送局の番組はrtmpe://netradio-hkr1-flash.nhk.jp/live/NetRadio_HKR1_flash@108442というURLで配信されていることがわかります。

とりあえず配信元のURLはわかったものの、そこからデータをどうダウンロードするんだろう、と、rtmpdumpと「らじる☆らじる」をキーワードに検索してみたら、文字通り、「らじる☆らじる」をrtmpdumpで録音するためのコードを紹介しているページが見つかりました。

このページによると、たとえばNHK FMの配信は

rtmpdump --rtmp "rtmpe://netradio-fm-flash.nhk.jp" \
         --playpath 'NetRadio_FM_flash@63343' \
         --app "live" \
         --swfVfy http://www3.nhk.or.jp/netradio/files/swf/rtmpe.swf \
         --live \
         -o fm.m4a

という指定でダウンロードできるようです。

指定されているオプションのうち、--swfVfyは配信されているAdobe Flashを再生するためのプレイヤーの指定で、⁠らじる☆らじる」のソースコードからインクルードされているJavaScript(common.js)の中で指定されているようです。こんなのよく調べたなぁ…、と感心しつつ、この指定を流用させてもらうことにしました。

さて、上記のような指定でダウンロードできることがわかれば、後はmplayer経由で録音していた部分をrtmpdump経由に改造するだけです。具体的にはradiru_rec.pyのチャンネル定義部分をRTMP経由に書きかえて、

206      if channel == 'r1':
207          rtmp='rtmpe://netradio-r1-flash.nhk.jp'
208          playpath='NetRadio_R1_flash@63346'
209      elif channel == 'r2':
210          rtmp='rtmpe://netradio-r2-flash.nhk.jp'
211          playpath='NetRadio_R2_flash@63342'
212      elif channel == 'fm':
213          rtmp='rtmpe://netradio-fm-flash.nhk.jp'
214          playpath='NetRadio_FM_flash@63343'
215      else:
216          print("channel set error:{0}".format(channel))
217          usage()
218          sys.exit(1)

生成する録音用スクリプトもrtmpdumpを使うように修正しました。

229      lines.append('#!/bin/sh')
230      lines.append('flvfile={0}/{1}.flv'.format(musicdir, title))
231      lines.append('m4afile={0}/{1}.m4a'.format(musicdir, title))
232      lines.append('(rtmpdump --rtmp {0} --playpath {1} --app "live" \
              --swfVfy "http://www3.nhk.or.jp/netradio/files/swf/rtmpe.swf" \
              --quiet --live --stop {2} -o $flvfile ) &'.format(rtmp, playpath, sduration))
233      lines.append('sleep 1m')
234      lines.append('radiru_noa.py {0} $m4afile'.format(channel))
235      lines.append('sleep {0}m'.format(duration))
236      lines.append('ffmpeg -loglevel error -i $flvfile -acodec copy $m4afile 237      lines.append('if [ -f "$m4afile" ]; then ')
238      lines.append('    rm -f $flvfile')
239      lines.append('fi')
240      lines.append('radiru_tag.py $m4afile')
241      lines.append('rm -f {}'.format(scriptname))
242      lines.append('')
243      script = "\n".join(lines)

このスクリプトでは、232行目でrtpdumpを使って受信したデータを"番組名.flv"という名前で保存してから、236行目でffmpegを使ってそのファイルを"番組名.m4a"に変換しています。このあたりは録音した番組を携帯音楽プレイヤーで再生するための調整で、多くの携帯音楽プレイヤー(手元のはSony Walkman)はMPEG-4 Audioなファイル(.m4a)は再生できるものの、Adobe Flashなファイル(.flv)には対応していません。そのため、rtmpdumpでダウンロードしたAdobe Flashファイルをffmpegを使ってMP4ファイルに変換しているわけです。

番組情報書き込み機能の修正

録音ファイルをMP3形式からMP4形式に変更するに伴い、番組情報をタグに書きこむ処理にも修正が必要になりました。従来使っていたeyeD3というコマンドはMP3形式のタグ(ID3タグ)専用で、MP4形式のタグ(正確にはメタ・データ)は扱えません。そのため、新たにMP4形式のタグを操作するツールを調べてみたところ、灯台下暗し、Plamo Linuxにも収録しているmp4v2というソフトウェアに含まれているmp4tagsというコマンドが使えることに気づきました。

mp4tagsは文字通り、MP4形式のタグを操作するためのツールです。

$ mp4tags
mp4tags: You must specify at least one MP4 file.
usage mp4tags OPTION... FILE...
Adds or modifies iTunes-compatible tags on MP4 files.

      -help            Display this help text and exit
      -version         Display version information and exit
  -A, -album       STR  Set the album title
  -a, -artist      STR  Set the artist information
  -b, -tempo       NUM  Set the tempo (beats per minute)
  -c, -comment     STR  Set a general comment
  ...
  -z, -artistid    NUM  Set the artist ID
  -Z, -composerid  NUM  Set the composer ID
  -r, -remove      STR  Remove tags by code (e.g. "-r cs"
                        removes the comment and song tags)

ざっと確認したところ、eyeD3とほぼ同じ情報が書き込めるようなので、以前はradiru_id3.pyとしていたタグファイル書き込み用のコマンドをradiru_tag.pyに改名してMP4形式のタグを書き込むようにしました。mp4tagsは外部コマンドなのでsubprocessモジュール経由で利用しています。

48    def set_tag(file, tag):
49        import subprocess
50        mp4file = file.replace('.flv','.m4a')
51        filename = os.path.basename(mp4file)
52        date = filename.split("_")
53        mytitle = date[0] + '_' + tag['title'].encode('utf-8')
54        title = " -song '{}' ".format(mytitle)
55        album = " -album'{}' ".format(tag['album'].encode('utf-8'))
56        artist = " -artist '{}' ".format(tag['act'].encode('utf-8'))
57        if len(tag['contents']) > 0:
58            comment = " -comment '{}' ".format(tag['contents'].encode('utf-8'))
59            cmdlist = ['mp4tags ', file, title, album, artist, comment, mp4file]
60        else:
61            cmdlist = ['mp4tags ', file, title, album, artist, mp4file]
62    
63        cmd = "".join(cmdlist)
64        p = subprocess.call(cmd, shell=True)

録音ファイルの確認

これらの修正を加えたradiru_rec.pyとradiru_tag.pyを使って、⁠らじる☆らじる」の番組を録音してみました。

VLCでタグファイルの情報を確認すると、番組タイトルや出演者、楽曲情報等が正しく記録されているようです。

図1 VLCで録音したファイルのメディアデータを表示
図1 VLCで録音したファイルのメディアデータを表示

これらの情報は、mp4v2パッケージに含まれているmp4infoコマンドでも確認できます。

$ mp4info 2015-09-29-06-00_古楽の楽しみ-ヴィヴァルディの音楽-_002.m4a 
mp4info version 2.0.0
2015-09-29-06-00_古楽の楽しみ-ヴィヴァルディの音楽-_002.m4a:
Track	Type	Info
1	audio	MPEG-4 AAC LC, 3300.010 secs, 48 kbps, 48000 Hz
 Name: 古楽の楽しみ -ヴィヴァルディの音楽-(2)
 Encoded with: Lavf56.4.101
 Comments: 今谷和徳
- ヴィヴァルディの音楽 -(2)「バイオリンと弦楽合奏および通奏低音のための協奏曲 二長調
作品8 第11 RV.210」ヴィヴァルディ作曲
(11分50秒)
(バイオリン)エンリコ・カサッツァ
(合奏)ラ・マニフィカ・コムニタ
 ...

しばらく新しいスクリプトを使ってみたところ、予約状況をチェックするradiru_check.pyや予約を取り消すradiru_del.pyにも修正が必要なことがわかり、それらも合わせて更新して、⁠らじる☆らじる」録音用ツールのrtmpdump化が完了しました。

Adobe Flashでは音声の圧縮にHE-AAC形式を利用しています。HE-AACはMP3よりも後発のCODECで、MP3よりも圧縮率が高く、低いビットレートでも高音質なことを売りにしています。実際、15分の語学番組を録音したファイルのサイズを比べてみたところ、1/3程度にまで小さくなっているようです。

$ ls -lh
-rw-r--r-- 1 kojima users  15M  8月 28日  07:01 2015-08-28-06-45_ラジオ英会話_2015_08_020.mp3
-rw-r--r-- 1 kojima users 5.3M  9月  4日  07:01 2015-09-04-06-45_ラジオ英会話_2015_09_005.m4a

また、WMAで録音していた際に悩まされていた配信の遅延もほぼ無くなる共に、rtmpdumpには何分記録するかを指定するオプション(--stop)も用意されているので、mplayerのようにFIFOを使って外から終了させるような処理も不要になって、録音スクリプトの信頼性も高まったように感じます。

これならもっと早くに乗り替えててもよかったな、と思う反面、⁠壊れていないものを直すな」という考え方もあるので、判断は難しいところです(苦笑⁠⁠。

なお、今回紹介したradiru_rec.py等のスクリプトや処理に必要なrtmpdumpの新しいパッケージは筆者の日記のページに添付しておきますので、ご興味のある方はダウンロードしてお試しください。

OSC 2015 Tokyo/Fallへの出展のお知らせ

最後に少し話題が変りますが、10/24-25に東京、日野市の明星大学で開催されるオープンソースカンファレンス2015 Tokyo/FallにPlamo Linuxメンテナグループが出展することになりましたことを紹介します。

ブース展示には両日とも出展し、MacBookで動くPlamo Linuxの展示やlxc-plamoの紹介、インストールメディアの配布等を行う予定です。また初日(10/24)の11時からは、メンテナの松木さんがPlamo Linuxに関するセミナーを行います。

Plamo Linuxの主要メンテナも顔を揃えますし、配布するメディアには新バージョンとなるPlamo-6.0を収めようと鋭意作業を進めていますので、Plamo Linuxに興味ある方はぜひご来訪くださいませ。

おすすめ記事

記事・ニュース一覧