SlideShare ist ein Scribd-Unternehmen logo
1 von 66
Downloaden Sie, um offline zu lesen
@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

Weitere ähnliche Inhalte

Was ist angesagt?

Python chapter 2
Python chapter 2Python chapter 2
Python chapter 2
Raghu nath
 
python chapter 1
python chapter 1python chapter 1
python chapter 1
Raghu nath
 
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
Eleanor McHugh
 
Código fuente del software educativo
Código fuente del software educativoCódigo fuente del software educativo
Código fuente del software educativo
Leo Chavez Martinez
 

Was ist angesagt? (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
 

Ähnlich wie 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

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
Jussi Pohjolainen
 

Ähnlich wie 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
 

Mehr von GeilDanke

Mehr von 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
 

Kürzlich hochgeladen

+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...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Kürzlich hochgeladen (20)

+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...
 
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
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
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...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
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...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
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...
 

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