<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>PeerCast on kimoto</title><link>https://new.kymt.me/tags/peercast/</link><description>Recent content in PeerCast on kimoto</description><generator>Hugo</generator><language>ja</language><atom:link href="https://new.kymt.me/tags/peercast/index.xml" rel="self" type="application/rss+xml"/><item><title>peercast.in</title><link>https://new.kymt.me/story/peercast-in/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://new.kymt.me/story/peercast-in/</guid><description>&lt;p&gt;PeerCast は 2002年生まれの P2P 映像配信ソフト。専用クライアントを入れてポートを開放しないと視聴できない、敷居の高さごと愛されてきた配信文化圏だった。&lt;strong&gt;peercast.in&lt;/strong&gt; は 2012年に作った、その PeerCast の配信をブラウザだけでサムネイル一覧・検索・視聴できるようにするサイト。「インストールしないと何をやっているかすら見えない」せいで失われているリスナーを取り戻し、PeerCast の間口を広げるのが狙いだった。&lt;/p&gt;
&lt;p&gt;実装は nginx reverse proxy + Sinatra + 自作のしたらば掲示板クローラー。配信ごとのコメントをリアルタイム表示する「Peercast Stream」機能は Server-Sent Events(サーバーから一方向にデータを流し続ける仕組み)で作っていた(詳しくは後述の&lt;a href="https://new.kymt.me/story/peercast-in/#%e5%86%85%e9%83%a8%e3%81%ae%e4%bb%95%e7%b5%84%e3%81%bf"&gt;内部の仕組み&lt;/a&gt;)。&lt;/p&gt;
&lt;h2 id="どんな画面だったか"&gt;どんな画面だったか&lt;/h2&gt;
&lt;p&gt;サイトの実物は残っていないが、公開10日目(2012年3月15日)のトップページの HTML が Wayback Machine に丸ごと残っていた。そこから当時の画面を再現したのがこれ:&lt;/p&gt;
&lt;figure class="map-thumb"&gt;
 &lt;img src="https://new.kymt.me/images/story/peercast-in-top-20120315-recon.png" alt="peercast.in トップページの再現スクリーンショット。黒いナビゲーションバーの下にサイト説明と検索フォーム、リスナー数順の配信一覧テーブルが並ぶ" width="1280" height="1000"&gt;
 &lt;figcaption&gt;2012年3月15日のトップページの再現。アーカイブされていた当時の HTML に同時期の Twitter Bootstrap 2.0 を当てたもので、配信者名はぼかし、未アーカイブのサムネイル画像はプレースホルダにしてある。「現在のPeercast総人口は、1220人です」「現在41件 配信中」も当時の実データ&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;トップページは配信中チャンネルをリスナー数順に並べたリアルタイムランキングで、各行にサムネイル・配信時間・「再生する」リンク・掲示板リンクが付く。配信中チャンネルの全文検索と過去の全データからの検索、AutoPagerize 対応もあった(2012年3月13日)。ランキングは最高リスナー数・平均リスナー数・配信時間の3種類で、「客観的な指標をもとに新たな配信者さんを見つけることができる」ことを狙っていた(2012年3月15日)。&lt;/p&gt;
