paint-brush
Amazon IVS、Muse ヘッドバンド、React を使用して脳をライブ ストリーミングする方法@amazonivs
4,671 測定値
4,671 測定値

Amazon IVS、Muse ヘッドバンド、React を使用して脳をライブ ストリーミングする方法

長すぎる; 読むには

React を使って脳のデータをライブ ストリーミングするのはこれが初めてです。 Amazon IVS Web Broadcast SDK を使用して、ライブの脳データをクラウドにブロードキャストします。この投稿では、SDK を利用するためのすべてのステップを検討するつもりはありません。代わりに、ハイライトを見て、それがどのように機能するかの一般的なアイデアを得る.最初のステップは、am-ivcast モジュールをインストールして、ブロードキャスト ツールを実行することです。broadcast-broadcast モジュールでは、お気に入りのパッケージにインポートする必要があります。ブロードキャスト ツールでは、別のステップを取得するための別のステップがあります。プロジェクトに。
featured image - Amazon IVS、Muse ヘッドバンド、React を使用して脳をライブ ストリーミングする方法
Amazon Interactive Video Service (IVS)  HackerNoon profile picture
0-item

今年の初め、私は「ブレイン」と名付けたとても楽しいプロジェクトを作成しました。
to the Cloud」でプレイ中に脳内データをクラウドに保存しました
Call of Duty の関係を分析できるように
認知機能とビデオゲームのパフォーマンス。三部構成で書きました
ブログ投稿シリーズといくつかの楽しいビデオを作成して、私の調査結果を要約します
そのプロジェクト。これらを確認したい場合は、
この投稿の下部にあるリンク。それを公開してから数ヶ月後
プロジェクトの開始後、私は Twitch でリード デベロッパー アドボケイトとして働き始めました。
Amazon Interactive Video Service (Amazon IVS) - フルマネージド ソリューション
ライブのインタラクティブなビデオ ストリーミング ソリューションを作成するためのものです (詳細については、このシリーズをご覧ください)。 「Brain to the Cloud」プロジェクトの次のステップは明らかでした。自分の脳をライブ ストリーミングする必要があったのです。

私の脳を放送する

コードを見る前に、最終製品を見てみましょう。 2つあります
アプリケーションのビュー: ブロードキャスト ビューと再生ビュー。の
ブロードキャスト ビューでは、ライブ ビデオをプレビューして、
ブロードキャストし、Muse ヘッドバンドを接続して脳データをストリーミングします
ヘッドバンドから入手。再生ビューでは、ライブを表示します
ストリーム

<video>
要素、脳データをリアルタイムでグラフ化

プロジェクト概要

このプロジェクトには 5 つのステップがあります。

  1. ライブ ストリームをブロードキャストする
  2. 脳のデータをキャプチャ
  3. ライブ ストリーム内で脳データを時限メタデータとして公開する
  4. ライブ ストリームの再生
  5. 時間指定されたメタデータをリッスンし、リアルタイムでグラフに脳データをレンダリングします

このようなものをグラフィカルに描写したい場合は、次のようになります。

プロジェクトのビルド

このプロジェクトには React を使用しました。なんで?まあ、経験は豊富だけど
Vue と Angular を使用していますが、私はおそらく最後の開発者の 1 人です。
React を試す地球。そろそろすべてを理解する時が来たと思いました
誇大宣伝があり、これが難しいことではないことはわかっていました
それを使って構築するプロジェクト。経験がないので、私はそうではありません。
フレームワークの「上級」ユーザーと呼ばれるものですが、私は言わなければなりません
私はこれまでに見たものにとても満足しています。プロセスを見つけた
楽しく、フレームワークと「戦っている」とは思いませんでした。しかし
このブログ投稿は、JavaScript フレームワークに関する私の意見ではありません。
将来の投稿のためにそれを保存します。代わりに、私がどのように放送するかについて話しましょう
私の脳!

ハードウェア

