diff --git a/package.json b/package.json
index de75c506c4e599fadf047bc6e6f588e9a39c5a2d..fabfffc6f99b4a325a5fa5c0fe912c37b72f16fd 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,6 @@
     "filetransfer": "^2.0.4",
     "localmedia": "^4.0.0",
     "rtcpeerconnection": "^8.0.0",
-    "webrtcsupport": "^2.2.0",
     "wildemitter": "^1.2.0",
     "socket.io-client": "1.3.7",
     "attachmediastream": "^2.0.0",
diff --git a/src/liowebrtc.js b/src/liowebrtc.js
index 9b24ba57255b700f5f5c0d4053dba695063baee6..e27620747753da09415a4a5def3d713dd1952d8a 100644
--- a/src/liowebrtc.js
+++ b/src/liowebrtc.js
@@ -54,7 +54,8 @@ class LioWebRTC extends WildEmitter {
       this.config[o] = options[o];
     });
 
-    if (this.config.dataOnly) {
+    if (options.dataOnly) {
+      console.log('data only');
       this.config.media.video = false;
       this.config.media.audio = false;
     }
diff --git a/src/localmedia.js b/src/localmedia.js
new file mode 100644
index 0000000000000000000000000000000000000000..c271ea69a488554da0a55443697cc1fdfdbdb740
--- /dev/null
+++ b/src/localmedia.js
@@ -0,0 +1,329 @@
+import util from 'util';
+import hark from 'hark';
+import getScreenMedia from 'getscreenmedia';
+import WildEmitter from 'wildemitter';
+import mockconsole from 'mockconsole';
+
+function isAllTracksEnded(stream) {
+    let isAllTracksEnded = true;
+    stream.getTracks().forEach(t => {
+        isAllTracksEnded = t.readyState === 'ended' && isAllTracksEnded;
+    });
+    return isAllTracksEnded;
+}
+
+function shouldWorkAroundFirefoxStopStream() {
+  if (typeof window === 'undefined') {
+    return false;
+  }
+  if (!window.navigator.mozGetUserMedia) {
+    return false;
+  }
+  const match = window.navigator.userAgent.match(/Firefox\/(\d+)\./);
+  const version = match && match.length >= 1 && parseInt(match[1], 10);
+  return version < 50;
+}
+
+class LocalMedia extends WildEmitter {
+  constructor(opts) {
+    super();
+    const config = this.config = {
+        detectSpeakingEvents: false,
+        audioFallback: false,
+        media: {
+            audio: true,
+            video: true
+        },
+        harkOptions: null,
+        logger: mockconsole
+    };
+
+    let item;
+    for (item in opts) {
+        if (opts.hasOwnProperty(item)) {
+            this.config[item] = opts[item];
+        }
+    }
+
+    this.logger = config.logger;
+    this._log = this.logger.log.bind(this.logger, 'LocalMedia:');
+    this._logerror = this.logger.error.bind(this.logger, 'LocalMedia:');
+
+    this.localStreams = [];
+    this.localScreens = [];
+
+    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
+        this._logerror('Your browser does not support local media capture.');
+    }
+
+    this._audioMonitors = [];
+    this.on('localStreamStopped', this._stopAudioMonitor.bind(this));
+    this.on('localScreenStopped', this._stopAudioMonitor.bind(this));
+  }
+
+  start(mediaConstraints, cb) {
+      const self = this;
+      const constraints = mediaConstraints || this.config.media;
+
+      this.emit('localStreamRequested', constraints);
+
+      navigator.mediaDevices.getUserMedia(constraints).then(stream => {
+          if (constraints.audio && self.config.detectSpeakingEvents) {
+              self._setupAudioMonitor(stream, self.config.harkOptions);
+          }
+          self.localStreams.push(stream);
+
+          stream.getTracks().forEach(track => {
+              track.addEventListener('ended', () => {
+                  if (isAllTracksEnded(stream)) {
+                      self._removeStream(stream);
+                  }
+              });
+          });
+
+          self.emit('localStream', stream);
+
+          if (cb) {
+              return cb(null, stream);
+          }
+      }).catch(err => {
+              // Fallback for users without a camera
+              if (self.config.audioFallback && err.name === 'NotFoundError' && constraints.video !== false) {
+                  constraints.video = false;
+                  self.start(constraints, cb);
+                  return;
+              }
+
+          self.emit('localStreamRequestFailed', constraints);
+
+          if (cb) {
+              return cb(err, null);
+          }
+      });
+  }
+
+  stop(stream) {
+      this.stopStream(stream);
+      this.stopScreenShare(stream);
+  }
+
+  stopStream(stream) {
+      const self = this;
+
+      if (stream) {
+          const idx = this.localStreams.indexOf(stream);
+          if (idx > -1) {
+              stream.getTracks().forEach(track => { track.stop(); });
+
+              //Half-working fix for Firefox, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1208373
+              if (shouldWorkAroundFirefoxStopStream()) {
+                  this._removeStream(stream);
+              }
+          }
+      } else {
+          this.localStreams.forEach(stream => {
+              stream.getTracks().forEach(track => { track.stop(); });
+
+              //Half-working fix for Firefox, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1208373
+              if (shouldWorkAroundFirefoxStopStream()) {
+                  self._removeStream(stream);
+              }
+          });
+      }
+  }
+
+  startScreenShare(constraints, cb) {
+      const self = this;
+
+      this.emit('localScreenRequested');
+
+      if (typeof constraints === 'function' && !cb) {
+          cb = constraints;
+          constraints = null;
+      }
+
+      getScreenMedia(constraints, (err, stream) => {
+          if (!err) {
+              self.localScreens.push(stream);
+
+              stream.getTracks().forEach(track => {
+                  track.addEventListener('ended', () => {
+                      let isAllTracksEnded = true;
+                      stream.getTracks().forEach(t => {
+                          isAllTracksEnded = t.readyState === 'ended' && isAllTracksEnded;
+                      });
+
+                      if (isAllTracksEnded) {
+                          self._removeStream(stream);
+                      }
+                  });
+              });
+
+              self.emit('localScreen', stream);
+          } else {
+              self.emit('localScreenRequestFailed');
+          }
+
+          // enable the callback
+          if (cb) {
+              return cb(err, stream);
+          }
+      });
+  }
+
+  stopScreenShare(stream) {
+      const self = this;
+
+      if (stream) {
+          const idx = this.localScreens.indexOf(stream);
+          if (idx > -1) {
+              stream.getTracks().forEach(track => { track.stop(); });
+
+              //Half-working fix for Firefox, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1208373
+              if (shouldWorkAroundFirefoxStopStream()) {
+                  this._removeStream(stream);
+              }
+          }
+      } else {
+          this.localScreens.forEach(stream => {
+              stream.getTracks().forEach(track => { track.stop(); });
+
+              //Half-working fix for Firefox, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1208373
+              if (shouldWorkAroundFirefoxStopStream()) {
+                  self._removeStream(stream);
+              }
+          });
+      }
+  }
+
+  // Audio controls
+  mute() {
+      this._audioEnabled(false);
+      this.emit('audioOff');
+  }
+
+  unmute() {
+      this._audioEnabled(true);
+      this.emit('audioOn');
+  }
+
+  // Video controls
+  pauseVideo() {
+      this._videoEnabled(false);
+      this.emit('videoOff');
+  }
+
+  resumeVideo() {
+      this._videoEnabled(true);
+      this.emit('videoOn');
+  }
+
+  // Combined controls
+  pause() {
+      this.mute();
+      this.pauseVideo();
+  }
+
+  resume() {
+      this.unmute();
+      this.resumeVideo();
+  }
+
+  // Internal methods for enabling/disabling audio/video
+  _audioEnabled(bool) {
+      this.localStreams.forEach(stream => {
+          stream.getAudioTracks().forEach(track => {
+              track.enabled = !!bool;
+          });
+      });
+  }
+
+  _videoEnabled(bool) {
+      this.localStreams.forEach(stream => {
+          stream.getVideoTracks().forEach(track => {
+              track.enabled = !!bool;
+          });
+      });
+  }
+
+  // check if all audio streams are enabled
+  isAudioEnabled() {
+      let enabled = true;
+      this.localStreams.forEach(stream => {
+          stream.getAudioTracks().forEach(track => {
+              enabled = enabled && track.enabled;
+          });
+      });
+      return enabled;
+  }
+
+  // check if all video streams are enabled
+  isVideoEnabled() {
+      let enabled = true;
+      this.localStreams.forEach(stream => {
+          stream.getVideoTracks().forEach(track => {
+              enabled = enabled && track.enabled;
+          });
+      });
+      return enabled;
+  }
+
+  _removeStream(stream) {
+      let idx = this.localStreams.indexOf(stream);
+      if (idx > -1) {
+          this.localStreams.splice(idx, 1);
+          this.emit('localStreamStopped', stream);
+      } else {
+          idx = this.localScreens.indexOf(stream);
+          if (idx > -1) {
+              this.localScreens.splice(idx, 1);
+              this.emit('localScreenStopped', stream);
+          }
+      }
+  }
+
+  _setupAudioMonitor(stream, harkOptions) {
+      this._log('Setup audio');
+      const audio = hark(stream, harkOptions);
+      const self = this;
+      let timeout;
+
+      audio.on('speaking', () => {
+          self.emit('speaking');
+      });
+
+      audio.on('stopped_speaking', () => {
+          if (timeout) {
+              clearTimeout(timeout);
+          }
+
+          timeout = setTimeout(() => {
+              self.emit('stoppedSpeaking');
+          }, 1000);
+      });
+      audio.on('volume_change', (volume, threshold) => {
+          self.emit('volumeChange', volume, threshold);
+      });
+
+      this._audioMonitors.push({audio, stream});
+  }
+
+  _stopAudioMonitor(stream) {
+      let idx = -1;
+      this._audioMonitors.forEach((monitors, i) => {
+          if (monitors.stream === stream) {
+              idx = i;
+          }
+      });
+
+      if (idx > -1) {
+          this._audioMonitors[idx].audio.stop();
+          this._audioMonitors.splice(idx, 1);
+      }
+  }
+}
+
+util.inherits(LocalMedia, WildEmitter);
+
+
+export default LocalMedia;
diff --git a/src/webrtc.js b/src/webrtc.js
index c34d4e85fb307937cf8869e7ca37e17eb6b66dc9..970339a90d27ceafce4ff1810333f0f1b5d115a6 100644
--- a/src/webrtc.js
+++ b/src/webrtc.js
@@ -1,11 +1,12 @@
 import util from 'util';
 import mockconsole from 'mockconsole';
-import localMedia from 'localmedia';
+import LocalMedia from './localmedia';
 import Peer from './peer';
 import webrtcSupport from './webrtcsupport';
 
-class WebRTC {
+class WebRTC extends LocalMedia {
   constructor(opts) {
+    super(opts);
     const self = this;
     const options = opts || {};
     const config = this.config = {
@@ -52,7 +53,7 @@ class WebRTC {
     this.peers = [];
 
       // call localMedia constructor
-    localMedia.call(this, this.config);
+    // localMedia.call(this, this.config);
 
     this.on('speaking', () => {
       if (!self.hardMuted) {
@@ -150,6 +151,4 @@ class WebRTC {
   }
 }
 
-util.inherits(WebRTC, localMedia);
-
 export default WebRTC;