SlideShare una empresa de Scribd logo
1 de 66
Descargar para leer sin conexión
@fischaelameergeildanke.com #webrebels
Using Web APIs 

For Your Own PleasurePleasure
What? Why?
Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project
What? Why?
Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project
Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project
What? Why?
Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project
What? Why?
Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project
What? Why?
Ahhh
Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project
What? Why?
Web Bluetooth API Support
Devices with
Bluetooth 4.0 or higher
Chrome, Chrome on Android,

Samsung Internet, Opera
Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project
Three Steps to Happiness
Write Data
via Bluetooth API
Connect
Bluetooth Device
Request Connection
Read
Audio Data
Expose Vowels
Uncover Bluetooth Commands
Web Bluetooth API
Connect to and interact with
Bluetooth Low Energy devices.
Bluetooth Low Energy
Bluetooth LE, BLE, Bluetooth smart
Bluetooth Low Energy
Support
iOS 5+ Android 4.3+ OS X 10.6+ Windows 8+
Harald "Blåtand"
Gormsson
~958-986
King of Denmark and Norway
means Bluetooth
Haglaz
Old Norse: Hagall
Berkanan
Old Norse: Bjarkan
Advertising and Discovery
Peripheral Device Central Device
Frequency Hopping Spread Spectrum (FHSS)
short-wavelength radio waves

~2.4GHz
Advertising and Discovery
Peripheral
Device
Central
Device
scan
response
request
advertising
data
advertising
data
scan
response
data
Advertising as Broadcasting
Peripheral
Device
Central Device
Central Device
Central Device
Central Device
Central DeviceCentral Device
Advertising Data
GATT
Generic Attribute Profile
Defines the way two Bluetooth LE devices 

transfer data back and forth 

using Characteristics and Services.
GATT
Server
GATT 

Client
Communication via GATT
sends

response
sends
request
sends