オリジナルの「Brain to the Cloud」プロジェクトでは、「ヴィンテージ」の EEG を使用しました
私の脳の測定値をキャプチャするための MindFlex と呼ばれるヘッドセット。割と効きました
まあ、ESP-12を追加してデバイスを「ハック」する必要がありました
デバイスから読み取り値を引き出して送信するためのマイクロコントローラ
それらをクラウドに。今回は少し新しいものに手を伸ばしました -
変更なしで使用できるもの。少ししてから
調査の結果、 Muse S ヘッドバンドに落ち着きました。ありがたいことに、 muse-jsと呼ばれる非常に優れたオープンソース ライブラリがあり、これを使用すると、Web Bluetooth を使用して Web ブラウザーで直接脳の測定値にアクセスできます (もちろん、サポートされているブラウザーで)。

ライブ ストリーム ブロードキャスト

最近まで、 Amazon IVS を使用したライブ ストリーミングでは、
RTMPS としてストリームをブロードキャストするためのサードパーティ クライアント。しかし、私たちは最近
はゲームチェンジャーを立ち上げました: Amazon IVS Web Broadcast SDK
名前が示すように、この SDK を使用すると、
Webブラウザから直接WebRTC経由でライブストリーミング。明らかに、これは
自分の脳をライブ ストリーミングするのにぴったりです。
私の脳のデータと一緒にブロードキャストするための「オールインワン」ソリューション
サードパーティのソフトウェアや外部スクリプトに依存しないライブ ストリーム。

React アプリに Web ブロードキャストを追加する

を利用するために必要なすべてのステップを検討するつもりはありません。
この投稿の Web ブロードキャスト SDK。代わりに、ハイライトを見て、
それがどのように機能するかについての一般的な考えを得る。心配しないでください - 別の投稿があります
を使用するための「段階的な」プロセスについて詳しく説明します。
Web ブロードキャスト SDK ですので、ご期待ください。そうは言っても、取りましょう
このプロジェクトで SDK をどのように使用したかを簡単に説明します。私の最初のステップ
をインストールするために Web ブロードキャストを使用することでした。

 amazon-ivs-web-broadcast
モジュール。お気に入りのパッケージ管理ツールを使用して、次を実行します。

 $ npm install amazon-ivs-web-broadcast

次に、それをコンポーネントにインポートする必要があります。 Broadcast.jsx コンポーネントに、以下を追加しました。

 import IVSBroadcastClient, { STANDARD_LANDSCAPE } from 'amazon-ivs-web-broadcast' ;

目的のストリーム構成で IVSBroadcastClient のインスタンスを作成し、Amazon IVS チャネルからエンドポイントを取り込み、それをコンポーネントの状態に設定できます。

 this .setState({  broadcastClient : IVSBroadcastClient.create({    streamConfig : STANDARD_LANDSCAPE,    ingestEndpoint : this .state.ingestEndpoint, }) });

クライアントのインスタンスを取得したので、カメラをクライアントに追加できます。このために使用します

navigator.mediaDevices.getUserMedia()
.

 const streamConfig = STANDARD_LANDSCAPE; const videoStream = await navigator.mediaDevices.getUserMedia({    video : {        deviceId : { exact : this .state.selectedVideoDeviceId },        width : {            ideal : streamConfig.maxResolution.width,            max : streamConfig.maxResolution.width, },        height : {            ideal : streamConfig.maxResolution.height,            max : streamConfig.maxResolution.height, }, }, }); this .state.broadcastClient.addVideoInputDevice(videoStream, 'camera1' , { index : 0 });

ユーザーのマイクをクライアントに追加する場合も、同様のパターンに従います。

 const audioStream = await navigator.mediaDevices.getUserMedia({    audio : {        deviceId : this .state.selectedAudioDeviceId }, }); this .state.broadcastClient.addAudioInputDevice(audioStream, 'mic1' );
注:ブラウザーのセキュリティ モデルにより、ユーザーのカメラとマイクにアクセスするためのアクセス許可を取得する必要があります。詳細については、 GitHub のプロジェクト ソースを参照してください。
ユーザーがデバイスを選択できるように、それらをダイアログに表示します。
複数のオプションが利用可能な場合はブロードキャスト デバイス。

これで、ライブ プレビューをページに追加して、視聴者が最終的にプレーヤー側で何を見るかを確認できるようになりました。

 <canvas ref={ this .previewRef} id= 'broadcast-preview' ></canvas>

