implement scrobbling. fixes #3
This commit is contained in:
parent
4211966433
commit
a896d01769
@ -27,7 +27,7 @@ const authService = new AuthService()
|
|||||||
const api = new API(authService)
|
const api = new API(authService)
|
||||||
const router = setupRouter(authService)
|
const router = setupRouter(authService)
|
||||||
const store = setupStore(authService, api)
|
const store = setupStore(authService, api)
|
||||||
setupAudio(store)
|
setupAudio(store, api)
|
||||||
|
|
||||||
Vue.prototype.$auth = authService
|
Vue.prototype.$auth = authService
|
||||||
Vue.prototype.$api = api
|
Vue.prototype.$api = api
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Store, Module } from 'vuex'
|
import { Store, Module } from 'vuex'
|
||||||
import { shuffle, trackListEquals } from '@/shared/utils'
|
import { shuffle, trackListEquals } from '@/shared/utils'
|
||||||
|
import { API } from '@/shared/api'
|
||||||
|
|
||||||
const audio = new Audio()
|
const audio = new Audio()
|
||||||
const storedQueue = JSON.parse(localStorage.getItem('queue') || '[]')
|
const storedQueue = JSON.parse(localStorage.getItem('queue') || '[]')
|
||||||
@ -12,6 +13,7 @@ const mediaSession: MediaSession | undefined = navigator.mediaSession
|
|||||||
interface State {
|
interface State {
|
||||||
queue: any[];
|
queue: any[];
|
||||||
queueIndex: number;
|
queueIndex: number;
|
||||||
|
scrobbled: boolean;
|
||||||
isPlaying: boolean;
|
isPlaying: boolean;
|
||||||
duration: number; // duration of current track in seconds
|
duration: number; // duration of current track in seconds
|
||||||
currentTime: number; // position of current track in seconds
|
currentTime: number; // position of current track in seconds
|
||||||
@ -24,6 +26,7 @@ export const playerModule: Module<State, any> = {
|
|||||||
state: {
|
state: {
|
||||||
queue: storedQueue,
|
queue: storedQueue,
|
||||||
queueIndex: storedQueueIndex,
|
queueIndex: storedQueueIndex,
|
||||||
|
scrobbled: false,
|
||||||
isPlaying: false,
|
isPlaying: false,
|
||||||
duration: 0,
|
duration: 0,
|
||||||
currentTime: 0,
|
currentTime: 0,
|
||||||
@ -65,6 +68,7 @@ export const playerModule: Module<State, any> = {
|
|||||||
index = index < state.queue.length ? index : 0
|
index = index < state.queue.length ? index : 0
|
||||||
state.queueIndex = index
|
state.queueIndex = index
|
||||||
localStorage.setItem('queueIndex', index)
|
localStorage.setItem('queueIndex', index)
|
||||||
|
state.scrobbled = false
|
||||||
const track = state.queue[index]
|
const track = state.queue[index]
|
||||||
audio.src = track.url
|
audio.src = track.url
|
||||||
if (mediaSession) {
|
if (mediaSession) {
|
||||||
@ -94,6 +98,9 @@ export const playerModule: Module<State, any> = {
|
|||||||
setDuration(state, value: any) {
|
setDuration(state, value: any) {
|
||||||
state.duration = value
|
state.duration = value
|
||||||
},
|
},
|
||||||
|
setScrobbled(state) {
|
||||||
|
state.scrobbled = true
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
@ -194,20 +201,29 @@ export const playerModule: Module<State, any> = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setupAudio(store: Store<any>) {
|
export function setupAudio(store: Store<any>, api: API) {
|
||||||
audio.ontimeupdate = () => {
|
audio.ontimeupdate = () => {
|
||||||
store.commit('player/setCurrentTime', audio.currentTime)
|
store.commit('player/setCurrentTime', audio.currentTime)
|
||||||
|
|
||||||
|
// Scrobble
|
||||||
|
if (store.state.player.scrobbled === false &&
|
||||||
|
audio.duration > 30 &&
|
||||||
|
audio.currentTime / audio.duration > 0.7) {
|
||||||
|
const id = store.getters['player/trackId']
|
||||||
|
store.commit('player/setScrobbled')
|
||||||
|
api.scrobble(id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
audio.ondurationchange = () => {
|
audio.ondurationchange = () => {
|
||||||
store.commit('player/setDuration', audio.duration)
|
store.commit('player/setDuration', audio.duration)
|
||||||
}
|
}
|
||||||
audio.onended = () => {
|
|
||||||
store.dispatch('player/next')
|
|
||||||
}
|
|
||||||
audio.onerror = () => {
|
audio.onerror = () => {
|
||||||
store.commit('player/setPaused')
|
store.commit('player/setPaused')
|
||||||
store.commit('setError', audio.error)
|
store.commit('setError', audio.error)
|
||||||
}
|
}
|
||||||
|
audio.onended = () => {
|
||||||
|
store.dispatch('player/next')
|
||||||
|
}
|
||||||
|
|
||||||
if (mediaSession) {
|
if (mediaSession) {
|
||||||
mediaSession.setActionHandler('play', () => {
|
mediaSession.setActionHandler('play', () => {
|
||||||
|
@ -312,6 +312,10 @@ export class API {
|
|||||||
return this.get('rest/startScan')
|
return this.get('rest/startScan')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async scrobble(id: string): Promise<void> {
|
||||||
|
return this.get('rest/scrobble', { id })
|
||||||
|
}
|
||||||
|
|
||||||
private normalizeRadioStation(item: any): Track & RadioStation {
|
private normalizeRadioStation(item: any): Track & RadioStation {
|
||||||
return {
|
return {
|
||||||
id: `radio-${item.id}`,
|
id: `radio-${item.id}`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user