A JavaScript version of the Bose Frames SDK
A JavaScript SDK for Bose AR-enabled products, including the Bose Frames, Bose QuietComfort 35 Wireless II, and Bose 700 Wireless . Click here for a Live Demo!
π Enabling and Disabling Sensors
π Enabling and Disabling Gestures
Make sure you have a Web Bluetooth-enabled device
chrome://flags/#enable-experimental-web-platform-features
and check Experimental Web Platform features
Update your Bose AR-enabled headset's firmware on their website
Disconnect your Bose AR-enabled from your smartphone if you have the Bose Connect App installed.
Save a local copy of bose-ar-web-sdk.min.js
In your HTML <head></head>
element, insert the file in a script element:
<script src="bose-ar-web-sdk.min.js"></script>
<body></body>
element, insert the following custom element:<bose-ar-device></bose-ar-device>
This element represents your Bose AR-enabled device, and will be used to interface with it. On your website the element will display a πΆοΈ
button that will attempt to connect with your Bose AR-enabled device when clicked, and become hidden once connected.
NOTE: Bose AR devices have 2 types of Bluetooth Connections: an Audio connection (audio playback and microphone controls) and an AR connection (head-tracking and gestures). This SDK is used to establish an AR connection and will allow you to enable/disable sensors/gestures, as well as access the sensor/gesture data. If you want to access the Bose AR device as an audio device (like normal bluetooth headphones and headsets), you'll need to connect to it again "the usual way" and use the standard Web Audio API.
ALSO NOTE: You can connect to multiple Bose AR devices (as an AR device) simultaneously, as well as have a single Bose AR device be accessed from multiple browsers (e.g. your smartphone and laptop). However, disabling a Bose AR's sensor/gesture from one browser disables it for any browser observing the Bose AR device's sensors/gestures.
ALSO ALSO NOTE: The browser needs permission from the user to connect to the Bose AR device (as an AR device as mentioned in the first "NOTE"), but no action on the Bose AR device is needed (e.g. pressing a "connect" button on the Bose AR device). This means anyone can access an unassuming user's Bose AR device from their browser and enable/disable/read sensor/gesture data without the Bose AR device owner even knowing. I'm not sure why they designed them this way, but I don't work there.
π To enable sensors before runtime, add them as attributes in the custom element, with an attribute value indicating the refresh rate (in milliseconds or as a string):
<bose-ar-device gyroscope=20 rotation="fast"></bose-ar-device>
π To enable sensors during runtime, set the custom element's attribute:
document.querySelector("bose-ar-device").setAttribute("rotation", "fast");
π To disable sensors during runtime, remove the custom element's attribute:
document.querySelector("bose-ar-device").removeAttribute("rotation");
π Valid sensor attributes:
accelerometer
gyroscope
rotation
game-rotation
β²οΈ Valid sensor attribute values:
20
or "very-fast"
40
or "fast"
80
or "normal"
160
or "slow"
320
or "very-slow"
π To enable gestures before runtime, add them as attributes in the custom element:
<bose-ar-device double-tap head-nod head-shake></bose-ar-device>
π To enable gestures during runtime, set the custom element's attribute:
document.querySelector("bose-ar-device").setAttribute("double-tap", '');
π To disable gestures during runtime, remove the custom element's attribute:
document.querySelector("bose-ar-device").removeAttribute("double-tap");
π Valid gesture attributes:
single-tap
double-tap
head-nod
head-shake
eventListener
to the custom element:document.querySelector("bose-ar-device").addEventListener("accelerometer", yourCustomCallback);
π Valid event names:
"accelerometer"
"gyroscope"
"rotation"
"gameRotation"
(coming soon)"singleTap"
doubleTap
"headNod"
"headShake"
To get the event data, you can get it from the custom element's attributes:
document.querySelector("bose-ar-device").addEventListener("accelerometer", event => {
const rotationX = Number(document.querySelector("bose-ar-device").getAttribute("rotationX"));
});
π Valid attributes for events:
"accelerometer"
"accelerometerX"
"accelerometerY"
"accelerometerZ"
"accelerometerTimestamp"
"gyroscope"
"gyroscopeX"
"gyroscopeY"
"gyroscopeZ"
"gyroscopeTimestamp"
"rotation"
"rotationW"
"rotationX"
"rotationY"
"rotationZ"
"rotationYaw"
"rotationPitch"
"rotationRoll"
"rotationTimestamp"
"gameRotation"
"gameRotationW"
"gameRotationX"
"gameRotationY"
"gameRotationZ"
"gameRotationYaw"
"gameRotationPitch"
"gameRotationRoll"
"gameRotationTimestamp"
"singleTap"
"singleTapTimestamp"
"headNod"
"headNodTimestamp"
"headShake"
"headShakeTimestamp"
Send us an email at [email protected] if you have a cool application made with our sdk!
injection.js
by the window.boseARDeviceElement.connect();
methodpopup.html
popup.js
, using sendMessage(message)
to forward the event to the current website you're on. This message should include a case
property value to specify the purpose of the message. myButton.addEventListener("click", event => {
const myMessage = {
case : "myCase",
};
sendMessage(myMessage);
});
case
string to the switch(event.data.case){}
block in injection.js
, which will receive the message
object created in the previous step. Here you can define your custom behavior, using both the message case and any extra values you passed in the message
object.chrome://extensions/
, clicking Load unpacked
, and selecting your edited extension
folder.manifest.json
and changing the name
property.icon.png
with your own image.Prefer Cycling '74's Max? Now you can use as many Bose AR devices as you want in a Max Patch using Node for Max via WebSockets!
bose-for-max
folderbose-for-max.maxpat
in Max (Max 8 is required for Node for Max.
localhost:3000
to connect your BoseAR device via the WebSDK (the top of the webpage will display the socket connection index to distinguish multiple devices in the Patch)Bose AR Device #
, and change the # to indicate other devices via their socket connection index (shown at the top of the web page)Our time is limited, so we'd greatly appreciate it if you guys could implement some of these ideas: