diff --git a/CHANGELOG b/CHANGELOG
index d9d896035c752ba4680a1ff268dd2178e8dfb854..2f6cbe48bca3afd1cc77de5dd01a7d77f660ef12 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,6 +8,7 @@ Changelog
 - Shortcuts: can now use the ``f`` shortcut to toggle the currently playing track
   as a favorite (#53)
 - Shortcuts: avoid collisions between shortcuts by using the exact modifier (#53)
+- Player: Added looping controls and shortcuts (#52)
 
 
 0.2.6 (2017-12-15)
diff --git a/front/src/audio/queue.js b/front/src/audio/queue.js
index 8c69638e80ceb46adfdd182010ced55898b6850f..bb3f0f9055fafa10deac458b7806d9f857ef1a8f 100644
--- a/front/src/audio/queue.js
+++ b/front/src/audio/queue.js
@@ -17,6 +17,7 @@ class Queue {
     this.currentTrack = null
     this.ended = true
     this.state = {
+      looping: 0, // 0 -> no, 1 -> on  track, 2 -> on queue
       volume: cache.get('volume', 0.5)
     }
     this.audio = {
@@ -267,12 +268,22 @@ class Queue {
 
   handleAudioEnded (e) {
     this.recordListen(this.currentTrack)
+    if (this.state.looping === 1) {
+      // we loop on the same track
+      logger.default.info('Looping on the same track')
+      return this.play(this.currentIndex)
+    }
     if (this.currentIndex < this.tracks.length - 1) {
       logger.default.info('Audio track ended, playing next one')
-      this.next()
+      return this.next()
     } else {
       logger.default.info('We reached the end of the queue')
-      this.ended = true
+      if (this.state.looping === 2) {
+        logger.default.info('Going back to the beginning of the queue')
+        return this.play(0)
+      } else {
+        this.ended = true
+      }
     }
   }
 
@@ -297,6 +308,14 @@ class Queue {
     }
   }
 
+  toggleLooping () {
+    if (this.state.looping > 1) {
+      this.state.looping = 0
+    } else {
+      this.state.looping += 1
+    }
+  }
+
 }
 
 let queue = new Queue()
diff --git a/front/src/components/audio/Player.vue b/front/src/components/audio/Player.vue
index aff3e65bd5bc0999b16c15874f04e22b5bf9b166..8cdb261c535023f50dc218b1712aeb3b099489d2 100644
--- a/front/src/components/audio/Player.vue
+++ b/front/src/components/audio/Player.vue
@@ -39,21 +39,71 @@
       </div>
     </div>
 
-    <div class="controls ui grid">
-      <div class="volume-control four wide center aligned column">
-        <input type="range" step="0.05" min="0" max="1" v-model="sliderVolume" />
+    <div class="two wide column controls ui grid">
+      <div
+        @click="queue.previous()"
+        title="Previous track"
+        class="two wide column control"
+        :disabled="!hasPrevious">
+          <i :class="['ui', {'disabled': !hasPrevious}, 'step', 'backward', 'big', 'icon']" ></i>
+      </div>
+      <div
+        v-if="!queue.audio.state.playing"
+        @click="pauseOrPlay"
+        title="Play track"
+        class="two wide column control">
+          <i :class="['ui', 'play', {'disabled': !queue.currentTrack}, 'big', 'icon']"></i>
+      </div>
+      <div
+        v-else
+        @click="pauseOrPlay"
+        title="Pause track"
+        class="two wide column control">
+          <i :class="['ui', 'pause', {'disabled': !queue.currentTrack}, 'big', 'icon']"></i>
+      </div>
+      <div
+        @click="queue.next()"
+        title="Next track"
+        class="two wide column control"
+        :disabled="!hasNext">
+          <i :class="['ui', {'disabled': !hasPrevious}, 'step', 'forward', 'big', 'icon']" ></i>
+      </div>
+      <div class="two wide column control volume-control">
         <i title="Unmute" @click="queue.setVolume(1)" v-if="currentVolume === 0" class="volume off secondary icon"></i>
         <i title="Mute" @click="queue.setVolume(0)" v-else-if="currentVolume < 0.5" class="volume down secondary icon"></i>
         <i title="Mute" @click="queue.setVolume(0)" v-else class="volume up secondary icon"></i>
+        <input type="range" step="0.05" min="0" max="1" v-model="sliderVolume" />
       </div>
-      <div class="eight wide center aligned column">
-        <i title="Previous track" @click="queue.previous()" :class="['ui', {'disabled': !hasPrevious}, 'step', 'backward', 'big', 'icon']" :disabled="!hasPrevious"></i>
-        <i title="Play track" v-if="!queue.audio.state.playing" :class="['ui', 'play', {'disabled': !queue.currentTrack}, 'big', 'icon']" @click="pauseOrPlay"></i>
-        <i title="Pause track" v-else :class="['ui', 'pause', {'disabled': !queue.currentTrack}, 'big', 'icon']" @click="pauseOrPlay"></i>
-        <i title="Next track" @click="queue.next()" :class="['ui', 'step', 'forward', {'disabled': !hasNext}, 'big', 'icon']" :disabled="!hasNext"></i>
+      <div class="two wide column control looping">
+        <i
+          title="Looping disabled. Click to switch to single-track looping."
+          v-if="queue.state.looping === 0"
+          @click="queue.state.looping = 1"
+          :disabled="!queue.currentTrack"
+          :class="['ui', {'disabled': !queue.currentTrack}, 'step', 'repeat', 'secondary', 'icon']"></i>
+        <i
+          title="Looping on a single track. Click to switch to whole queue looping."
+          v-if="queue.state.looping === 1"
+          @click="queue.state.looping = 2"
+          :disabled="!queue.currentTrack"
+          class="repeat secondary icon">
+          <span class="ui circular tiny orange label">1</span>
+        </i>
+        <i
+          title="Looping on whole queue. Click to disable looping."
+          v-if="queue.state.looping === 2"
+          @click="queue.state.looping = 0"
+          :disabled="!queue.currentTrack"
+          class="repeat orange secondary icon">
+        </i>
       </div>
-      <div class="four wide center aligned column">
-        <i title="Clear your queue" @click="queue.clean()" :class="['ui', 'trash', 'secondary', {'disabled': queue.tracks.length === 0}, 'icon']" :disabled="queue.tracks.length === 0"></i>
+      <div class="three wide column"></div>
+      <div
+        @click="queue.clean()"
+        :disabled="queue.tracks.length === 0"
+        title="Clear your queue"
+        class="two wide column control">
+        <i :class="['ui', 'trash', 'secondary', {'disabled': queue.tracks.length === 0}, 'icon']" ></i>
       </div>
     </div>
     <GlobalEvents
@@ -63,6 +113,7 @@
       @keydown.ctrl.down.prevent.exact="queue.incrementVolume(-0.1)"
       @keydown.ctrl.up.prevent.exact="queue.incrementVolume(0.1)"
       @keydown.f.prevent.exact="favoriteTracks.toggle(queue.currentTrack.id)"
+      @keydown.l.prevent.exact="queue.toggleLooping"
       />
 
   </div>
@@ -187,14 +238,32 @@ export default {
 .volume-control {
   position: relative;
   .icon {
-    margin: 0;
+    // margin: 0;
   }
   [type="range"] {
-    max-width: 75%;
+    max-width: 100%;
     position: absolute;
     bottom: 5px;
     left: 10%;
     cursor: pointer;
+    display: none;
+  }
+  &:hover {
+    [type="range"] {
+      display: block;
+    }
+  }
+}
+
+.looping.control {
+  i {
+    position: relative;
+  }
+  .label {
+    position: absolute;
+    font-size: 0.7rem;
+    bottom: -0.7rem;
+    right: -0.7rem;
   }
 }
 .ui.feed.icon {