response
sends
request
sends
reques
Profile
collection of
related services
Service
collection of
related
characteristics
Parts of GATT
Characteristic
Characteristic
Characteristic
read (RX) and
write (TX) data
Connect Bluetooth Device
const LUSH_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e';
button.addEventListener('click', () => {
navigator.bluetooth.requestDevice({
filters: [{ services: [LUSH_SERVICE] }]
}).then((device) => {
console.log('Device found. Device: ', device);
return device.gatt.connect();
}).then((server) => {
console.log('Device connected. Server ', server);
});
});
Connect Bluetooth Device
const LUSH_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e';
button.addEventListener('click', () => {
navigator.bluetooth.requestDevice({
filters: [{ services: [LUSH_SERVICE] }]
}).then((device) => {
console.log('Device found. Device: ', device);
return device.gatt.connect();
}).then((server) => {
console.log('Device connected. Server ', server);
});
});
const LUSH_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e';
button.addEventListener('click', () => {
navigator.bluetooth.requestDevice({
filters: [{ services: [LUSH_SERVICE] }]
}).then((device) => {
console.log('Device found. Device: ', device);
return device.gatt.connect();
}).then((server) => {
console.log('Device connected. Server ', server);
});
});
Connect Bluetooth Device
const LUSH_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e';
button.addEventListener('click', () => {
navigator.bluetooth.requestDevice({
filters: [{ services: [LUSH_SERVICE] }]
}).then((device) => {
console.log('Device found. Device: ', device);
return device.gatt.connect();
}).then((server) => {
console.log('Device connected. Server ', server);
});
});
Connect Bluetooth Device
nRF Connect
nRF Connect
Nordic UART
Service
const LUSH_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e';
button.addEventListener('click', () => {
navigator.bluetooth.requestDevice({
filters: [{ services: [LUSH_SERVICE] }]
}).then((device) => {
console.log('Device found. Device: ', device);
return device.gatt.connect();
}).then((server) => {
console.log('Device connected. Server ', server);
});
});
Connect Bluetooth Device
const LUSH_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e';
button.addEventListener('click', () => {
navigator.bluetooth.requestDevice({
filters: [{ services: [LUSH_SERVICE] }]
}).then((device) => {
console.log('Device found. Device: ', device);
return device.gatt.connect();
}).then((server) => {
console.log('Device connected. Server ', server);
});
});
Connect Bluetooth Device
Web Audio API
Control audio on the web inside an Audio Context
with linked together Audio Nodes that for an
Audio Routing Graph.
Audio Context
Audio Routing Graph
Source Node
e.g. <audio>
output
Audio Node
Processing Node
e.g. reverb
input
Audio Node
output
Destination Node
e.g. speakers
Audio Node
input
UltrasonicSubsonic
20Hz
Sound Frequencies
heard by human ears
20kHz
What is Sound?
What is Sound?
https://en.wikipedia.org/wiki/Sound#/media/File:Sine_waves_different_frequencies.svg
What is Sound?
https://de.wikipedia.org/wiki/Frequenzspektrum
How to detect Vowels
formants:
f1 = ~800hz
f2 = ~1600hz
https://de.wikipedia.org/wiki/Formant
Vowel Detection within the Web
AudioContext MediaStreamAudioSourceNode AnalyserNode
Create Context and Nodes
Connect Nodes
MediaStreamAudioSourceNode AnalyserNode Destination
Vowel Detection within the Web
let audioContext = new window.AudioContext();
let stream = document.getElementById('video').captureStream();
let audioSource = audioContext.createMediaStreamSource(stream);
let analyser = audioContext.createAnalyser();
audioSource.connect(analyser);
analyser.connect(audioContext.destination);
Vowel Detection within the Web
let audioContext = new window.AudioContext();
let stream = document.getElementById('video').captureStream();
let audioSource = audioContext.createMediaStreamSource(stream);
let analyser = audioContext.createAnalyser();
audioSource.connect(analyser);
analyser.connect(audioContext.destination);
AnalyserNode
Input Node Anaylser Node Output Node
UnchangedFast Fourier
Transformation
Frequency Data
AnalyserNode
analyser.fftSize = 2048;
console.log(analyser.frequencyBinCount); //1024
let dataArray = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(dataArray);
AnalyserNode
analyser.fftSize = 2048;
console.log(analyser.frequencyBinCount); //1024
let dataArray = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(dataArray);
AnalyserNode
analyser.fftSize = 2048;
console.log(analyser.frequencyBinCount); //1024
let dataArray = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(dataArray);
AnalyserNode
analyser.fftSize = 2048;
console.log(analyser.frequencyBinCount); //1024
let dataArray = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(dataArray);
Visualize and Analyse Audio
let render = function () {
analyser.getByteFrequencyData(dataArray);
formants = getFormants(dataArray);
vowel = formantsToAh(formants[0], formants[1]);
window.requestAnimationFrame(render);
};
window.requestAnimationFrame(render);
Frequency Data
decibel = value / 256;Get Decibel
frequency = index * 44100 / 2048;Get Frequency
audioContext.sampleRate
FFT Size
Get Formants
let getFormants = function (data) {
let f1, f2, maxF1 = -Infinity, maxF2 = -Infinity;
data.forEach(function (date, i) {
let frequency = i * 44100 / 2048, decibel = date / 256;
if (frequency < 1000) {
if (decibel > maxF1) { maxF1 = decibel; f1 = frequency; }
} else if (frequency < 5000) {
if (decibel > maxF2) { maxF2 = decibel; f2 = frequency; }
}
});
return [{ db: maxF1, freq: f1}, { db: maxF2, freq: f2 }];
};
Get Formants
let getFormants = function (data) {
let f1, f2, maxF1 = -Infinity, maxF2 = -Infinity;
data.forEach(function (date, i) {
let frequency = i * 44100 / 2048, decibel = date / 256;
if (frequency < 1000) {
if (decibel > maxF1) { maxF1 = decibel; f1 = frequency; }
} else if (frequency < 5000) {
if (decibel > maxF2) { maxF2 = decibel; f2 = frequency; }
}
});
return [{ db: maxF1, freq: f1}, { db: maxF2, freq: f2 }];
};
Get Formants
let getFormants = function (data) {
let f1, f2, maxF1 = -Infinity, maxF2 = -Infinity;
data.forEach(function (date, i) {
let frequency = i * 44100 / 2048, decibel = date / 256;
if (frequency < 1000) {
if (decibel > maxF1) { maxF1 = decibel; f1 = frequency; }
} else if (frequency < 5000) {
if (decibel > maxF2) { maxF2 = decibel; f2 = frequency; }
}
});
return [{ db: maxF1, freq: f1}, { db: maxF2, freq: f2 }];
};
Get Formants
let getFormants = function (data) {
let f1, f2, maxF1 = -Infinity, maxF2 = -Infinity;
data.forEach(function (date, i) {
let frequency = i * 44100 / 2048, decibel = date / 256;
if (frequency < 1000) {
if (decibel > maxF1) { maxF1 = decibel; f1 = frequency; }
} else if (frequency < 5000) {
if (decibel > maxF2) { maxF2 = decibel; f2 = frequency; }
}
});
return [{ db: maxF1, freq: f1}, { db: maxF2, freq: f2 }];
};
Get Formants
let getFormants = function (data) {
let f1, f2, maxF1 = -Infinity, maxF2 = -Infinity;
data.forEach(function (date, i) {
let frequency = i * 44100 / 2048, decibel = date / 256;
if (frequency < 1000) {
if (decibel > maxF1) { maxF1 = decibel; f1 = frequency; }
} else if (frequency < 5000) {
if (decibel > maxF2) { maxF2 = decibel; f2 = frequency; }
}
});
return [{ db: maxF1, freq: f1}, { db: maxF2, freq: f2 }];
};
Get Vowels
let formantsToAh = function (f1, f2) {
if (f1.freq > 700 && f1.freq < 1000 && f1.db > 0.4 &&
f2.freq > 1200 && f2.freq < 1800 && f2.db > 0.2) {
return 'a';
}
return null;
};
Real-time Vowel Detection
let render = function () {
analyser.getByteFrequencyData(dataArray);
formants = getFormants(dataArray);
vowel = formantsToAh(formants[0], formants[1]);
if (vowel === 'a') {
console.log('Ah!');
}
window.requestAnimationFrame(render);
};
Next video: https://www.youtube.com/watch?v=-74Tyi-fvi8
Identify Bluetooth Commands
Vibrate:4;
Identify Bluetooth Commands
56 69 62 72 61 74 65 3a 34 3b
Write to a Bluetooth Characteristic
const LUSH_TX_CHARACTERISTIC = '6e400002-b5a3-f393-e0a9-e50e24dcca9e';
let txCharacteristic = null;
button.addEventListener('click', () => {
/* … */
}).then((server) => {
return server.getPrimaryService(LUSH_SERVICE);
}).then((service) => {
return service.getCharacteristic(LUSH_TX_CHARACTERISTIC);
}).then((characteristic) => { txCharacteristic = characteristic; });
});
const LUSH_TX_CHARACTERISTIC = '6e400002-b5a3-f393-e0a9-e50e24dcca9e';
let txCharacteristic = null;
button.addEventListener('click', () => {
/* … */
}).then((server) => {
return server.getPrimaryService(LUSH_SERVICE);
}).then((service) => {
return service.getCharacteristic(LUSH_TX_CHARACTERISTIC);
}).then((characteristic) => { txCharacteristic = characteristic; });
});
Write to a Bluetooth Characteristic
const LUSH_TX_CHARACTERISTIC = '6e400002-b5a3-f393-e0a9-e50e24dcca9e';
let txCharacteristic = null;
button.addEventListener('click', () => {
/* … */
}).then((server) => {
return server.getPrimaryService(LUSH_SERVICE);
}).then((service) => {
return service.getCharacteristic(LUSH_TX_CHARACTERISTIC);
}).then((characteristic) => { txCharacteristic = characteristic; });
});
Write to a Bluetooth Characteristic
if (vowel === 'a') {
let message = new TextEncoder('ASCII').encode('Vibrate:10;');
txCharacteristic.writeValue(message);
} else {
let message = new TextEncoder('ASCII').encode('Vibrate:0;');
txCharacteristic.writeValue(message);
}
Write to a Bluetooth Characteristic
if (vowel === 'a') {
let message = new TextEncoder('ASCII').encode('Vibrate:10;');
txCharacteristic.writeValue(message);
} else {
let message = new TextEncoder('ASCII').encode('Vibrate:0;');
txCharacteristic.writeValue(message);
}
Write to a Bluetooth Characteristic
Next video: https://www.youtube.com/watch?v=-74Tyi-fvi8
@fischaelameergeildanke.com #webrebels
Be Creative!
Use More Web APIs, Experiment, Give Feedback
@fischaelameergeildanke.com #webrebels
More Information
https://developers.google.com/web/updates/2015/07/interact-with-ble-devices-on-the-web
http://nilhcem.com/iot/reverse-engineering-simple-bluetooth-devices
https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API
https://www.bluetooth.com/specifications/gatt/services
Thanks to:
Stefan Judis
https://www.metafetish.com/
https://github.com/gre/zpeech

