翻訳: 英語/English, 韓国語/한국어 🇰🇷

翻訳: tgfjt

hypervision を使った P2P ストリーム配信

ストリーム配信は本当に楽しいものです。今や主流のSNSにはストリーミング配信がほぼあり、写真を共有するのと同じくらい簡単に自分のカメラを使って放送することが出来ます。

一度に何千人もの視聴者に音声と映像を届けるには多くの帯域を必要とします。仮に100人の視聴者にある程度までの品質でビデオストリームを送信するサーバーを起動する必要があるとなると、恐らく毎時40〜50GBのデータを送信することになるでしょう。またこういった類のデータ転送には大量のスループットを扱うことのできる接続が必要となり、一般的なインターネット接続では対応できません。

YouTube や Facebook を使っての放送は比較的簡単ですが、私としては未来の分散型インターネットがどういったものなのかについてのほうがはるかにワクワクします。もし私達が P2P 技術を使って配信することが出来れば、制限のあるソーシャルネットワークではなくオープンでアクセシブルかつ検閲フリーなものに簡単に乗り換えることができます。

週末のプロジェクトとして、私は hypervision のソースコードにダイブすることに決めました。hypervision は「P2P テレビ」とシンプルに題された実験的なコードベースです。私はそれが何をしているのか理解し、そこから何らかのコントリビュートしてみようと思いました。

hypervision とは?

hypervision は P2P ライブストリームの視聴と配信、両方を可能にするデスクトップアプリケーションです。何人かのユーザーがストリームに接続すると、ユーザー間でデータを受信・配信します。。そのため中央サーバーも、すべてのユーザーに同じデータを送信するための膨大な帯域幅も不要になります。

hypervisionDat プロジェクト の開発者である Mathias Buus によって始められました。 多くの hypervision の技術は Dat プロジェクトの基盤と同様のものに依存しています。

hypervision のキャプチャ画像

どんなふうに動くのか?

hypervision はいくつかの JavaScript モジュール上に構築されています。なかでも最も興味を引くモジュールが、hypercorehyperdiscovery です。

hypercore は一種のデータストレージで他のコンピューターに簡単に再配布可能となっています。その意図としては、大きなデータセットやリアルタイムデータのストリームを簡単にシェアすることです。

hyperdiscovery は、hypercore のフィードを他のユーザーが見つけられるようにします。フィードが渡されると、hyperdiscovery は同じデータを求めている他のユーザーを検索します。これは BitTorrent のユーザーが他のピアに接続する方法に酷似した方法です。

hypervision で視聴するキャプチャ画像

放送を開始する前に、hypervision はユーザーのコンピュータに付属されたメディアデバイス(カメラやマイク)へと接続します。hypervisionElectron で書かれており、Electron は Chrome 上に構築されたデスクトップアプリケーション作成用フレームワーク ですので、デバイスにアクセスするときは getUserMedia() API を使うことが出来ます。

var recorder = require('media-recorder-stream')
 var cluster = require('webm-cluster-stream')

 navigator.webkitGetUserMedia({
   audio: true,
   video: true
 }, function (media) {
   var stream = recorder(media, { interval: 1000 }).pipe(cluster())
 })

デバイスのどれかひとつを初期化すると、返り値としてメディアストリームを受け取ります。さらにいくつかのステップの後、このデータは最終的に .webm 形式のビデオバッファコレクションとなり、小さな断片に分割されます。

カメラやマイクから新しいデータを受信した場合は、これを小さなバッファとして hypercore フィードに追加します。

var hypercore = require('hypercore')
 var level = require('level')
 var swarm = require('hyperdiscovery')

 var core = hypercore(level('producer.db'))
 var feed = core.createFeed({
   storage: raf('producer.data/' + Date.now() + '.feed')
 })

 swarm(feed)

この時点で既にフィードは hyperdiscovery に渡されており、以後リアルタイムなデータは他のユーザーから利用可能になります。そしてユーザーたちのこの "群れ" は他のユーザーが求めるどのようなバッファも共有します。

hypercore を利用して新しいフィードを作成すると、そのストリームに接続したがっている他のユーザーとの共有キーが返されます。このキーは P2P ネットワーク上でブロードキャストを認識するための識別子です。

var key = feed.key.toString('hex')
          

視聴者としてキーを入力すると、求めているストリームデータを共有出来るユーザーを探しに行きます。このプロセスは hyperdiscovery 側でも実施されます。データの受信を開始すると、各バッファを新たな hypercore フィードに追加していきます。

var core = hypercore(level('viewer.db'))
 var feed = core.createFeed(key, {
   sparse: true,
   storage: raf('viewer.data/' + key + '.feed')
 })

画面上で、<video> 要素に対し、 hypervision によって作成された .webm ビデオの視聴を開始を指示します。この時点で既にその配信に参加しており、同時に同じ配信を他の視聴者に提供していることになります。

hypervision にコントリビュート

この記事を書く前、hypervision は基本的にユーザーインターフェースのないアプリケーションでした。ソースコードを掘り下げてどのように動作するのかを理解し、私はシンプルな UI を作り、初めてのユーザーにとってナビゲーションを分かりやすくしました。それからデバイスのプレビュー、ビットレート選択、そして放送するひとが ウェブカメラとスクリーン共有を切り替えられるように機能を追加しました。

私はこれらを全て含んだ PRhypervision に出しています。マージされるまでの間は、louiscenter/hypervision をクローンして、README の手順に従ってビルドすれば、新しい UI を試すことができます。

更新: この PR はマージされました。hypervisionGitHub リポジトリ に行って、README.md の指示に従い新しい UI を試すことが出来ます。

hypervision の次は?

hypervision はオープンソースの JavaScript プロジェクトのため、Node.jsブラウザ のソースコードを書くのが楽しいひとであれば誰でも簡単に新しい機能の作成に取り掛かることが出来ます。

私がしたいことの1つは、ユーザーのファイルシステムに hypercore のフィードを読み書きする際の hypervision の依存を取り除き、WebRTC を利用してデータを集めるようにすることです。こうすれば、デスクトップアプリケーションをダウンロードしなくても、ユーザーがブラウザで Web サイトを訪問するだけで、P2P ライブストリーミングを視聴することが出来るようになります。

ブラウザで P2P ライブストリーミングを簡単にアクセスしたり利用出来るようにすることで、他の集中型ストリーミングプラットフォームに代わる実用的な手段となります。

もっと読む