響 HiBiki Radio Station をaacで録音する

2015/11/10追記

響がリニューアルしたんでこの記事の情報は全く役に立たなくなりました。 新しい仕様についての説明、コードはこちら↓

vector.hateblo.jp

検索用キーワード: Mac, Linux, rtmp, rtmpdump, rtmpe, 保存

まえがき

響で再エンコードなしでaacを取得する方法がわかったんでメモ。

ググるwmaやm3u8で取得する方法は見つかるんだが、wmaだとiOSとかで再生できないし、再エンコードは気分が悪い。m3u8 (HTTP Live Streaming)はなんかファイルがすごい分割されていてパッとググってもffmpegとかでいい感じにmp4などに復元する方法が見つからなかったので遠慮したさがあった。

コード

雑なコードとしては下の2ファイルを見て欲しい

https://github.com/yayugu/net-radio-archive/blob/18d9097df6266f8ece9e026b1414768eb82e26d8/lib/hibiki/scraping.rb

https://github.com/yayugu/net-radio-archive/blob/18d9097df6266f8ece9e026b1414768eb82e26d8/lib/hibiki/downloading.rb

手順

http://hibiki-radio.jp/get_program/$(WEEKDAY)

にアクセスすると曜日ごとの番組情報が取得できる。$WEEKDAYは数字で1-6がそれぞれ月〜金と土日に対応している。

Aタグのonclickが onclick="AttachVideo('garo','1637','1','0')" みたいになっているのでこの関数の1つめと2つめを取り出す。

m = /AttachVideo\('(.+?)','(.+?)','.+?','.+?'\)/.match(onclick_text)
short_name = m[1]
channel_id = m[2]

その情報からURLを生成してアクセスする。

      uri = URI.parse("http://image.hibiki-radio.jp/uploads/data/channel/#{base.short_name}/#{base.channel_id}.xml")

      res = Net::HTTP.get_response(uri)
      unless res.is_a?(Net::HTTPSuccess)
        return nil
      end

      dom = Nokogiri::HTML.parse(res.body)

      protocol = dom.css('protocol').text
      domain = dom.css('domain').text
      dir = dom.css('dir').text
      flv = dom.css('flv').text
      if protocol.blank? || domain.blank? || dir.blank? || flv.blank?
        return nil
      end
      m = /^.+?\:(.+)$/.match(flv)
      filename_query = m[1]
      rtmp_url = "#{protocol}://#{domain}/#{dir}/#{filename_query}"

xmlのような雰囲気のものが取り出せる。404だったり、情報が空のこともある。その場合はその番組はおそらく配信していない。 無事取得できて、以下のようになってたら成功。この情報を組み立てるとrtmpのurlができる。

<data>
        <protocol>rtmpe</protocol>
        <domain>cp209391.edgefcs.net</domain>
        <dir>ondemand</dir>
        <channel type="main">
                <flv>mp4:150101_lovelive_ms_150101_lovelive_ms.mp4?di=910&si=609&pi=2806&gi=6494&gc=3&bi=34236&bc=lovelive_ms&ei=921385&ec=150101_lovelive_ms&vi=4989926&vc=150101_lovelive_ms&msi=516&mc=&ni=1625</flv>
                <thumbnail>http://image.hibiki-radio.jp/uploads/radio_program/flash_image/c7562a9a9a67e099402d472585bcdc5068da0d24.jpg</thumbnail>
        </channel>
</data>

組み立てたurlをrtmpdumpに渡す

`rtmpdump -q -r #{Shellwords.escape(rtmp_url)} -o #{Shellwords.escape(flv_path)}`

うまくいっていればflvファイルがあるはずである。中身はh264の映像とaacの音声である。h264の映像はダミーであるため、ffmpeg(or avconv)でaacだけを取り出す。

`avconv -loglevel error -y -i #{Shellwords.escape(flv_path)} -acodec copy #{Shellwords.escape(aac_path)}`

あとがき

ちなみにrtmpもhls(HTTP Live Streaming)もデータを転送するための方法であり、中身は大抵の場合h264とaacである。 なのでどちらでもmp4が取り出せるはず(方法は知らないけど)

VMで開発してるんだけど IntelliJ / PHPStorm とかを使いたい

xxxa: dockerコンテナ側のディレクトリをローカルmacにマウントしたいんだけど 
xxxa: -v, --volume=[] Bind mount a volume (e.g., from the host: -v /host:/container, from Docker: -v /container) 
xxxa: -v /container してもローカルmacに表われないんですけどどうしたらいんですか 
xxxb: boot2docker? 
xxxa: はい
yayugu: 多分出来ない 
xxxa: そうなんですね 
yayugu: boot2dockerに多くを期待してはいけません 
xxxa: intelliJ使いたいんだけどなあ・・・
yayugu: っsshfs 
yayugu: sshfsクソ遅いということは知りながら書いてる 
yayugu: この辺についてはおおいに問題なんですけど 
yayugu: まあ現実解としては4つくらいしかないくて 
yayugu: 1. Linuxをマシン直で使う 
yayugu: 2. sshfsで転送遅いのを我慢する 
yayugu: 3. ローカルにgit置いてIntelliJの機能(SFTP)でlinuxマシンに転送する。ラグいのは我慢する。PHPUnitなどの連携がクソるのも我慢する 
yayugu: 4. Macで動くようにする 
xxxc: 3がオススメだ 
yayugu: 1ができると最高なんだが、俺はムリです。X window systemキツイ
xxxc: 無理して1にする必要も感じないな。開発用のライブラリとか突っ込んでいくとサーバーと同じ環境じゃなくなっていく。 
xxxa: 1、江添さんっぽい 
xxxc: 1でやったとしても VM 立てたくなる。 
xxxb: というかローカル開発じゃなくてローカルVM開発がもう基本なのか。4だと思ってた 
xxxc: ほら、ローカルにいろいろインストールしたくないじゃない。 
xxxb: はい
xxxc: プロジェクトごとにまっさらな環境でやりたいじゃない。 
xxxb: はい
yayugu:  1でdocker使うとVM立てなくてもxxxaが最初にやろうとしてたことできるよ

RailsでStrutsの再発明

真面目な話mixinだと複数の実装を依存関係なく共有できるので、実装の共有を継承ツリーでしか表現できなかったJavaStrutsより便利だと思う。

ユーザー認証の手抜き

Webアプリ作っているといろんな局面でユーザー認証が必要になる局面がある。まじめにつくると果てしなく面倒だし、適当につくるとセキュリティ上問題になるので、要件に応じて適切に手抜きする必要がある。

適当なやつからしっかりしたやつまでなんとなくソートしていくとこんなかんじだと思う。

  • 認証なし
  • IPで弾く
  • Basic認証ソースコード、設定ファイルにパスワードベタ書き)
  • Basic認証(DBにUserテーブルをつくってパスワードを保存。追加はcliとかで手動)
  • login/logout画面作成。cookieなりmemcacheなりにセッションを保存
  • webからユーザーを追加できるように
  • password変更機能
  • OAuth
  • OpenID
  • mailを送ってリンクをクリックさせてメールアドレスの所有確認
  • メールアドレス変更機能
  • メールを使ってのパスワードリセット機能
  • OAuthで作ったアプリへの後からのメールアドレスとパスワード追加登録機能
  • 二段階認証

不特定多数のユーザーが登録する場合に開発として楽なのはid/password方式。
メールアドレス認証とかがない純粋なidだとすごい楽です。
こういうときOAuth選びがちだけど意外と使い勝手悪い。

