peercast.in
2012 · 🪦 retired
PeerCast は 2002年生まれの P2P 映像配信ソフト。専用クライアントを入れてポートを開放しないと視聴できない、敷居の高さごと愛されてきた配信文化圏だった。peercast.in は 2012年に作った、その PeerCast の配信をブラウザだけでサムネイル一覧・検索・視聴できるようにするサイト。「インストールしないと何をやっているかすら見えない」せいで失われているリスナーを取り戻し、PeerCast の間口を広げるのが狙いだった。
実装は nginx reverse proxy + Sinatra + 自作のしたらば掲示板クローラー。配信ごとのコメントをリアルタイム表示する「Peercast Stream」機能は Server-Sent Events(サーバーから一方向にデータを流し続ける仕組み)で作っていた(詳しくは後述の内部の仕組み)。
どんな画面だったか
サイトの実物は残っていないが、公開10日目(2012年3月15日)のトップページの HTML が Wayback Machine に丸ごと残っていた。そこから当時の画面を再現したのがこれ:

トップページは配信中チャンネルをリスナー数順に並べたリアルタイムランキングで、各行にサムネイル・配信時間・「再生する」リンク・掲示板リンクが付く。配信中チャンネルの全文検索と過去の全データからの検索、AutoPagerize 対応もあった(2012年3月13日)。ランキングは最高リスナー数・平均リスナー数・配信時間の3種類で、「客観的な指標をもとに新たな配信者さんを見つけることができる」ことを狙っていた(2012年3月15日)。
サムネイルは10分おきに全配信から取得していて、配信ごとの「サムネ一覧」ページで時系列に眺められた。ノンストップで蜘蛛の生活を流し続ける配信(当時すでに100時間超)をこのサムネ一覧で紹介した日記も残っている(2012年3月12日)。
このスクリーンショットの2日後(2012年3月17日)には、配信中の番組をスクリーンショットのタイルで一覧できる「Now!」ページが追加された。「アクセスするごとにランダムに並び変わるので、人間が左上から順番に見てしまうという行動パターンへの対策もバッチリできています」(当時の日記)。その後もサイドバー・最新レス表示・配信者一覧・取得先 YP(配信一覧を持つ元サイト)の追加と、ほぼ日次のペースで機能が増えていった(2012年3月20日〜26日)。
内部の仕組み
当時のソースコードが手元に残っていた。それと日記を突き合わせると、内部構成はこうなっていた:
- スタックは nginx + Sinatra(Ruby)+ MySQL。実は Sinatra アプリは2つに分かれていて、peercast.in 本体がランキング・検索・サムネ一覧・Now! を、別アプリの Peercast Stream がコメントのリアルタイム配信を受け持っていた
- サムネイルのキャプチャは、サーバー上で常駐させた PeerCast クライアント(
localhost:7144)経由で各配信に接続し、ffmpeg で「先頭8秒地点」の1フレームを切り出して、RMagick で縮小・黒背景に合成して軽くぼかす、という流れ。最初の8秒はバッファで映像が乱れがちだったのを避ける工夫で(2012年3月5日)、これを10分ごとに全配信ぶん回していた。並列化には parallel gem、失敗時のリトライには自作の retry-handler を使っている - YP の index.txt(
<>区切りのチャンネル一覧)は、複数の YP を結合してから NG キーワードで配信を除外し、1つのファイルに書き出していた(yp_merger)。パーサは自作ライブラリ集 orelib にあり、のちに自作の csvmapper で書き直す記事も書いた(2012年8月1日)。YP のクロール自体は本体とは別のサーバーで回していた(2012年3月23日) - ランキング(最高リスナー数・平均リスナー数など)は MySQL のビューとして持っていた
- 8,000 req/sec は nginx のキャッシュチューニングによるもの(2012年3月8日)。動画そのものは配信していない(再生リンクは視聴者手元の PeerCast クライアント
localhost:7144に向く)ので、捌くのは HTML とサムネイル画像だけでよかった - Peercast Stream の SSE は Sinatra の
stream :keep_open、nginx 側はproxy_buffering offで流していた(2012年4月20日)
クライアント側のパッチ
そのキャプチャの土台になっていたのが、公開の2週間前(2012年2月21日)に用意した Linux 用 PeerCast クライアントの fork だ。ベースは「PeerCast for Linux(VP パッチ版)」で、README には “VP patch + fixed compile bug” とだけ書いてある。けれど実際に足していた本命は、サーバーで無人常駐させるための自動再起動だった。PeerCast 本体を fork() した子プロセスで動かし、親が waitpid() で見張って、子が落ちたらまた起動しなおす——というスーパーバイザを main.cpp に加えている。10分おきに何日も動き続けるキャプチャ基盤の裏で、クライアントが落ちても勝手に生き返るようにするための改造で、コンパイルを通すための細かい修正(sys/wait.h の include など)も一緒に入っていた。
反響
2012年3月5日に公開すると、すぐに PeerCast コミュニティで話題になった。アクセスは公開直後から多く、3日後にはキャッシュチューニングを施して 8,000 req/sec を捌ける構成にしている(2012年3月8日、「キャッシュ設定楽しすぎてニヤニヤしながら仕事してしまうんだが〜〜」)。
相手にしていたコミュニティの規模も記録がある。サイトに「PeerCast 総人口」(配信者数+全リスナー数)を表示する機能を付けたところ、夜間はアクティブ3,500人。「キャッシュではなく3500人が PC の前に座り動画を視聴しているということを表してる!」(2012年3月15日)
平日の昼間、職場から Google Analytics のリアルタイム画面を「蟻の群れを見ているかのような感覚」で眺めていたという日記もある(2012年3月14日)。2012年5月には「peercast.in を再設計させてくれと海外の人からメールが来ていた」という題の日記も残っている。
プライバシーとの衝突
PeerCast はツリー型 P2P で、仕組み上配信者の IP アドレスがオープンになる。クライアントを入れる手間が参入障壁として機能していた世界を、ブラウザで誰でも覗けるようにすることは、配信者の望まない露出を生みうる——公開直後にコミュニティから噴出したのは、まさにその懸念だった。
対応は即日だった。2012年3月26日、「@Peercast 関係者各位」と題して既存サービス(MultiYP)と同じ NG キーワードでのクロール除外を表明し、同日中にいったん全クロールを停止。翌27日には収集した全データを削除した。このときの総括には「あくまでもプロトタイプとして技術的な実験としてやってみた」「(クローラーの)PeerCast ネットワークへの負荷は問題ないことがわかった」「既存 YP から配信者を奪うような形態はやりたくない」と書いている。
その後は、配信者本人が掲載を拒否できる情報拒絶機能などの対策を実装した上での再公開を目指した。当時の日記より:
俺はpeercastが好きだから、配信者の個人情報が暴露されてしまうようなシステムにしたくなくて、その対策を今実装してるみたいな感じです。
停止
最終的にサービスを止めた直接の理由は、YP(Yellow Page: PeerCast の配信一覧を持つ既存サイト)の運用者がクロール拒否を宣言したことだった。情報検索サービスの複製を適法とする著作権法47条の6は「権利者が収集拒否を明示した場合はしない」ことを要件にしており、拒否宣言後も続ければこの要件を満たせなくなる。詳しくは当時の wiki の法的整理(法律/著作権関連/Peercast.in)に書いた通りで、「だからこそサービスを全停止させた」。
翌2013年の日記には、こう書いている:
peercast.inは失敗に終わったけど、あれを通じて知り合いができたことが大きな利益になってる。何も無駄ではなかった。