放送大学のインターネット配信授業をダウンロードする

この記事は放送大学 Advent Calendar 2018の1日目の記事です。

放送大学のインターネット配信は従来は動画・音声ファイルをダウンロードするものでしたが、最近になって刷新されてなぜかこの御時世にFlashを採用してrtmpによるストリーミング配信に移行しました。

ionicで実装されており、スマートフォンアプリもリリースなどもしており、それなりに情熱も感じさせてくれるのですが、使い心地は正直なところイマイチで、以前のように素直にダウンロードさせてくれたほうが嬉しい場面もあります。

というわけでrtmpdumpとffmpegを使って配信授業をdumpしてみます。(もちろん、ログインが必要なので放送大学に在籍する学生か教職員しかできません。)

まずは必要なものをインストールします。

$ brew install rtmpdump
$ brew install ffmpeg

放送大学の配信授業のページをdev toolsで見てみるとhttps://vod.ouj.ac.jp/v1/tenants/1/vod-contents/{動画ID}/video-src?hls=falseにストリーミングのURLが記載されています。(動画IDは各チャプターのURLの?co=動画IDの数字です)


{
   "timestamp": タイムスタンプ,
     "isWatermark": false,
     "x1_0VideoSource": {
       "videoSrc": "rtmpe://vod-st.ouj.ac.jp:80/classtream?authTicket={トークン}&mp4:1/{動画ID}.mp4",
       "videoType": "rtmp/mp4",
       "abrVideoType": "rtmp/mp4",
       "duration": 2700
       },
     "x2_0VideoSource": {
       "videoType": "rtmp/mp4",
       "abrVideoType": "rtmp/mp4"
     },
     "x1_5VideoSource": {
       "videoSrc": "rtmpe://vod-st.ouj.ac.jp:80/classtream?authTicket={トークン}&mp4:1/{動画ID}_1-5.mp4",
       "videoType": "rtmp/mp4",
       "abrVideoType": "rtmp/mp4",
       "duration": 1936
     },
     "existsSamiFile": false,
     "userId": "学籍番号"
 }

動画の再生速度ごとの動画ソースのほか、字幕の有無はexistsSamiFileで判定できそうです。videoSrcauthTicketはログインしたユーザーが動画ページをリクエストするたびに発行されるものです。

ちなみに?hls=falseクエリを外すとHLSのソースが表示されますが、WebからだとauthTicketがないのでiOSにユーザーエージェントを偽装するとHLSでも取得できるんじゃないかなと思います。(まだ試してない)

dumpするには動画プレイヤーが必要ですが、これはhttps://vod.ouj.ac.jp/classtream-player/v1.2/js/video-js/5.12.6/video-js.swfのようです。

ではダウンロードしてみます。

$ rtmpdump -r "rtmpe://vod-st.ouj.ac.jp:80/classtream?authTicket={トークン}&mp4:1/{動画ID}.mp4" \
-s "https://vod.ouj.ac.jp/classtream-player/v1.2/js/video-js/5.12.6/video-js.swf" \
-y "mp4:1/{動画ID}.mp4" \
| ffmpeg -i pipe:0 -c copy 'output.mp4'

上のようにplaypathを指定しないとうまく切り出せないようです。(参考: 【DL】動画の保存方法総合スレ【保存】part30 – 2ちゃんねる勢い速報まとめ [板:YouTube スレ:1486301431 レス:668] 

rtmpdumpで出力したものはそのままでは再生できないのでffmpegに渡して出力しています。(参考: rtmpdumpとffmpegをつかったライブトランスコーディング – 別館 子子子子子子(ねこのここねこ)はてブロ部)

色々表示やメタデータが表示されてダウンロードが完了します。完了した動画のメタデータを表示してみます。

$ ffmpeg -i output.mp4
# 中略
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.20.100
  Duration: 00:45:03.24, start: 0.000000, bitrate: 454 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, smpte170m), 640x480 [SAR 1:1 DAR 4:3], 350 kb/s, 30 fps, 30 tbr, 16k tbn, 60 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 93 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
At least one output file must be specified

動画を再生してみます。

再生できました。

あとはiCloudにぶちこんでiPadで再生するなり、音声データをCloud Speech APIに投げて文字起こししたりして学習が捗りそうです。

ここから字幕を変換して合成したり、内部APIを叩いたり、ダウンロードを大体自動化するNode.js製のCLIを作っていたりするのですが、Advent Calendarネタで空いてる日に適当に書こうと思います。

明日は@weblog_techさんです。