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

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

この記事を読むのに必要な時間:およそ 5.5 分

当初,今回は前回の続きでスキャンした「お講」文書を読解する話の予定だったものの,本連載で以前に紹介した「らじる☆らじる」の録音スクリプトが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形式での配信には遅延が目立つようになり,録音用スクリプトの待ち時間を増やして調整した記憶があります。今から考えれば,次第にWMA形式の配信用の帯域を絞っていたのかも知れません。

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で配信されていることがわかります。

R1がNHKラジオ第一,R2がラジオ第二,FMはNHK FMをそれぞれ示し,NHK仙台放送局のコールサインはJOHKなので,放送局の識別子としてhkを使っているようです。ちなみに名古屋はck,大阪はbkになっています。

とりあえず配信元の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)の中で指定されているようです。こんなのよく調べたなぁ…,と感心しつつ,この指定を流用させてもらうことにしました。

最近,改めて確認したところ,JavaScriptの名称は"common2015.js"に変更されており,プレイヤーも"rtmpe_ver2015.swf"に変更されていました。もっとも"rtmpe.swf"の指定でもダウンロードはできるので,両者に互換性は持たせてあるようです。

さて,上記のような指定でダウンロードできることがわかれば,後は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 < /dev/null')
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ファイルに変換しているわけです。

Adobe Flashファイルの音声データはMPEG-4 Audioと同じHE-AAC(High-Efficiency Advanced Audio Codec)形式で記録されているので,ffmpegを使った変換の際も-acodec copyを指定して音声データのCODECはそのまま,データの格納形式のみAdobe Flash(.flv)からMP4(.m4a)に変換しています。

著者プロフィール

こじまみつひろ

Plamo Linuxとりまとめ役。もともとは人類学的にハッカー文化を研究しようとしていたものの,いつの間にかミイラ取りがミイラになってOSSの世界にどっぷりと漬かってしまいました。最近は田舎に隠棲して半農半自営な生活をしながらソフトウェアと戯れています。

URLhttp://www.linet.gr.jp/~kojima/Plamo/index.html

コメント

コメントの記入