This solution is a bit of a workaround as it relies on the browser revealing the label
attribute of the MediaDevice
and making assumptions based on the presence of the string "head"
to determine if a headphone device is connected. Alternatively, you could monitor the number of connected audio devices and implement actions accordingly based on your specific needs.
Most of the logic used here was inspired by information found on the MDN page for navigator.mediaDevices.ondevicechange
.
IMPORTANT: Please note that this code may not function correctly when run from a file://
URL; instead, access it through an http://
or https://
URL to allow the browser to retrieve the label
property of the MediaDevice
. Additionally, depending on the browser being used, you might need to employ the workaround mentioned in the initial version of this answer (link) which prompts the user for microphone access to grant permission for accessing the label
property.
// Assume no headphones are currently connected
let headphonesConnected = false;
const updateDevices = () => {
navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
// Check for any devices with "head" in their names (e.g., "headset", "headphones")
headphonesConnected = devices
.filter(device => /audio\w+/.test(device.kind))
.find(device => device.label.toLowerCase().includes('head'))
;
})
;
};
updateDevices();
// Listen for changes in device connections
navigator.mediaDevices.ondevicechange = updateDevices;
NOTE: While testing has yielded mixed results with this simplified version, it eliminates the requirement for microphone access. Keep in mind that certain browsers may have varying delays in triggering the ondevicechange
event handler.