Más contenido relacionado

La actualidad más candente

Python chapter 2
Python chapter 2Python chapter 2
Python chapter 2Raghu nath
 
python chapter 1
python chapter 1python chapter 1
python chapter 1Raghu nath
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKirill Rozov
 
The Ring programming language version 1.10 book - Part 92 of 212
The Ring programming language version 1.10 book - Part 92 of 212The Ring programming language version 1.10 book - Part 92 of 212
The Ring programming language version 1.10 book - Part 92 of 212Mahmoud Samir Fayed
 
RIA - Entwicklung mit Ext JS
RIA - Entwicklung mit Ext JSRIA - Entwicklung mit Ext JS
RIA - Entwicklung mit Ext JSDominik Jungowski
 
Go for the would be network programmer
Go for the would be network programmerGo for the would be network programmer
Go for the would be network programmerEleanor McHugh
 
The Ring programming language version 1.5.4 book - Part 46 of 185
The Ring programming language version 1.5.4 book - Part 46 of 185The Ring programming language version 1.5.4 book - Part 46 of 185
The Ring programming language version 1.5.4 book - Part 46 of 185Mahmoud Samir Fayed
 
Código fuente del software educativo
Código fuente del software educativoCódigo fuente del software educativo
Código fuente del software educativoLeo Chavez Martinez
 
Código fuente del software educativo
Código fuente del software educativoCódigo fuente del software educativo
Código fuente del software educativoLeo Chavez Martinez
 
Neotool (using py2neo from the command line)
Neotool (using py2neo from the command line)Neotool (using py2neo from the command line)
Neotool (using py2neo from the command line)Nigel Small
 
Investigating Python Wats
Investigating Python WatsInvestigating Python Wats
Investigating Python WatsAmy Hanlon
 
PLOTCON NYC: Behind Every Great Plot There's a Great Deal of Wrangling
PLOTCON NYC: Behind Every Great Plot There's a Great Deal of WranglingPLOTCON NYC: Behind Every Great Plot There's a Great Deal of Wrangling
PLOTCON NYC: Behind Every Great Plot There's a Great Deal of WranglingPlotly
 
Elixir & Phoenix – fast, concurrent and explicit
Elixir & Phoenix – fast, concurrent and explicitElixir & Phoenix – fast, concurrent and explicit
Elixir & Phoenix – fast, concurrent and explicitTobias Pfeiffer
 
T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...
T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...
T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...Jeroen Baten
 
The Ring programming language version 1.9 book - Part 56 of 210
The Ring programming language version 1.9 book - Part 56 of 210The Ring programming language version 1.9 book - Part 56 of 210
The Ring programming language version 1.9 book - Part 56 of 210Mahmoud Samir Fayed
 
Elixir & Phoenix – fast, concurrent and explicit
Elixir & Phoenix – fast, concurrent and explicitElixir & Phoenix – fast, concurrent and explicit
Elixir & Phoenix – fast, concurrent and explicitTobias Pfeiffer
 
The Ring programming language version 1.5.4 book - Part 47 of 185
The Ring programming language version 1.5.4 book - Part 47 of 185The Ring programming language version 1.5.4 book - Part 47 of 185
The Ring programming language version 1.5.4 book - Part 47 of 185Mahmoud Samir Fayed
 

La actualidad más candente (19)

Python chapter 2
Python chapter 2Python chapter 2
Python chapter 2
 
python chapter 1
python chapter 1python chapter 1
python chapter 1
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is coming
 
The Ring programming language version 1.10 book - Part 92 of 212
The Ring programming language version 1.10 book - Part 92 of 212The Ring programming language version 1.10 book - Part 92 of 212
The Ring programming language version 1.10 book - Part 92 of 212
 
FPBrno 2018-05-22: Benchmarking in elixir
FPBrno 2018-05-22: Benchmarking in elixirFPBrno 2018-05-22: Benchmarking in elixir
FPBrno 2018-05-22: Benchmarking in elixir
 
RIA - Entwicklung mit Ext JS
RIA - Entwicklung mit Ext JSRIA - Entwicklung mit Ext JS
RIA - Entwicklung mit Ext JS
 
Go for the would be network programmer
Go for the would be network programmerGo for the would be network programmer
Go for the would be network programmer
 
Corona sdk
Corona sdkCorona sdk
Corona sdk
 