OAuth使うと発生する問題

  • ライブラリの依存とか諸々ではまりやすい
  • OAuth provider (TwitterとかFBとかギッハブとか)に依存することになる
  • 複数のOAuth providerに対応すると1人のユーザーが複数アカウント重複してしまう可能性がでてきてめんどくさくなる
  • Native Appつくるときに認証でWebView開いて(myapp(web) -> Twitter -> myapp(web) -> myapp(native))みたいなcallbackの嵐をやるハメになる
  • Native Appのバイナリ内にサーバー側と同じConsumer Key/Consumer Secretを持つとセキュリティ上問題があるのでNativeでは持たないようにするなり、別のConsumer Keyを持つなりしないといけない
  • 更にマジメな話をするとアプリ内WebViewで外部サービスのパスワード入力させて認証させるのはfishingのおそれがあるのでアドレスバーが信頼できる外部ブラウザアプリに飛ばして認証させたほうが良い

追記

OAuthは認可であって認証ではないうんぬんの話は承知しておりますが現実としてその辺に詳しくないエンジニアの皆様は「Twitterで認証」とおっしゃられてますし、TwitterにOAuthで認可を得てverify_credential.jsonを叩いた結果からuser_idを取得するとそれは認証として問題なく使えてしまうという現実もあります(余計な権限の認可もついていますが、そっちもなんだかんだで使うし)。OAuth単独だと認証機能がないというのは事実なんですが一般的に言うOAuthとは要するにTwitterでありFacebookでありそれらのAPIと組み合わせることで認証機能を得ることができるし、IDな人たちが大好きなOpenIDの最新規格であるOpenID ConnectだってOAuthでaccess_token取得するついでにIdentityもついてくるというTwitter APIのverify_credentialを呼ぶ手間が省けて共通規格にしましたみたいなもんだし、日曜深夜にこんな長文書くハメになるのでOAuthがどうとか認証とか認可とかの議論やめたい。

TwitterのRSSを生成する Twitter Great RSS をつくった

つくりました。
Twitter Great RSS

  • 1人のユーザーのツイート一覧
  • list
  • 検索結果 (←NEW!)

RSS化できます。
検索にも新たに対応しました。エゴサーチが捗りますね!


以前つくっていたもの(Twitter Good RSS)が、一部壊れているようで新規登録ができないとの連絡を受けていたんんですが、以前のやつは今見るとDB周りが色々絶望的で直したくなかったので新しいものを作りなおしました。

機能的にも上位互換なので今後はこちらをお使いください


Twitter Great RSS


GitHub

neovimで新しくなったところまとめ

neovimは「vimを近代化させよう」というvimのforkです。

https://github.com/neovim/neovim
http://news.mynavi.jp/news/2014/02/26/097/

なかなかかっこいいので、現状どのような改修が行われたのかcommitを追いかけてみました

TL;DR

  • 開発始まったばっかりなので総Commit数まだ少ない
  • CMake使うようにした
  • ゴミ掃除とサポートしたくない環境の切り捨てをした
  • 実用段階になるには少なくとも半年以上はかかりそう

詳しく


Import vim from changeset v5628:c9cad40b4181

  • ファーストコミット
  • いらなそうなファイルとかマクロとか消したらしい
  • Cmakeにビルドを移植したらしい
  • fork元との差分はなし。あんまり丁寧じゃないね


Fix build on OSX/Archlinux and add README

  • SELinux対応面倒なのでとりあえずコメントアウト
  • OSX/Archlinuxでビルドが壊れているのを修正
  • OSXでlibintl(gettextなどから使用される)を探すように&なんか色々ハックしてる
  • Archlinuxでリンク時に-ltermcapをつけても名前が見つからずリンクできないのでtermcapを包有しているcursesをリンクすることで(-llibcurses)回避

わりと雑なハックが行われている模様


