diff --git a/src/media/audio/coreaudio/osx/corelayer.h b/src/media/audio/coreaudio/osx/corelayer.h
index f5c7ba339f0b4d2e2921984318a76b59188c2f64..79aaed596d763dbc1eed9c80a5ef5b003838226b 100644
--- a/src/media/audio/coreaudio/osx/corelayer.h
+++ b/src/media/audio/coreaudio/osx/corelayer.h
@@ -125,6 +125,10 @@ private:
                                           UInt32 inNumberAddresses,
                                           const AudioObjectPropertyAddress inAddresses[],
                                           void* inRefCon);
+    static OSStatus devicesChangedCallback(AudioObjectID inObjectID,
+                                           UInt32 inNumberAddresses,
+                                           const AudioObjectPropertyAddress inAddresses[],
+                                           void* inRefCon);
 
     void read(AudioUnitRenderActionFlags* ioActionFlags,
               const AudioTimeStamp* inTimeStamp,
diff --git a/src/media/audio/coreaudio/osx/corelayer.mm b/src/media/audio/coreaudio/osx/corelayer.mm
index fc91bd1e7c7f7b3637bf60760cc9c432e66c14d8..0240029478e4cb3b3e93ea1d3099d914f16ab29a 100644
--- a/src/media/audio/coreaudio/osx/corelayer.mm
+++ b/src/media/audio/coreaudio/osx/corelayer.mm
@@ -175,6 +175,7 @@ CoreLayer::initAudioLayerIO(AudioDeviceType stream)
                                                  &size,
                                                  &playbackDeviceID);
     }
+
     // add listener for detecting when devices are removed
     const AudioObjectPropertyAddress aliveAddress = {kAudioDevicePropertyDeviceIsAlive,
                                                      kAudioObjectPropertyScopeGlobal,
@@ -182,6 +183,12 @@ CoreLayer::initAudioLayerIO(AudioDeviceType stream)
     AudioObjectAddPropertyListener(playbackDeviceID, &aliveAddress, &deviceIsAliveCallback, this);
     AudioObjectAddPropertyListener(inputDeviceID, &aliveAddress, &deviceIsAliveCallback, this);
 
+    // add listener to detect when devices changed
+    const AudioObjectPropertyAddress changedAddress = {kAudioHardwarePropertyDevices,
+                                                     kAudioObjectPropertyScopeGlobal,
+                                                     kAudioObjectPropertyElementMaster};
+    AudioObjectAddPropertyListener(kAudioObjectSystemObject, &changedAddress, &devicesChangedCallback, this);
+
     // Set stream format
     AudioStreamBasicDescription info;
     size = sizeof(info);
@@ -360,6 +367,18 @@ CoreLayer::deviceIsAliveCallback(AudioObjectID inObjectID,
     return kAudioServicesNoError;
 }
 
+OSStatus
+CoreLayer::devicesChangedCallback(AudioObjectID inObjectID,
+                                 UInt32 inNumberAddresses,
+                                 const AudioObjectPropertyAddress inAddresses[],
+                                 void* inRefCon)
+{
+    if (static_cast<CoreLayer*>(inRefCon)->status_ != Status::Started)
+        return kAudioServicesNoError;
+    static_cast<CoreLayer*>(inRefCon)->devicesChanged();
+    return kAudioServicesNoError;
+}
+
 OSStatus
 CoreLayer::outputCallback(void* inRefCon,
                           AudioUnitRenderActionFlags* ioActionFlags,