The Ring programming language version 1.5.4 book - Part 46 of 185
The Ring programming language version 1.5.4 book - Part 46 of 185The Ring programming language version 1.5.4 book - Part 46 of 185
The Ring programming language version 1.5.4 book - Part 46 of 185
 
Código fuente del software educativo
Código fuente del software educativoCódigo fuente del software educativo
Código fuente del software educativo
 
Código fuente del software educativo
Código fuente del software educativoCódigo fuente del software educativo
Código fuente del software educativo
 
Neotool (using py2neo from the command line)
Neotool (using py2neo from the command line)Neotool (using py2neo from the command line)
Neotool (using py2neo from the command line)
 
Investigating Python Wats
Investigating Python WatsInvestigating Python Wats
Investigating Python Wats
 
PLOTCON NYC: Behind Every Great Plot There's a Great Deal of Wrangling
PLOTCON NYC: Behind Every Great Plot There's a Great Deal of WranglingPLOTCON NYC: Behind Every Great Plot There's a Great Deal of Wrangling
PLOTCON NYC: Behind Every Great Plot There's a Great Deal of Wrangling
 
Elixir & Phoenix – fast, concurrent and explicit
Elixir & Phoenix – fast, concurrent and explicitElixir & Phoenix – fast, concurrent and explicit
Elixir & Phoenix – fast, concurrent and explicit
 
T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...
T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...
T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...
 
The Ring programming language version 1.9 book - Part 56 of 210
The Ring programming language version 1.9 book - Part 56 of 210The Ring programming language version 1.9 book - Part 56 of 210
The Ring programming language version 1.9 book - Part 56 of 210
 
Elixir & Phoenix – fast, concurrent and explicit
Elixir & Phoenix – fast, concurrent and explicitElixir & Phoenix – fast, concurrent and explicit
Elixir & Phoenix – fast, concurrent and explicit
 
The Ring programming language version 1.5.4 book - Part 47 of 185
The Ring programming language version 1.5.4 book - Part 47 of 185The Ring programming language version 1.5.4 book - Part 47 of 185
The Ring programming language version 1.5.4 book - Part 47 of 185
 

Similar a Using New Web APIs For Your Own Pleasure – How I Wrote New Features For My Vibrator using the Web Bluetooth API and the Web Audio API

Using New Web APIs For Your Own Pleasure
Using New Web APIs For Your Own PleasureUsing New Web APIs For Your Own Pleasure
Using New Web APIs For Your Own PleasureMichaela Lehr
 
Using New Web APIs For Your Own Pleasure
Using New Web APIs For Your Own PleasureUsing New Web APIs For Your Own Pleasure
Using New Web APIs For Your Own PleasureGeilDanke
 
Arduino and the real time web
Arduino and the real time webArduino and the real time web
Arduino and the real time webAndrew Fisher
 
Asynchronous Programming at Netflix
Asynchronous Programming at NetflixAsynchronous Programming at Netflix
Asynchronous Programming at NetflixC4Media
 
Remote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.create
Remote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.createRemote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.create
Remote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.createPeter Lehto
 
Getting physical with web bluetooth in the browser
Getting physical with web bluetooth in the browserGetting physical with web bluetooth in the browser
Getting physical with web bluetooth in the browserDan Jenkins
 
Going real time with Socket.io
Going real time with Socket.ioGoing real time with Socket.io
Going real time with Socket.ioArnout Kazemier
 
Presentation at ClueCon 2019 - Chicago, IL, USA 🇺🇸
Presentation at ClueCon 2019 - Chicago, IL, USA 🇺🇸Presentation at ClueCon 2019 - Chicago, IL, USA 🇺🇸
Presentation at ClueCon 2019 - Chicago, IL, USA 🇺🇸Alessandro Polidori
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015Fernando Daciuk
 
Server Side Events
Server Side EventsServer Side Events
Server Side Eventsthepilif
 
Introduction to Things board (An Open Source IoT Cloud Platform)
Introduction to Things board (An Open Source IoT Cloud Platform)Introduction to Things board (An Open Source IoT Cloud Platform)
Introduction to Things board (An Open Source IoT Cloud Platform)Amarjeetsingh Thakur
 
Android Wi-Fi Manager and Bluetooth Connection
Android Wi-Fi Manager and Bluetooth ConnectionAndroid Wi-Fi Manager and Bluetooth Connection
Android Wi-Fi Manager and Bluetooth ConnectionJussi Pohjolainen
 
DomCode 2015 - Abusing phones to make the internet of things
DomCode 2015 - Abusing phones to make the internet of thingsDomCode 2015 - Abusing phones to make the internet of things
DomCode 2015 - Abusing phones to make the internet of thingsJan Jongboom
 
Getting physical with web bluetooth in the browser
Getting physical with web bluetooth in the browserGetting physical with web bluetooth in the browser
Getting physical with web bluetooth in the browserDan Jenkins
 
Designing for Distributed Systems with Reactor and Reactive Streams
Designing for Distributed Systems with Reactor and Reactive StreamsDesigning for Distributed Systems with Reactor and Reactive Streams
Designing for Distributed Systems with Reactor and Reactive StreamsStéphane Maldini
 
WebRTC 101 - How to get started building your first WebRTC application
WebRTC 101 - How to get started building your first WebRTC applicationWebRTC 101 - How to get started building your first WebRTC application
WebRTC 101 - How to get started building your first WebRTC applicationDan Jenkins
 
Can you hear me now?
Can you hear me now?Can you hear me now?
Can you hear me now?Ida Aalen
 
Windows Phone 8 Sensors
Windows Phone 8 SensorsWindows Phone 8 Sensors
Windows Phone 8 SensorsDavid Isbitski
 

Similar a Using New Web APIs For Your Own Pleasure – How I Wrote New Features For My Vibrator using the Web Bluetooth API and the Web Audio API (20)

Using New Web APIs For Your Own Pleasure
Using New Web APIs For Your Own PleasureUsing New Web APIs For Your Own Pleasure
Using New Web APIs For Your Own Pleasure
 