プレビューを

broadcastClient
:

 this .state.broadcastClient.attachPreview( this .previewRef.current);

ブロードキャストを開始するには、ページにボタンを追加し、

 onClick
ボタン呼び出しのハンドラ
startBroadcast()
上で
broadcastClient
(必要な
streamKey
)。

 this .state.broadcastClient.startBroadcast( this .state.streamKey);

私の脳のデータを取得する

上で述べたように、私は

muse-js
このライブラリは、ヘッドバンドに接続して生データを取得する機能を提供します。でも、
 muse-js
は、EEG データの絶対帯域パワーを計算しません。このために、別のライブラリに手を伸ばす必要がありました。
 eeg-pipes
.

最初のステップは、ライブラリを追加してインポートすることです。

 $ npm install muse-js $ npm install @neurosity/pipes
 import { zipSamples, MuseClient } from 'muse-js' ; import { powerByBand, epoch, fft } from '@neurosity/pipes' ;

次に、クリック ハンドラーを含むボタンを追加しました。ハンドラーで、私は
ヘッドセットに接続し、データのリッスンを開始し、
ストリーム。

 const client = new MuseClient(); await client.connect(); await client.start(); zipSamples(client.eegReadings) .pipe( epoch({ duration : 1024 , interval : 250 , samplingRate : 256 }), fft({ bins : 256 }), powerByBand(), ) .subscribe(    ( data ) => {      const ch0 = [data.delta[ 0 ], data.theta[ 0 ], data.alpha[ 0 ], data.beta[ 0 ], data.gamma[ 0 ]];      const ch1 = [data.delta[ 1 ], data.theta[ 1 ], data.alpha[ 1 ], data.beta[ 1 ], data.gamma[ 1 ]];      const ch2 = [data.delta[ 2 ], data.theta[ 2 ], data.alpha[ 2 ], data.beta[ 2 ], data.gamma[ 2 ]];      const ch3 = [data.delta[ 3 ], data.theta[ 3 ], data.alpha[ 3 ], data.beta[ 3 ], data.gamma[ 3 ]];      const meta = [ch0, ch1, ch2, ch3];      //publish metadata
 } );

自分の脳データを Timed Metadata として公開する

これで、Muse から脳のデータを収集するハンドラーができました
ヘッドバンド、そのデータを時間指定されたメタデータとしてライブで公開する時が来ました
ストリーム。

すごいところは
timed metadata
ビデオ ストリームに直接埋め込まれ、そのストリームの永続的な部分として残ります。つまり、記録されたバージョンにも存在するということです。つまり、オンデマンドの再生でも、イベントをリッスンして応答することができます。

Web Broadcast SDK は、クライアント側からの時限メタデータの公開をサポートしていないため、使用する必要があります

putMetadata
(ドキュメント) AWS SDK for JavaScript経由。このために、AWS Lambda 関数を作成しました。

 const AWS = require ( 'aws-sdk' ); const ivs = new AWS.IVS({  apiVersion : '2020-07-14' ,  region : 'us-east-1'
}); exports .send = async (event, context, callback) => {  // response object
  const response = {      'statusCode' : 200 ,      'headers' : {          'Access-Control-Allow-Origin' : '*' ,          'Access-Control-Allow-Methods' : 'OPTIONS,GET,PUT,POST,DELETE' ,          'Content-Type' : 'application/json'
 },      'body' : '' ,      'isBase64Encoded' : false
 };  // parse payload
  let payload;  try { payload = JSON .parse(event.body); }  catch (err) { response.statusCode = 500 ; response.body = JSON .stringify(err); callback( null , response);    return ; }  // validate payload
  if (!payload || !payload.channelArn || !payload.metadata) { response.statusCode = 400 ; response.body = 'Must provide, channelArn and metadata' ; callback( null , response);    return ; }  // check payload size
  let byteLength = Buffer.byteLength(payload.metadata, 'utf8' );  if (byteLength > 1024 ) { response.statusCode = 400 ; response.body = 'Too big. Must be less than or equal to 1K' ; callback( null , response);    return ; }  // putmetadata input
  let params = {    channelArn : payload.channelArn,    metadata : payload.metadata };  try {    await ivs.putMetadata(params).promise(); response.statusCode = 200 ; response.body = JSON .stringify({ 'published' : true }, '' , 2 ); callback( null , response); }  catch (err) { response.statusCode = 500 ; response.body = err.stack; callback( null , response);    return ; } };

脳のデータを時限メタデータとして公開するために、Amazon API Gateway を作成して関数を呼び出し、

 subscribe()
上記のメソッドを使用して AWS Lambda 関数を呼び出します。

 zipSamples(client.eegReadings) .pipe( epoch({ duration : 1024 , interval : 250 , samplingRate : 256 }), fft({ bins : 256 }), powerByBand(), ) .subscribe(    ( data ) => {      const ch0 = [data.delta[ 0 ], data.theta[ 0 ], data.alpha[ 0 ], data.beta[ 0 ], data.gamma[ 0 ]];      const ch1 = [data.delta[ 1 ], data.theta[ 1 ], data.alpha[ 1 ], data.beta[ 1 ], data.gamma[ 1 ]];      const ch2 = [data.delta[ 2 ], data.theta[ 2 ], data.alpha[ 2 ], data.beta[ 2 ], data.gamma[ 2 ]];      const ch3 = [data.delta[ 3 ], data.theta[ 3 ], data.alpha[ 3 ], data.beta[ 3 ], data.gamma[ 3 ]];      const meta = [ch0, ch1, ch2, ch3];      // put metadata if broadcasting
      if ( this .state.isBroadcasting) { fetch(LAMBDA_URL, {          'method' : 'POST' ,          'mode' : 'no-cors' ,          'headers' : {            'Content-Type' : 'application/json' , },          'body' : JSON .stringify({            channelArn : this .state.channelArn,            metadata : JSON .stringify(meta) }) }); } } );

ライブ ストリーム再生の構築と脳データのグラフ化

脳内データ放送ビューのライブストリームが完了すると、
ライブ ストリームを表示する再生エクスペリエンスを作成する時間
時限メタデータを介して脳のデータをリアルタイムでグラフ化します。

ライブ ストリーム プレーヤーの作成

NPM 経由で IVS Web Player SDK を使用できますが、WebAssembly を使用するため、扱いが難しくなる可能性があります。そのトリッキーさを避けるために、私は Web プレーヤーを

<script>
タグと私はそれを私の
index.html
私のReactアプリで。

 <script src= "https://player.live-video.net/1.12.0/amazon-ivs-player.min.js" ></script>

私の中で

Playback.jsx
コンポーネント、プレーヤーへの参照といくつかの必要な要素を取得します。

 const { IVSPlayer } = window ; const { create : createMediaPlayer, isPlayerSupported, PlayerEventType, PlayerState } = IVSPlayer; const { ENDED, PLAYING, READY, BUFFERING } = PlayerState; const { TEXT_METADATA_CUE, ERROR } = PlayerEventType;

再生には、ネイティブを使用します

<video>
鬼ごっこ。

 <video ref={ this .videoRef} controls playsInline></video>

プレーヤーを初期化して再生を開始するには:

 this .playerRef.current = createMediaPlayer(); this .playerRef.current.attachHTMLVideoElement( this .videoRef.current); this .playerRef.current.load(STREAM_URL); this .playerRef.current.play();

時限メタデータのリッスンと応答

ライブ ストリームを再生しているので、受信する脳データをリッスンして応答できます。

 this .playerRef.current.addEventListener(TEXT_METADATA_CUE, this .onPlayerMetadata);

脳のデータをコンポーネントの状態に設定します。

 onPlayerMetadata = ( e ) => {  //console.log(e);
  const data = JSON .parse(e.text);  this .setState( state => { state.ch0.datasets[ 0 ].data = data[ 0 ]; state.ch1.datasets[ 0 ].data = data[ 1 ]; state.ch2.datasets[ 0 ].data = data[ 2 ]; state.ch3.datasets[ 0 ].data = data[ 3 ];    this .chartReferenceCh0.current.data.datasets[ 0 ].data = state.ch0.datasets[ 0 ].data;    this .chartReferenceCh1.current.data.datasets[ 0 ].data = state.ch1.datasets[ 0 ].data;    this .chartReferenceCh2.current.data.datasets[ 0 ].data = state.ch2.datasets[ 0 ].data;    this .chartReferenceCh3.current.data.datasets[ 0 ].data = state.ch3.datasets[ 0 ].data;    return ({      ch0 : state.ch0,      ch1 : state.ch1,      ch2 : state.ch2,      ch3 : state.ch3 }); }); };

そして、それを棒グラフ (Chart.js を使用) でレンダリングします。

 <Bar data={ this .state.ch0} ref={ this .chartReferenceCh0} options={ {      aspectRatio : 1 ,      title : {        display : true ,        text : 'Channel: ' + channelNames[ 0 ] },        responsive : true ,        tooltips : {          enabled : false 
 },        legend : {          display : false 
 } } } />

ビジュアライゼーションはクールで、確かに私のものを見る楽しい方法を提供します
ゲームのライブ ストリーミング中に脳のデータを取得しましたが、大量のデータは提供されません。
環境。だから私はいくつかの計算を含めることは理にかなっているだろうと考えました
データが実際に何を意味するかについての洞察を提供します。そのために、見つけた
でのいくつかの計算

muse-lsl
GitHub のプロジェクト
これには、次のような要因を計算するために使用できるいくつかの式が含まれていました
リラクゼーション(アルファをデルタで割る)、集中力(ベータを次で割る)
シータ)。私が見つけた別の素晴らしいブログ投稿では、疲労 ((シータ + アルファ) / ベータ) を導き出す方法が強調されていました。これらの計算を便利で再利用可能なコンポーネントにまとめました。

 <Row className= 'mb-2' > { /* Delta: 0 Theta: 1 Alpha: 2 Beta: 3 Gamma: 4 */ } <Col xs={ 12 } xxl={ 4 } className= 'align-items-center mb-2 mb-xxl-0' >    < Badge className = 'fs-6 w-100' bg = 'info' >
 Relaxation:      < span className = 'fw-bold' >
        < NumberFormat 
          value = {this.props.dataset.data[0] ? ( this.props.dataset.data [ 2 ] / this.props.dataset.data [ 0 ]) : 0 }          decimalScale = {2} 
          displayType = { ' text '} />
      </ span >
    </ Badge > 
 </Col>  < Col xs = {12} xxl = {4} className = 'align-items-center mb-2 mb-xxl-0' >
    < Badge className = 'fs-6 w-100' bg = 'info' >
 Fatigue:      < span className = 'fw-bold' >
        < NumberFormat 
          value = { this.props.dataset.data [ 3 ] ? ( ( this.props.dataset.data [ 1 ] + this.props.dataset.data [ 2 ]) / this.props.dataset.data [ 3 ] ) : 0 }          decimalScale = {2} 
          displayType = { ' text '} />
      </ span >
    </ Badge > 
  </ Col >
  < Col xs = {12} xxl = {4} className = 'align-items-center mb-2 mb-xxl-0' >
    < Badge className = 'fs-6 w-100' bg = 'info' >
 Focus:      < span className = 'fw-bold' >
        < NumberFormat 
          value = {this.props.dataset.data[1] ? ( this.props.dataset.data [ 3 ] / this.props.dataset.data [ 1 ]) : 0 }          decimalScale = {2} 
          displayType = { ' text '} />
      </ span >
    </ Badge >
  </ Col >
</Row>

概要

この投稿では、私がどのようにして React アプリケーションを作成したかを見ていきました。
Amazon IVS で脳のデータをストリーミングします。詳しく知りたい方は
Amazon IVS については、こちらの dev.to でAmazon Interactive Video Service の入門シリーズをご覧ください。アプリケーションを試してみたい、またはアプリケーションの完全なソースを確認したいだけの場合は、 GitHubで確認してください。コメント、質問、フィードバックはいつでも大歓迎です。ここにコメントを残すか、 Twitterで私に連絡してください。

リンク