diff --git a/packages/qr-code-scanner/rollup.config.js b/packages/qr-code-scanner/rollup.config.js
index 71dc2688e93aad50a0e9dca45b70ce3a5774a9ae..ea73141b91160c4a47dede33e45a9d83619b5096 100644
--- a/packages/qr-code-scanner/rollup.config.js
+++ b/packages/qr-code-scanner/rollup.config.js
@@ -65,10 +65,6 @@ export default (async () => {
                     {src: 'assets/index.html', dest: 'dist'},
                     {src: 'assets/favicon.ico', dest: 'dist'},
                     {src: await getPackagePath('dbp-common', 'assets/icons/*.svg'), dest: 'dist/local/dbp-common/icons'},
-                    {
-                        src: await getPackagePath('qr-scanner', 'qr-scanner-worker.min.js'),
-                        dest: 'dist/local/dbp-qr-scanner'
-                    },
                 ]
             }),
             (process.env.ROLLUP_WATCH === 'true') ? serve({
diff --git a/packages/qr-code-scanner/src/i18n/de/translation.json b/packages/qr-code-scanner/src/i18n/de/translation.json
index 2c63c0851048d8f7bff41ecf0f8cee05f52fd120..8bc69df6c3cb071f35643ccdcc268a462119c660 100644
--- a/packages/qr-code-scanner/src/i18n/de/translation.json
+++ b/packages/qr-code-scanner/src/i18n/de/translation.json
@@ -1,2 +1,11 @@
 {
+  "no-camera-access": "Zugriff auf Kamera nicht möglich (bitte stellen Sie sicher, dass eine Webcam aktiviert ist)",
+  "finished-scan": "Scannen erfolgreich abgeschlossen.",
+  "loading-video": "Video laden ...",
+  "no-qr-detected": "Kein QR-Code erkannt.",
+  "no-support": "Ihr Gerät unterstützt keine Videoaufnahmen,",
+  "data": "Inhalt",
+  "camera": "Kamera ",
+  "front-camera": "Vordere Kamera",
+  "back-camera": "Rückseitige Kamera"
 }
diff --git a/packages/qr-code-scanner/src/i18n/en/translation.json b/packages/qr-code-scanner/src/i18n/en/translation.json
index 2c63c0851048d8f7bff41ecf0f8cee05f52fd120..a5e8a38078be45d8210ffdd10218e2ae50b708ee 100644
--- a/packages/qr-code-scanner/src/i18n/en/translation.json
+++ b/packages/qr-code-scanner/src/i18n/en/translation.json
@@ -1,2 +1,11 @@
 {
+  "no-camera-access": "Unable to access video stream (please make sure you have a webcam enabled)",
+  "finished-scan": "Finished scanning successfully.",
+  "loading-video": "⌛ Loading video...",
+  "no-qr-detected": "No QR code detected.",
+  "no-support": "Your device does not support video recording.",
+  "data": "Data",
+  "camera": "Camera",
+  "front-camera": "Frontcamera",
+  "back-camera": "Backcamera"
 }
diff --git a/packages/qr-code-scanner/src/qr-code-scanner.js b/packages/qr-code-scanner/src/qr-code-scanner.js
index 7af0131af499ee5685735cb2e964ba740d9e9866..836606b0f325ace53d24fa41382743a28e9fa48e 100644
--- a/packages/qr-code-scanner/src/qr-code-scanner.js
+++ b/packages/qr-code-scanner/src/qr-code-scanner.js
@@ -1,17 +1,18 @@
 import {i18n} from './i18n';
-import {css, html} from 'lit-element';
+import {css, html, LitElement} from 'lit-element';
 import DBPLitElement from 'dbp-common/dbp-lit-element';
 import * as commonStyles from 'dbp-common/styles';
-import {Icon, MiniSpinner} from 'dbp-common';
+import {ScopedElementsMixin} from '@open-wc/scoped-elements';
+import * as commonUtils from 'dbp-common/utils';
+import {Button, Icon, MiniSpinner} from 'dbp-common';
 import {classMap} from 'lit-html/directives/class-map.js';
-import * as commonUtils from "dbp-common/utils";
 import jsQR from "jsqr";
 
 
 /**
  * Notification web component
  */
-export class QrCodeScanner extends DBPLitElement {
+export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) {
     constructor() {
         super();
         this.lang = 'de';
@@ -20,9 +21,11 @@ export class QrCodeScanner extends DBPLitElement {
         this.videoRunning = false;
         this.notSupported = false;
         this.front = false;
+        this.loading = false;
 
         this.scanIsOk = false;
         this.showOutput = false;
+        this.stopScan = false;
     }
 
     static get scopedElements() {
@@ -42,8 +45,10 @@ export class QrCodeScanner extends DBPLitElement {
             videoRunning: { type: Boolean, attribute: false },
             notSupported: { type: Boolean, attribute: false },
             front: { type: Boolean, attribute: false },
+            loading: { type: Boolean, attribute: false },
             scanIsOk: { type: Boolean, attribute: 'scan-is-ok' },
-            showOutput: { type: Boolean, attribute: 'show-output' }
+            showOutput: { type: Boolean, attribute: 'show-output' },
+            stopScan: { type: Boolean, attribute: 'stop-scan' }
         };
     }
 
@@ -53,9 +58,9 @@ export class QrCodeScanner extends DBPLitElement {
         const that = this;
 
         this.updateComplete.then(()=>{
-           let devices_map = new Map();
+            let devices_map = new Map();
 
-           const that = this;
+            const that = this;
 
             navigator.mediaDevices.enumerateDevices()
                 .then(function(devices) {
@@ -66,10 +71,10 @@ export class QrCodeScanner extends DBPLitElement {
                             // TODO Ãœbersetzen
                             let id = device.deviceId;
                             if ( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
-                               devices_map.set('user', 'Frontcamera');
-                               devices_map.set('environment', 'Backcamera');
+                               devices_map.set('user', i18n.t('front-camera'));
+                               devices_map.set('environment', 'back-camera');
                             } else {
-                                devices_map.set(device.deviceId ? device.deviceId : true, device.label || 'camera ' + (devices_map.size + 1));
+                                devices_map.set(id ? id : true, device.label || i18n.t('camera') + (devices_map.size + 1));
                             }
                         }
                     });
@@ -96,6 +101,11 @@ export class QrCodeScanner extends DBPLitElement {
         });
     }
 
+    getLoadingMsg(string) {
+        let loadingMsg = html `<dbp-mini-spinner class="spinner"></dbp-mini-spinner> ${i18n.t(string)}`;
+        return loadingMsg;
+    }
+
     qrCodeScannerInit() {
         this.askPermission = true;
 
@@ -103,11 +113,11 @@ export class QrCodeScanner extends DBPLitElement {
         let canvasElement = this._("#canvas");
         let canvas = canvasElement.getContext("2d");
         let loadingMessage = this._("#loadingMessage");
+        let loadingMessageInner = this._(".loadingMsg");
         let outputContainer = this._("#output");
         let outputMessage = this._("#outputMessage");
         let outputData = this._("#outputData");
 
-
         //TODO
         let color = this.scanIsOk ? getComputedStyle(document.documentElement)
                 .getPropertyValue('--dbp-success-bg-color') : getComputedStyle(document.documentElement)
@@ -124,23 +134,19 @@ export class QrCodeScanner extends DBPLitElement {
         }
 
         const that = this;
-        if ( this._('#videoSource').val === 'user') {
-            this.front = true;
+        let constraint = null;
+        if ( this._('#videoSource').val === 'user' ) {
+            constraint = {facingMode:  {exact: ("user")}};
+        }
+        else if ( this._('#videoSource').val === 'environment' ) {
+            constraint = {facingMode:  {exact: ("environment")}};
         }
-        navigator.mediaDevices.getUserMedia({ video:  { deviceId: this._('#videoSource').val, facingMode: (this.front ? "user" : "environment") } }).then(function(stream) {
+        navigator.mediaDevices.getUserMedia({ video:  { deviceId: this._('#videoSource').val, constraint}}).then(function(stream) {
             video.srcObject = stream;
             video.setAttribute("playsinline", true); // required to tell iOS safari we don't want fullscreen
             video.play();
             that.videoRunning = true;
             requestAnimationFrame(tick);
-
-            const track = stream.getVideoTracks()[0];
-            track.applyConstraints(constraints)
-                .then(() => {
-                    advanced : [{ zoom: 3 }]
-                    // Do something with the track such as using the Image Capture API.
-                })
-
         }).catch((e) => { console.log(e); that.askPermission = true;});
 
         function tick() {
@@ -152,13 +158,25 @@ export class QrCodeScanner extends DBPLitElement {
                     canvasElement.hidden = true;
                     outputContainer.hidden = true;
                 });
-                loadingMessage.innerText = "🎥 Unable to access video stream (please make sure you have a webcam enabled)";
+                loadingMessageInner.innerText = i18n.t('no-camera-access');
                 return;
             }
-
-            loadingMessage.innerText = "⌛ Loading video..."
+            if (that.stopScan) {
+                video.srcObject.getTracks().forEach(function(track) {
+                    track.stop();
+                    console.log("stop early");
+                    loadingMessage.hidden = false;
+                    canvasElement.hidden = true;
+                    outputContainer.hidden = true;
+                });
+                loadingMessageInner.innerText = i18n.t('finished-scan');
+                return;
+            }
+            that.loading = true;
+            loadingMessageInner.innerText = i18n.t('loading-video');
             if (video.readyState === video.HAVE_ENOUGH_DATA) {
                 loadingMessage.hidden = true;
+                that.loading = false;
                 canvasElement.hidden = false;
                 outputContainer.hidden = false;
 
@@ -207,32 +225,58 @@ export class QrCodeScanner extends DBPLitElement {
             ${commonStyles.getButtonCSS()}
             
             #loadingMessage {
-              text-align: center;
-              padding: 40px;
+                text-align: center;
+                padding: 40px;
+            }
+            
+            .wrapper-msg {
+                width: 100%;
+                display: flex;
+                justify-content: center;
+                align-items: baseline;
             }
         
             #canvas {
-              width: 100%;
+                width: 100%;
             }
         
             #output {
-              margin-top: 20px;
-              background: #eee;
-              padding: 10px;
-              padding-bottom: 0;
+                  margin-top: 20px;
+                  background: #eee;
+                  padding: 10px;
+                  padding-bottom: 0;
             }
         
             #output div {
-              padding-bottom: 10px;
-              word-wrap: break-word;
+                  padding-bottom: 10px;
+                  word-wrap: break-word;
             }
         
             #noQRFound {
-              text-align: center;
+                text-align: center;
+            }
+            
+            .spinner{
+                margin-right: 10px;
+                font-size: 0.7em;
+            }
+            
+            #videoSource{
+                padding-bottom: calc(0.375em - 2px);
+                padding-left: 0.75em;
+                padding-right: 1.75em;
+                padding-top: calc(0.375em - 2px);
+                background-position-x: calc(100% - 0.4rem);
+                font-size: inherit;
+            }
+            select:not(.select)#videoSource{
+                background-size: 15%;
             }
             
             .border{
-                border-bottom: 1px solid black;            
+                margin-top: 2rem;
+                padding-top: 2rem;
+                border-top: 1px solid black;
             }
         `;
     }
@@ -245,27 +289,32 @@ export class QrCodeScanner extends DBPLitElement {
             <div class="columns">
                 <div class="column" id="qr">
                     
-                    
                     <div class="${classMap({hidden: this.notSupported})}">
                     
-                        <div class="button-wrapper border">
+                        <div class="button-wrapper">
                             <button class="start button is-primary ${classMap({hidden: this.videoRunning})}" @click="${() => this.qrCodeScannerInit()}">start scanning</button>
                             <button class="stop button is-primary ${classMap({hidden: !this.videoRunning})}" @click="${() => this.stopScanning()}">stop scanning</button>
-                            <span class="select">
-                                <select id="videoSource"></select>
-                            </span>
+                            
+                            <select id="videoSource"></select>
+
                         </div>
-                        <div id="loadingMessage" class="${classMap({hidden: !this.askPermission})}">🎥 Unable to access video stream (please make sure you have a webcam enabled)</div>
-                        <canvas id="canvas" hidden></canvas>
+                       
+                        <div id="loadingMessage" class="border ${classMap({hidden: !this.askPermission})}">
+                            <div class="wrapper-msg">
+                                <dbp-mini-spinner class="spinner ${classMap({hidden: !this.loading})}"></dbp-mini-spinner>
+                                <div class="loadingMsg">${i18n.t('no-camera-access')}</div>
+                            </div>
+                       </div>
+                       <canvas id="canvas" hidden class="border"></canvas>
                         
                        
-                        <div id="output" hidden class="${classMap({hidden: !this.showOutput})}">
-                           <div id="outputMessage">No QR code detected.</div>
-                           <div hidden><b>Data:</b> <span id="outputData"></span></div>
+                        <div id="output" hidden class="border ${classMap({hidden: !this.showOutput})}">
+                           <div id="outputMessage">${i18n.t('no-qr-detectede')}</div>
+                           <div hidden><b>${i18n.t('data')}:</b> <span id="outputData"></span></div>
                         </div>
                     </div>
-                    <div class="${classMap({hidden: !this.notSupported})}">
-                        Ihr device unterstützt keine video aufnahmen
+                    <div class="border ${classMap({hidden: !this.notSupported})}">
+                        ${i18n.t('no-support')}
                     </div>
                 </div>
             </div>