Using New Web APIs For Your Own Pleasure
Using New Web APIs For Your Own PleasureUsing New Web APIs For Your Own Pleasure
Using New Web APIs For Your Own Pleasure
 
Air superiority for Android Apps
Air superiority for Android AppsAir superiority for Android Apps
Air superiority for Android Apps
 
Arduino and the real time web
Arduino and the real time webArduino and the real time web
Arduino and the real time web
 
Asynchronous Programming at Netflix
Asynchronous Programming at NetflixAsynchronous Programming at Netflix
Asynchronous Programming at Netflix
 
Remote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.create
Remote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.createRemote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.create
Remote controlling Parrot AR drone with Vaadin & Spring Boot @ GWT.create
 
Getting physical with web bluetooth in the browser
Getting physical with web bluetooth in the browserGetting physical with web bluetooth in the browser
Getting physical with web bluetooth in the browser
 
Going real time with Socket.io
Going real time with Socket.ioGoing real time with Socket.io
Going real time with Socket.io
 
Presentation at ClueCon 2019 - Chicago, IL, USA 🇺🇸
Presentation at ClueCon 2019 - Chicago, IL, USA 🇺🇸Presentation at ClueCon 2019 - Chicago, IL, USA 🇺🇸
Presentation at ClueCon 2019 - Chicago, IL, USA 🇺🇸
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015
 
Server Side Events
Server Side EventsServer Side Events
Server Side Events
 
Introduction to Things board (An Open Source IoT Cloud Platform)
Introduction to Things board (An Open Source IoT Cloud Platform)Introduction to Things board (An Open Source IoT Cloud Platform)
Introduction to Things board (An Open Source IoT Cloud Platform)
 
Android Wi-Fi Manager and Bluetooth Connection
Android Wi-Fi Manager and Bluetooth ConnectionAndroid Wi-Fi Manager and Bluetooth Connection
Android Wi-Fi Manager and Bluetooth Connection
 
DomCode 2015 - Abusing phones to make the internet of things
DomCode 2015 - Abusing phones to make the internet of thingsDomCode 2015 - Abusing phones to make the internet of things
DomCode 2015 - Abusing phones to make the internet of things
 
Getting physical with web bluetooth in the browser
Getting physical with web bluetooth in the browserGetting physical with web bluetooth in the browser
Getting physical with web bluetooth in the browser
 
Designing for Distributed Systems with Reactor and Reactive Streams
Designing for Distributed Systems with Reactor and Reactive StreamsDesigning for Distributed Systems with Reactor and Reactive Streams
Designing for Distributed Systems with Reactor and Reactive Streams
 
WebRTC 101 - How to get started building your first WebRTC application
WebRTC 101 - How to get started building your first WebRTC applicationWebRTC 101 - How to get started building your first WebRTC application
WebRTC 101 - How to get started building your first WebRTC application
 
JavaCro'15 - Remote controlling Parrot AR Drone with Spring Boot and Vaadin -...
JavaCro'15 - Remote controlling Parrot AR Drone with Spring Boot and Vaadin -...JavaCro'15 - Remote controlling Parrot AR Drone with Spring Boot and Vaadin -...
JavaCro'15 - Remote controlling Parrot AR Drone with Spring Boot and Vaadin -...
 
Can you hear me now?
Can you hear me now?Can you hear me now?
Can you hear me now?
 
Windows Phone 8 Sensors
Windows Phone 8 SensorsWindows Phone 8 Sensors
Windows Phone 8 Sensors
 

Más de GeilDanke

WebXR: A New Dimension For The Web Writing Virtual and Augmented Reality Apps...
WebXR: A New Dimension For The Web Writing Virtual and Augmented Reality Apps...WebXR: A New Dimension For The Web Writing Virtual and Augmented Reality Apps...
WebXR: A New Dimension For The Web Writing Virtual and Augmented Reality Apps...GeilDanke
 
Writing Virtual And Augmented Reality Apps With Web Technology
Writing Virtual And Augmented Reality Apps With Web TechnologyWriting Virtual And Augmented Reality Apps With Web Technology
Writing Virtual And Augmented Reality Apps With Web TechnologyGeilDanke
 
Creating Augmented Reality Apps with Web Technology
Creating Augmented Reality Apps with Web TechnologyCreating Augmented Reality Apps with Web Technology
Creating Augmented Reality Apps with Web TechnologyGeilDanke
 
How to Make Your Users Sick in 60 Seconds – About UX Design, WebVR and React VR
How to Make Your Users Sick in 60 Seconds – About UX Design, WebVR and React VRHow to Make Your Users Sick in 60 Seconds – About UX Design, WebVR and React VR
How to Make Your Users Sick in 60 Seconds – About UX Design, WebVR and React VRGeilDanke
 
More Ways to Make Your Users Sick – A talk about WebVR and UX Design
More Ways to Make Your Users Sick – A talk about WebVR and UX DesignMore Ways to Make Your Users Sick – A talk about WebVR and UX Design
More Ways to Make Your Users Sick – A talk about WebVR and UX DesignGeilDanke
 
Goodbye, Flatland! An introduction to WebVR and what it means for web developers
Goodbye, Flatland! An introduction to WebVR and what it means for web developersGoodbye, Flatland! An introduction to WebVR and what it means for web developers
Goodbye, Flatland! An introduction to WebVR and what it means for web developersGeilDanke
 
Goodbye, Flatland! An introduction to React VR and what it means for web dev...
Goodbye, Flatland! An introduction to React VR  and what it means for web dev...Goodbye, Flatland! An introduction to React VR  and what it means for web dev...
Goodbye, Flatland! An introduction to React VR and what it means for web dev...GeilDanke
 
