Commit f06295a5 authored by Eliot Berriot's avatar Eliot Berriot 💬

Fix #586: The progress bar in the player now display loading state / buffer loading

parent c3fece42
The progress bar in the player now display loading state / buffer loading (#586)
......@@ -51,7 +51,11 @@
<p class="timer total">{{durationFormatted}}</p>
</div>
</div>
<div ref="progress" class="ui small orange inverted progress" @click="touchProgress">
<div
ref="progress"
:class="['ui', 'small', 'orange', 'inverted', {'indicating': isLoadingAudio}, 'progress']"
@click="touchProgress">
<div class="buffer bar" :data-percent="bufferProgress" :style="{ 'width': bufferProgress + '%' }"></div>
<div class="bar" :data-percent="progress" :style="{ 'width': progress + '%' }"></div>
</div>
</div>
......@@ -301,9 +305,11 @@ export default {
...mapState({
currentIndex: state => state.queue.currentIndex,
playing: state => state.player.playing,
isLoadingAudio: state => state.player.isLoadingAudio,
volume: state => state.player.volume,
looping: state => state.player.looping,
duration: state => state.player.duration,
bufferProgress: state => state.player.bufferProgress,
queue: state => state.queue
}),
...mapGetters({
......@@ -522,4 +528,43 @@ export default {
margin: 0;
}
@keyframes MOVE-BG {
from {
transform: translateX(0px);
}
to {
transform: translateX(46px);
}
}
.indicating.progress {
overflow: hidden;
}
.ui.progress .bar {
transition: none;
}
.ui.inverted.progress .buffer.bar {
position: absolute;
background-color:rgba(255, 255, 255, 0.15);
}
.indicating.progress .bar {
left: -46px;
width: 200% !important;
color: grey;
background: repeating-linear-gradient(
-55deg,
grey 1px,
grey 10px,
transparent 10px,
transparent 20px,
) !important;
animation-name: MOVE-BG;
animation-duration: 2s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
</style>
......@@ -44,11 +44,17 @@ export default {
}
},
onload: function () {
self.$store.commit('player/isLoadingAudio', false)
self.$store.commit('player/resetErrorCount')
self.$store.commit('player/duration', self.sound.duration())
let node = self.sound._sounds[0]._node;
node.addEventListener('progress', () => {
self.updateBuffer(node)
})
}
})
if (this.autoplay) {
self.$store.commit('player/isLoadingAudio', true)
this.sound.play()
this.$store.commit('player/playing', true)
this.observeProgress(true)
......@@ -91,10 +97,40 @@ export default {
}
},
methods: {
updateBuffer (node) {
// from https://github.com/goldfire/howler.js/issues/752#issuecomment-372083163
let range = 0;
let bf = node.buffered;
let time = node.currentTime;
try {
while(!(bf.start(range) <= time && time <= bf.end(range))) {
range += 1;
}
} catch (IndexSizeError) {
return
}
let loadPercentage
let start = bf.start(range)
let end = bf.end(range)
if (range === 0) {
// easy case, no user-seek
let loadStartPercentage = start / node.duration;
let loadEndPercentage = end / node.duration;
loadPercentage = loadEndPercentage - loadStartPercentage;
} else {
let loaded = end - start
let remainingToLoad = node.duration - start
// user seeked a specific position in the audio, our progress must be
// computed based on the remaining portion of the track
loadPercentage = loaded / remainingToLoad;
}
this.$store.commit('player/bufferProgress', loadPercentage * 100)
},
updateProgress: function () {
this.isUpdatingTime = true
if (this.sound && this.sound.state() === 'loaded') {
this.$store.dispatch('player/updateProgress', this.sound.seek())
this.updateBuffer(this.sound._sounds[0]._node)
}
},
observeProgress: function (enable) {
......
......@@ -8,11 +8,13 @@ export default {
maxConsecutiveErrors: 5,
errorCount: 0,
playing: false,
isLoadingAudio: false,
volume: 0.5,
tempVolume: 0.5,
duration: 0,
currentTime: 0,
errored: false,
bufferProgress: 0,
looping: 0 // 0 -> no, 1 -> on track, 2 -> on queue
},
mutations: {
......@@ -59,12 +61,18 @@ export default {
playing (state, value) {
state.playing = value
},
bufferProgress (state, value) {
state.bufferProgress = value
},
toggleLooping (state) {
if (state.looping > 1) {
state.looping = 0
} else {
state.looping += 1
}
},
isLoadingAudio (state, value) {
state.isLoadingAudio = value
}
},
getters: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment