इस साल की शुरुआत में, मैंने वास्तव में एक मजेदार परियोजना बनाई जिसे मैंने "ब्रेन" कहा
टू द क्लाउड" जहां मैंने खेलते समय अपने मस्तिष्क के डेटा को क्लाउड में सहेजा था
कॉल ऑफ ड्यूटी ताकि मैं अपने बीच के रिश्ते का विश्लेषण कर सकूं
संज्ञानात्मक कार्य और वीडियो गेम प्रदर्शन। मैंने तीन भाग लिखे
ब्लॉग पोस्ट श्रृंखला और मेरे निष्कर्षों को सारांशित करने के लिए कुछ मजेदार वीडियो बनाए
वह परियोजना। यदि आप उन्हें देखना चाहते हैं, तो आप इसका उल्लेख कर सकते हैं
इस पोस्ट के नीचे लिंक। मेरे प्रकाशित होने के कुछ महीने बाद
प्रोजेक्ट, मैंने ट्विच के लिए प्रमुख डेवलपर एडवोकेट के रूप में काम करना शुरू किया
अमेज़ॅन इंटरएक्टिव वीडियो सेवा (अमेज़ॅन आईवीएस) - एक पूरी तरह से प्रबंधित समाधान
लाइव, इंटरैक्टिव वीडियो स्ट्रीमिंग समाधान बनाने के लिए (अधिक जानने के लिए इस श्रृंखला को देखें)। मेरे "ब्रेन टू द क्लाउड" प्रोजेक्ट का अगला चरण स्पष्ट था - मुझे अपने मस्तिष्क को लाइव स्ट्रीम करने की आवश्यकता थी।
इससे पहले कि हम कोड देखें, आइए अंतिम उत्पाद देखें। वहाँ 2 है
एप्लिकेशन के लिए दृश्य: एक प्रसारण दृश्य और एक प्लेबैक दृश्य। में
प्रसारण दृश्य, हम लाइव वीडियो का पूर्वावलोकन कर सकते हैं, प्रारंभ कर सकते हैं
प्रसारण करें, और मस्तिष्क के डेटा को स्ट्रीम करने के लिए सरस्वती हेडबैंड को कनेक्ट करें
हेडबैंड से प्राप्त किया। प्लेबैक दृश्य में, हम लाइव प्रदर्शित करते हैं
ए के साथ स्ट्रीम करें
<video>
तत्व, और वास्तविक समय में मस्तिष्क डेटा को चार्ट करें इस परियोजना के 5 चरण हैं:
यदि आप ऐसी चीजों का ग्राफिकल चित्रण पसंद करते हैं, तो यहां देखें कि यह कैसा दिखता है:
मैंने इस प्रोजेक्ट के लिए रिएक्ट का इस्तेमाल किया। क्यों? खैर, मेरे पास काफी अनुभव है
Vue और Angular के साथ, लेकिन मैं शायद आखिरी डेवलपर्स में से एक हूं
पृथ्वी प्रतिक्रिया की कोशिश करने के लिए। मुझे लगा कि यह पता लगाने का समय आ गया है कि सब क्या है
प्रचार के बारे में था, और मुझे पता था कि यह मुश्किल नहीं होगा
इसके साथ निर्माण करने के लिए परियोजना। मेरे पूर्व अनुभव की कमी के कारण, मैं नहीं हूँ
आप ढांचे के "उन्नत" उपयोगकर्ता को क्या कहेंगे, लेकिन मुझे कहना है
कि मैं अब तक जो कुछ भी देख रहा हूं उससे बहुत खुश हूं। मुझे प्रक्रिया मिली
सुखद और खुद को ढांचे के साथ "लड़" नहीं पाया। परंतु
यह ब्लॉग पोस्ट जावास्क्रिप्ट ढांचे पर मेरी राय के बारे में नहीं है, इसलिए मैं करूँगा
इसे भविष्य की पोस्ट के लिए सेव करें। इसके बजाय, आइए बात करें कि मैं कैसे प्रसारित करता हूं
मेरा दिमाग!
मेरे मूल "ब्रेन टू द क्लाउड" प्रोजेक्ट में, मैंने "विंटेज" ईईजी का इस्तेमाल किया
मेरे दिमाग की रीडिंग को कैप्चर करने के लिए हेडसेट को माइंडफ्लेक्स कहा जाता है। इसने निष्पक्ष रूप से काम किया
ठीक है, लेकिन मुझे ESP-12 जोड़कर डिवाइस को "हैक" करने की आवश्यकता है
डिवाइस के रीडिंग को खींचने और भेजने के लिए माइक्रोकंट्रोलर
उन्हें बादल के लिए। इस बार मैं कुछ नया लेकर आया -
और कुछ ऐसा जो मैं बिना किसी संशोधन के उपयोग कर सकता था। थोड़े के बाद
शोध, मैं सरस्वती एस हेडबैंड पर बस गया। शुक्र है, वास्तव में एक भयानक ओपन-सोर्स लाइब्रेरी है, जिसे म्यूज़-जेएस कहा जाता है, जो मुझे वेब ब्लूटूथ (निश्चित रूप से समर्थित ब्राउज़रों में) के साथ वेब ब्राउज़र में सीधे मस्तिष्क की रीडिंग तक पहुंचने देता है।
कुछ समय पहले तक, Amazon IVS के साथ लाइव स्ट्रीमिंग के लिए हमें एक का उपयोग करना पड़ता था
हमारी स्ट्रीम को RTMPS के रूप में प्रसारित करने के लिए तृतीय-पक्ष क्लाइंट। लेकिन हम हाल ही में
गेम-चेंजर लॉन्च किया: Amazon IVS वेब ब्रॉडकास्ट SDK ।
जैसा कि नाम से ही स्पष्ट है, यह एसडीके हमें अपने प्रसारण की क्षमता देता है
सीधे वेब ब्राउज़र से WebRTC के माध्यम से लाइव स्ट्रीम करें। स्पष्ट रूप से, यह एक था
मेरे दिमाग को लाइव स्ट्रीमिंग के लिए एकदम सही फिट क्योंकि इसका मतलब है कि मैं बना सकता हूं
मेरे मस्तिष्क डेटा को मेरे साथ प्रसारित करने के लिए एक "ऑल-इन-वन" समाधान
तृतीय-पक्ष सॉफ़्टवेयर या बाहरी स्क्रिप्ट पर भरोसा किए बिना लाइव स्ट्रीम करें।
रिएक्ट ऐप में वेब ब्रॉडकास्ट जोड़ना
हम इसका उपयोग करने के लिए आवश्यक हर एक कदम पर गौर नहीं करने जा रहे हैं
इस पोस्ट में वेब प्रसारण एसडीके। इसके बजाय, हम हाइलाइट्स को देखेंगे
यह कैसे काम करता है इसका एक सामान्य विचार प्राप्त करें। चिंता न करें - मेरे पास एक और पोस्ट है
जल्द ही आ रहा है जहां हम उपयोग करने के लिए "चरण-दर-चरण" प्रक्रिया में खुदाई करेंगे
वेब ब्रॉडकास्ट एसडीके, तो उसके लिए बने रहें। उस ने कहा, चलो एक ले लो
यह देखने के लिए त्वरित यात्रा कि मैंने इस प्रोजेक्ट में SDK का उपयोग कैसे किया। मेरा पहला कदम
स्थापित करने के लिए एक वेब प्रसारण का उपयोग करना था
amazon-ivs-web-broadcast
मापांक। अपने पसंदीदा पैकेज प्रबंधन उपकरण का उपयोग करके, चलाएँ: $ npm install amazon-ivs-web-broadcast
अगला, हमें इसे अपने घटक में आयात करने की आवश्यकता है। मेरे ब्रॉडकास्ट.जेएसएक्स घटक में, मैंने जोड़ा:
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' );
नोट: ब्राउज़र सुरक्षा मॉडल के कारण, हमें उपयोगकर्ता के कैमरे और माइक्रोफ़ोन तक पहुँचने के लिए अनुमतियाँ प्राप्त करने की आवश्यकता होती है। इस पर अधिक जानकारी के लिए गिटहब पर परियोजना स्रोत का संदर्भ लें, और यह देखने के लिए कि मैंने सूची कैसे प्राप्त की
उपकरण और उपयोगकर्ता को चुनने की अनुमति देने के लिए उन्हें एक संवाद में प्रस्तुत किया
ब्रॉडकास्ट डिवाइस अगर कई विकल्प उपलब्ध हैं।
अब हम पृष्ठ पर एक लाइव पूर्वावलोकन जोड़ सकते हैं ताकि हम देख सकें कि हमारे दर्शक अंततः खिलाड़ियों की तरफ से क्या देखेंगे।
<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-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
वेब ब्रॉडकास्ट एसडीके क्लाइंट की ओर से समयबद्ध मेटाडेटा को प्रकाशित करने का समर्थन नहीं करता है, इसलिए हमें इसका उपयोग करना होगा
putMetadata
( डॉक्स ) जावास्क्रिप्ट के लिए एडब्ल्यूएस एसडीके के माध्यम से। इसके लिए मैंने AWS लैम्ब्डा फंक्शन बनाया। 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 ; } };
मेरे मस्तिष्क डेटा को समयबद्ध मेटाडेटा के रूप में प्रकाशित करने के लिए, मैंने फ़ंक्शन को लागू करने और संशोधित करने के लिए एक अमेज़ॅन एपीआई गेटवे बनाया
subscribe()
उपरोक्त विधि AWS लैम्ब्डा फ़ंक्शन को कॉल करने के लिए। 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 वेब प्लेयर SDK का उपयोग कर सकते हैं, लेकिन चूंकि यह WebAssembly का उपयोग करता है इसलिए चीजें मुश्किल हो सकती हैं । उस चालाकी से बचने के लिए, मुझे वेब प्लेयर का उपयोग करना आसान लगता है
<script>
टैग और मैंने उसे जोड़ा my index.html
मेरे रिएक्ट ऐप में। <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 }); }); };
और इसे बार चार्ट के साथ प्रस्तुत करें (चार्ट.जेएस के साथ):
<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>
इस पोस्ट में, हमने देखा कि कैसे मैंने जीने के लिए एक रिएक्ट एप्लिकेशन बनाया
Amazon IVS के साथ मेरे मस्तिष्क के डेटा को स्ट्रीम करें। यदि आप के बारे में और जानना चाहते हैं
Amazon IVS, कृपया dev.to पर Amazon इंटरैक्टिव वीडियो सेवा के साथ आरंभ करने की श्रृंखला देखें। यदि आप एप्लिकेशन को आज़माने में रुचि रखते हैं या केवल एप्लिकेशन के पूर्ण स्रोत की जाँच कर रहे हैं, तो इसे GitHub पर देखें। आपकी टिप्पणियों, प्रश्नों और प्रतिक्रिया का हमेशा स्वागत है, इसलिए यहां एक टिप्पणी छोड़ें या ट्विटर पर मेरे साथ जुड़ें