An Introduction to WebVR – or How to make your user sick in 60 seconds
An Introduction to WebVR – or How to make your user sick in 60 secondsAn Introduction to WebVR – or How to make your user sick in 60 seconds
An Introduction to WebVR – or How to make your user sick in 60 secondsGeilDanke
 
2016 First steps with Angular 2 – enterjs
2016 First steps with Angular 2 – enterjs2016 First steps with Angular 2 – enterjs
2016 First steps with Angular 2 – enterjsGeilDanke
 
2014 HTML und CSS für Designer – Pubkon
2014 HTML und CSS für Designer – Pubkon2014 HTML und CSS für Designer – Pubkon
2014 HTML und CSS für Designer – PubkonGeilDanke
 
2013 Digitale Magazine erstellen - Konzeption und Redaktion
2013 Digitale Magazine erstellen - Konzeption und Redaktion2013 Digitale Magazine erstellen - Konzeption und Redaktion
2013 Digitale Magazine erstellen - Konzeption und RedaktionGeilDanke
 
2014 Adobe DPS Update 29
2014 Adobe DPS Update 292014 Adobe DPS Update 29
2014 Adobe DPS Update 29GeilDanke
 
2012 Digital Publishing IDUG Stuttgart
2012 Digital Publishing IDUG Stuttgart2012 Digital Publishing IDUG Stuttgart
2012 Digital Publishing IDUG StuttgartGeilDanke
 

Más de GeilDanke (13)

WebXR: A New Dimension For The Web Writing Virtual and Augmented Reality Apps...
WebXR: A New Dimension For The Web Writing Virtual and Augmented Reality Apps...WebXR: A New Dimension For The Web Writing Virtual and Augmented Reality Apps...
WebXR: A New Dimension For The Web Writing Virtual and Augmented Reality Apps...
 
Writing Virtual And Augmented Reality Apps With Web Technology
Writing Virtual And Augmented Reality Apps With Web TechnologyWriting Virtual And Augmented Reality Apps With Web Technology
Writing Virtual And Augmented Reality Apps With Web Technology
 
Creating Augmented Reality Apps with Web Technology
Creating Augmented Reality Apps with Web TechnologyCreating Augmented Reality Apps with Web Technology
Creating Augmented Reality Apps with Web Technology
 
How to Make Your Users Sick in 60 Seconds – About UX Design, WebVR and React VR
How to Make Your Users Sick in 60 Seconds – About UX Design, WebVR and React VRHow to Make Your Users Sick in 60 Seconds – About UX Design, WebVR and React VR
How to Make Your Users Sick in 60 Seconds – About UX Design, WebVR and React VR
 
More Ways to Make Your Users Sick – A talk about WebVR and UX Design
More Ways to Make Your Users Sick – A talk about WebVR and UX DesignMore Ways to Make Your Users Sick – A talk about WebVR and UX Design
More Ways to Make Your Users Sick – A talk about WebVR and UX Design
 
Goodbye, Flatland! An introduction to WebVR and what it means for web developers
Goodbye, Flatland! An introduction to WebVR and what it means for web developersGoodbye, Flatland! An introduction to WebVR and what it means for web developers
Goodbye, Flatland! An introduction to WebVR and what it means for web developers
 
Goodbye, Flatland! An introduction to React VR and what it means for web dev...
Goodbye, Flatland! An introduction to React VR  and what it means for web dev...Goodbye, Flatland! An introduction to React VR  and what it means for web dev...
Goodbye, Flatland! An introduction to React VR and what it means for web dev...
 
An Introduction to WebVR – or How to make your user sick in 60 seconds
An Introduction to WebVR – or How to make your user sick in 60 secondsAn Introduction to WebVR – or How to make your user sick in 60 seconds
An Introduction to WebVR – or How to make your user sick in 60 seconds
 
2016 First steps with Angular 2 – enterjs
2016 First steps with Angular 2 – enterjs2016 First steps with Angular 2 – enterjs
2016 First steps with Angular 2 – enterjs
 
2014 HTML und CSS für Designer – Pubkon
2014 HTML und CSS für Designer – Pubkon2014 HTML und CSS für Designer – Pubkon
2014 HTML und CSS für Designer – Pubkon
 
2013 Digitale Magazine erstellen - Konzeption und Redaktion
2013 Digitale Magazine erstellen - Konzeption und Redaktion2013 Digitale Magazine erstellen - Konzeption und Redaktion
2013 Digitale Magazine erstellen - Konzeption und Redaktion
 
2014 Adobe DPS Update 29
2014 Adobe DPS Update 292014 Adobe DPS Update 29
2014 Adobe DPS Update 29
 
2012 Digital Publishing IDUG Stuttgart
2012 Digital Publishing IDUG Stuttgart2012 Digital Publishing IDUG Stuttgart
2012 Digital Publishing IDUG Stuttgart
 

Último

"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 

Último (20)

"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 