&lt;p&gt;サムネイルは10分おきに全配信から取得していて、配信ごとの「サムネ一覧」ページで時系列に眺められた。ノンストップで蜘蛛の生活を流し続ける配信(当時すでに100時間超)をこのサムネ一覧で紹介した日記も残っている(2012年3月12日)。&lt;/p&gt;
&lt;p&gt;このスクリーンショットの2日後(2012年3月17日)には、配信中の番組をスクリーンショットのタイルで一覧できる「Now!」ページが追加された。「アクセスするごとにランダムに並び変わるので、人間が左上から順番に見てしまうという行動パターンへの対策もバッチリできています」(当時の日記)。その後もサイドバー・最新レス表示・配信者一覧・取得先 YP(配信一覧を持つ元サイト)の追加と、ほぼ日次のペースで機能が増えていった(2012年3月20日〜26日)。&lt;/p&gt;
&lt;h2 id="内部の仕組み"&gt;内部の仕組み&lt;/h2&gt;
&lt;p&gt;当時のソースコードが手元に残っていた。それと日記を突き合わせると、内部構成はこうなっていた:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://new.kymt.me/story/peercast-in/architecture.svg" alt="peercast.in のシステム構成図(当時のソースコードと日記から作成)"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;スタック&lt;/strong&gt;は nginx + Sinatra(Ruby)+ MySQL。実は Sinatra アプリは2つに分かれていて、&lt;strong&gt;peercast.in&lt;/strong&gt; 本体がランキング・検索・サムネ一覧・Now! を、別アプリの &lt;strong&gt;Peercast Stream&lt;/strong&gt; がコメントのリアルタイム配信を受け持っていた&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;サムネイルのキャプチャ&lt;/strong&gt;は、サーバー上で常駐させた PeerCast クライアント(&lt;code&gt;localhost:7144&lt;/code&gt;)経由で各配信に接続し、&lt;strong&gt;ffmpeg で「先頭8秒地点」の1フレーム&lt;/strong&gt;を切り出して、RMagick で縮小・黒背景に合成して軽くぼかす、という流れ。最初の8秒はバッファで映像が乱れがちだったのを避ける工夫で(2012年3月5日)、これを10分ごとに全配信ぶん回していた。並列化には parallel gem、失敗時のリトライには自作の &lt;a href="https://new.kymt.me/projects/retry-handler/"&gt;retry-handler&lt;/a&gt; を使っている&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;YP の index.txt&lt;/strong&gt;(&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; 区切りのチャンネル一覧)は、複数の YP を結合してから NG キーワードで配信を除外し、1つのファイルに書き出していた(&lt;code&gt;yp_merger&lt;/code&gt;)。パーサは自作ライブラリ集 orelib にあり、のちに自作の &lt;a href="https://github.com/kimoto/csvmapper"&gt;csvmapper&lt;/a&gt; で書き直す記事も書いた(2012年8月1日)。YP のクロール自体は本体とは別のサーバーで回していた(2012年3月23日)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ランキング&lt;/strong&gt;(最高リスナー数・平均リスナー数など)は MySQL のビューとして持っていた&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;8,000 req/sec&lt;/strong&gt; は nginx のキャッシュチューニングによるもの(2012年3月8日)。動画そのものは配信していない(再生リンクは視聴者手元の PeerCast クライアント &lt;code&gt;localhost:7144&lt;/code&gt; に向く)ので、捌くのは HTML とサムネイル画像だけでよかった&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Peercast Stream&lt;/strong&gt; の SSE は Sinatra の &lt;code&gt;stream :keep_open&lt;/code&gt;、nginx 側は &lt;code&gt;proxy_buffering off&lt;/code&gt; で流していた(2012年4月20日)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="クライアント側のパッチ"&gt;クライアント側のパッチ&lt;/h3&gt;
&lt;p&gt;そのキャプチャの土台になっていたのが、公開の2週間前(2012年2月21日)に用意した Linux 用 PeerCast クライアントの fork だ。ベースは「PeerCast for Linux(VP パッチ版)」で、README には &amp;ldquo;VP patch + fixed compile bug&amp;rdquo; とだけ書いてある。けれど実際に足していた本命は、&lt;strong&gt;サーバーで無人常駐させるための自動再起動&lt;/strong&gt;だった。PeerCast 本体を &lt;code&gt;fork()&lt;/code&gt; した子プロセスで動かし、親が &lt;code&gt;waitpid()&lt;/code&gt; で見張って、子が落ちたらまた起動しなおす——というスーパーバイザを &lt;code&gt;main.cpp&lt;/code&gt; に加えている。10分おきに何日も動き続けるキャプチャ基盤の裏で、クライアントが落ちても勝手に生き返るようにするための改造で、コンパイルを通すための細かい修正(&lt;code&gt;sys/wait.h&lt;/code&gt; の include など)も一緒に入っていた。&lt;/p&gt;</description></item><item><title>yp.kymt.me</title><link>https://new.kymt.me/projects/yp/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://new.kymt.me/projects/yp/</guid><description>&lt;p&gt;Twitch や Livetube などの配信サイトの番組一覧を、PeerCast 用クライアント(pcyplite や PecaRecorder)に登録できる Yellow Page 形式で配信するサービスです。5分間隔で更新。&lt;/p&gt;
&lt;p&gt;PeerCast のツールで、PeerCast 以外の配信サイトの番組もまとめてチェックできるようにする、という発想でした。&lt;/p&gt;
&lt;h2 id="リスト"&gt;リスト&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Twitch&lt;/strong&gt; — twitch.tv の番組一覧 YP(LoL, HoN, SC2 とか CS1.6、Mario64 の TA とか色々)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Own3d&lt;/strong&gt; — own3d.tv の番組一覧 YP(ほぼ LoL)※2013/01/31 でサービス終了した&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Livetube&lt;/strong&gt; — livetube.cc の番組一覧 YP(2021/05/02 に停止)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="変更履歴原文ママ"&gt;変更履歴(原文ママ)&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2021/05/02: Fix twitch cralwer and stop livetube YP
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2015/06/24: livetubeのcrawlに失敗していたので直した
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2014/10/06: /livetubeindex.txtってところへのアクセスが結構あるので対応してみた
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2014/06/20: 関連サイトのニコ生YPさんがDyndnsの問題で参照できなくなってたのでdeleteした(HTMLタグ的な意味で)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2013/02/03: own3d.tvがサービス終了したのでown3d.tvのYPは更新停止することに
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2012/11/17: Twitch.tvのサイト変更で動作しなくなっていたのをDeveloper JSON APIを利用するように変更してfix
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2012/07/12: livetube.ccサイト変更でうまく取得できてなかったのを修正
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2012/07/12: twitch.tvサイトリニューアルでうまく取得できてなかったのを修正
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2012/07/12: own3dサイトリニューアルでうまく取得できてなかったのを修正
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2011/未明: 公開
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;対象サイトのリニューアルのたびにクローラーを直し続けた、10年間の記録でもあります。&lt;/p&gt;
&lt;p&gt;→ &lt;a href="http://yp.kymt.me/"&gt;yp.kymt.me&lt;/a&gt;(当時のページがそのまま残っています)&lt;/p&gt;</description></item></channel></rss>