Remove more #ifdef dead code

  • 古いマクロとかさまざまな環境に対応するためのコードとかをごっそり削除
  • Mac OS 9とかBorland C++ CompilerとかMSDOSとか
  • libuvの乗り換えるためかsys/poll.hとか使うのやめている
  • GUIは別プロセスにしてTCP接続する疎結合に切り替える予定のためかGUIまわりのコード(X11, GTK, ...)もごっそり削除


Automate libuv download and build

  • libuvを自動ダウンロード&ビルドするように……ってそれmakeでやることなの? aptなりyumなりbrewなりに任せるべきでは


Add libtool to OSX installs
Add Arch dependency instructions to README.md

  • それぞれOSXとArch Linuxでのインストール手順説明の修正
  • Arch Linux向けのcommit複数あってそれぞれ別の人がやっていて流行っている感じある


include a copy of the Vim License

  • うっかり忘れていたっぽい。雑っぽい


Cleanup refactoring in main
Clean up main.c:parse_command_name


Add travis-ci configuration

  • TravisCI導入


First pass on getting build working on FreeBSD.

  • FreeBSDでビルドできるように
  • みんな自分のOSに対応させるし使ってないOSはどうでもいいということがわかっておもしろい
  • バザール開発だ


README.md: fix ubuntu/debian deps

  • 「For Ubuntu 12.04」ってなんだよ、俺はdebian使ってるんだという心の声が聞こえる
  • build-essentialはubuntuにしかないんだよ。要するに必要なのはlibtool, autoconf, g++だという心の声が聞こえる

追記: debianにもbuild-essentialはあるらしい(thx KoshianX!)。今手元のsqueezeで確認したら確かにありました。build-essentailではlibtool, autoconfは入らないようなのでそこを直したと思われる


Added 'neovim' to the feature list, following discussion on #44

  • VimLからhas("neovim")でneovimがどうか判定できるように


scripts/common.sh: remove a couple bashisms


追記:bashでしか動かないバグをbashismsというらしい(thx KoshianX!)。

シェルスクリプト詳しくないので精進します


Adding neovim formula for Homebrew
Updating README file to use Homebrew for local builds

  • Homebrewのfomula書いたぜ
> brew install neovim/neovim/neovim

でneovimが入る便利ライフに

コーディング規約とかガイドとかって難しいよねという話

注:細かくてどうでもいい話です

Cookpadの規約スタイルガイドについての話
https://github.com/cookpad/styleguide

[SHOULD] ハッシュのキーを Symbol にして良い場合は、文字列よりも高速に lookup できるので積極的に Symbol を使うこと。

ここの箇所、言いたいことは分かるんですがちょっと誤解を招くなと思った
具体的には

  • 「可読性と一貫性」*1を目的にしているならパフォーマンスの話をするのはおかしい
  • ハッシュのlookup速度が問題になるケースはかなり少ないので、一般的な状況ではキーをSymbolにすることにパフォーマンス上の優位点はない
  • SymbolはGCされないので新しいSymbolがガンガン作られる状況(ex. ユーザからの入力を.to_symする, 巨大な文字列の集合を.to_symしたものでハッシュをつくるなど)ではメモリリーク*2が発生する。

という問題があると感じた。

で、r7kamuraさんに聞いてみたところ
いくつか勘違いしていたことに気づいた

  • ガイドなので規約ではなく必ず守らなければならないものではないらしい*3
  • ずっとリテラルの話をしていてのこの節なのでインスタンスではなくリテラルの話だとわかるはず(つまり空気読めていなかった)

こうしたらいいんじゃないかなという解決策

↑のようなことを丁寧に書くとクソ長くなってしまうのでもっと率直な理由にすればいいのでは

[SHOULD] ハッシュのキーを Symbol にして良い場合は、タイプしやすいしかっこいいので積極的に Symbol を使うこと。

*1:https://github.com/cookpad/styleguide/blob/master/ruby.ja.md#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB

*2:これを厳密な意味でのメモリリークというかは知りません

*3:じゃあmustとか書かないほうがいいのでは