Using New Web APIs For Your Own Pleasure – How I Wrote New Features For My Vibrator using the Web Bluetooth API and the Web Audio API

  • 1. @fischaelameergeildanke.com #webrebels Using Web APIs 
 For Your Own PleasurePleasure
  • 2. What? Why? Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project
  • 3. What? Why? Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project
  • 4. Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project What? Why?
  • 5. Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project What? Why?
  • 6. Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project What? Why?
  • 7. Ahhh Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project What? Why?
  • 8.
  • 9.
  • 10. Web Bluetooth API Support Devices with Bluetooth 4.0 or higher Chrome, Chrome on Android,
 Samsung Internet, Opera Created by Ben Davis from the Noun Project, Created by Viktor Vorobyev from the Noun Project
  • 11. Three Steps to Happiness Write Data via Bluetooth API Connect Bluetooth Device Request Connection Read Audio Data Expose Vowels Uncover Bluetooth Commands
  • 12. Web Bluetooth API Connect to and interact with Bluetooth Low Energy devices.
  • 13. Bluetooth Low Energy Bluetooth LE, BLE, Bluetooth smart
  • 14. Bluetooth Low Energy Support iOS 5+ Android 4.3+ OS X 10.6+ Windows 8+
  • 15. Harald "Blåtand" Gormsson ~958-986 King of Denmark and Norway means Bluetooth
  • 17. Advertising and Discovery Peripheral Device Central Device Frequency Hopping Spread Spectrum (FHSS) short-wavelength radio waves
 ~2.4GHz
  • 19. Advertising as Broadcasting Peripheral Device Central Device Central Device Central Device Central Device Central DeviceCentral Device Advertising Data
  • 20. GATT Generic Attribute Profile Defines the way two Bluetooth LE devices 
 transfer data back and forth 
 using Characteristics and Services.
  • 21. GATT Server GATT 
 Client Communication via GATT sends
 response sends request sends
 response sends request sends reques
  • 22. Profile collection of related services Service collection of related characteristics Parts of GATT Characteristic Characteristic Characteristic read (RX) and write (TX) data
  • 23. Connect Bluetooth Device const LUSH_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e'; button.addEventListener('click', () => { navigator.bluetooth.requestDevice({ filters: [{ services: [LUSH_SERVICE] }] }).then((device) => { console.log('Device found. Device: ', device); return device.gatt.connect(); }).then((server) => { console.log('Device connected. Server ', server); }); });
  • 24. Connect Bluetooth Device const LUSH_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e'; button.addEventListener('click', () => { navigator.bluetooth.requestDevice({ filters: [{ services: [LUSH_SERVICE] }] }).then((device) => { console.log('Device found. Device: ', device); return device.gatt.connect(); }).then((server) => { console.log('Device connected. Server ', server); }); });
  • 25. const LUSH_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e'; button.addEventListener('click', () => { navigator.bluetooth.requestDevice({ filters: [{ services: [LUSH_SERVICE] }] }).then((device) => { console.log('Device found. Device: ', device); return device.gatt.connect(); }).then((server) => { console.log('Device connected. Server ', server); }); }); Connect Bluetooth Device
  • 26. const LUSH_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e'; button.addEventListener('click', () => { navigator.bluetooth.requestDevice({ filters: [{ services: [LUSH_SERVICE] }] }).then((device) => { console.log('Device found. Device: ', device); return device.gatt.connect(); }).then((server) => { console.log('Device connected. Server ', server); }); }); Connect Bluetooth Device
  • 29. const LUSH_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e'; button.addEventListener('click', () => { navigator.bluetooth.requestDevice({ filters: [{ services: [LUSH_SERVICE] }] }).then((device) => { console.log('Device found. Device: ', device); return device.gatt.connect(); }).then((server) => { console.log('Device connected. Server ', server); }); }); Connect Bluetooth Device
  • 30. const LUSH_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e'; button.addEventListener('click', () => { navigator.bluetooth.requestDevice({ filters: [{ services: [LUSH_SERVICE] }] }).then((device) => { console.log('Device found. Device: ', device); return device.gatt.connect(); }).then((server) => { console.log('Device connected. Server ', server); }); }); Connect Bluetooth Device
  • 31.
  • 32. Web Audio API Control audio on the web inside an Audio Context with linked together Audio Nodes that for an Audio Routing Graph.
  • 33. Audio Context Audio Routing Graph Source Node e.g. <audio> output Audio Node Processing Node e.g. reverb input Audio Node output Destination Node e.g. speakers Audio Node input
  • 34. UltrasonicSubsonic 20Hz Sound Frequencies heard by human ears 20kHz What is Sound?
  • 37. How to detect Vowels formants: f1 = ~800hz f2 = ~1600hz https://de.wikipedia.org/wiki/Formant
  • 38. Vowel Detection within the Web AudioContext MediaStreamAudioSourceNode AnalyserNode Create Context and Nodes Connect Nodes MediaStreamAudioSourceNode AnalyserNode Destination
  • 39. Vowel Detection within the Web let audioContext = new window.AudioContext(); let stream = document.getElementById('video').captureStream(); let audioSource = audioContext.createMediaStreamSource(stream); let analyser = audioContext.createAnalyser(); audioSource.connect(analyser); analyser.connect(audioContext.destination);
  • 40. Vowel Detection within the Web let audioContext = new window.AudioContext(); let stream = document.getElementById('video').captureStream(); let audioSource = audioContext.createMediaStreamSource(stream); let analyser = audioContext.createAnalyser(); audioSource.connect(analyser); analyser.connect(audioContext.destination);
  • 41. AnalyserNode Input Node Anaylser Node Output Node UnchangedFast Fourier Transformation Frequency Data
  • 42. AnalyserNode analyser.fftSize = 2048; console.log(analyser.frequencyBinCount); //1024 let dataArray = new Uint8Array(analyser.frequencyBinCount); analyser.getByteFrequencyData(dataArray);
  • 43. AnalyserNode analyser.fftSize = 2048; console.log(analyser.frequencyBinCount); //1024 let dataArray = new Uint8Array(analyser.frequencyBinCount); analyser.getByteFrequencyData(dataArray);
  • 44. AnalyserNode analyser.fftSize = 2048; console.log(analyser.frequencyBinCount); //1024 let dataArray = new Uint8Array(analyser.frequencyBinCount); analyser.getByteFrequencyData(dataArray);
  • 45. AnalyserNode analyser.fftSize = 2048; console.log(analyser.frequencyBinCount); //1024 let dataArray = new Uint8Array(analyser.frequencyBinCount); analyser.getByteFrequencyData(dataArray);
  • 46. Visualize and Analyse Audio let render = function () { analyser.getByteFrequencyData(dataArray); formants = getFormants(dataArray); vowel = formantsToAh(formants[0], formants[1]); window.requestAnimationFrame(render); }; window.requestAnimationFrame(render);
  • 47. Frequency Data decibel = value / 256;Get Decibel frequency = index * 44100 / 2048;Get Frequency audioContext.sampleRate FFT Size
  • 48. Get Formants let getFormants = function (data) { let f1, f2, maxF1 = -Infinity, maxF2 = -Infinity; data.forEach(function (date, i) { let frequency = i * 44100 / 2048, decibel = date / 256; if (frequency < 1000) { if (decibel > maxF1) { maxF1 = decibel; f1 = frequency; } } else if (frequency < 5000) { if (decibel > maxF2) { maxF2 = decibel; f2 = frequency; } } }); return [{ db: maxF1, freq: f1}, { db: maxF2, freq: f2 }]; };
  • 49. Get Formants let getFormants = function (data) { let f1, f2, maxF1 = -Infinity, maxF2 = -Infinity; data.forEach(function (date, i) { let frequency = i * 44100 / 2048, decibel = date / 256; if (frequency < 1000) { if (decibel > maxF1) { maxF1 = decibel; f1 = frequency; } } else if (frequency < 5000) { if (decibel > maxF2) { maxF2 = decibel; f2 = frequency; } } }); return [{ db: maxF1, freq: f1}, { db: maxF2, freq: f2 }]; };
  • 50. Get Formants let getFormants = function (data) { let f1, f2, maxF1 = -Infinity, maxF2 = -Infinity; data.forEach(function (date, i) { let frequency = i * 44100 / 2048, decibel = date / 256; if (frequency < 1000) { if (decibel > maxF1) { maxF1 = decibel; f1 = frequency; } } else if (frequency < 5000) { if (decibel > maxF2) { maxF2 = decibel; f2 = frequency; } } }); return [{ db: maxF1, freq: f1}, { db: maxF2, freq: f2 }]; };
  • 51. Get Formants let getFormants = function (data) { let f1, f2, maxF1 = -Infinity, maxF2 = -Infinity; data.forEach(function (date, i) { let frequency = i * 44100 / 2048, decibel = date / 256; if (frequency < 1000) { if (decibel > maxF1) { maxF1 = decibel; f1 = frequency; } } else if (frequency < 5000) { if (decibel > maxF2) { maxF2 = decibel; f2 = frequency; } } }); return [{ db: maxF1, freq: f1}, { db: maxF2, freq: f2 }]; };
  • 52. Get Formants let getFormants = function (data) { let f1, f2, maxF1 = -Infinity, maxF2 = -Infinity; data.forEach(function (date, i) { let frequency = i * 44100 / 2048, decibel = date / 256; if (frequency < 1000) { if (decibel > maxF1) { maxF1 = decibel; f1 = frequency; } } else if (frequency < 5000) { if (decibel > maxF2) { maxF2 = decibel; f2 = frequency; } } }); return [{ db: maxF1, freq: f1}, { db: maxF2, freq: f2 }]; };
  • 53. Get Vowels let formantsToAh = function (f1, f2) { if (f1.freq > 700 && f1.freq < 1000 && f1.db > 0.4 && f2.freq > 1200 && f2.freq < 1800 && f2.db > 0.2) { return 'a'; } return null; };
  • 54. Real-time Vowel Detection let render = function () { analyser.getByteFrequencyData(dataArray); formants = getFormants(dataArray); vowel = formantsToAh(formants[0], formants[1]); if (vowel === 'a') { console.log('Ah!'); } window.requestAnimationFrame(render); }; Next video: https://www.youtube.com/watch?v=-74Tyi-fvi8
  • 55.
  • 57. Vibrate:4; Identify Bluetooth Commands 56 69 62 72 61 74 65 3a 34 3b
  • 58. Write to a Bluetooth Characteristic const LUSH_TX_CHARACTERISTIC = '6e400002-b5a3-f393-e0a9-e50e24dcca9e'; let txCharacteristic = null; button.addEventListener('click', () => { /* … */ }).then((server) => { return server.getPrimaryService(LUSH_SERVICE); }).then((service) => { return service.getCharacteristic(LUSH_TX_CHARACTERISTIC); }).then((characteristic) => { txCharacteristic = characteristic; }); });
  • 59. const LUSH_TX_CHARACTERISTIC = '6e400002-b5a3-f393-e0a9-e50e24dcca9e'; let txCharacteristic = null; button.addEventListener('click', () => { /* … */ }).then((server) => { return server.getPrimaryService(LUSH_SERVICE); }).then((service) => { return service.getCharacteristic(LUSH_TX_CHARACTERISTIC); }).then((characteristic) => { txCharacteristic = characteristic; }); }); Write to a Bluetooth Characteristic
  • 60.
  • 61. const LUSH_TX_CHARACTERISTIC = '6e400002-b5a3-f393-e0a9-e50e24dcca9e'; let txCharacteristic = null; button.addEventListener('click', () => { /* … */ }).then((server) => { return server.getPrimaryService(LUSH_SERVICE); }).then((service) => { return service.getCharacteristic(LUSH_TX_CHARACTERISTIC); }).then((characteristic) => { txCharacteristic = characteristic; }); }); Write to a Bluetooth Characteristic
  • 62. if (vowel === 'a') { let message = new TextEncoder('ASCII').encode('Vibrate:10;'); txCharacteristic.writeValue(message); } else { let message = new TextEncoder('ASCII').encode('Vibrate:0;'); txCharacteristic.writeValue(message); } Write to a Bluetooth Characteristic
  • 63. if (vowel === 'a') { let message = new TextEncoder('ASCII').encode('Vibrate:10;'); txCharacteristic.writeValue(message); } else { let message = new TextEncoder('ASCII').encode('Vibrate:0;'); txCharacteristic.writeValue(message); } Write to a Bluetooth Characteristic Next video: https://www.youtube.com/watch?v=-74Tyi-fvi8
  • 64.
  • 65. @fischaelameergeildanke.com #webrebels Be Creative! Use More Web APIs, Experiment, Give Feedback