Merge branch 'advplyr:master' into stream-sync

This commit is contained in:
svdztn 2021-10-26 11:02:27 +08:00 committed by GitHub
commit ad823ca486
6 changed files with 134 additions and 47 deletions

View file

@ -16,6 +16,8 @@ class Server extends EventEmitter {
this.connected = false
this.stream = null
this.isConnectingSocket = false
}
get token() {
@ -60,6 +62,10 @@ class Server extends EventEmitter {
}
async connect(url, token) {
if (this.connected) {
console.warn('[SOCKET] Connection already established for ' + this.url)
return true
}
if (!url) {
console.error('Invalid url to connect')
return false
@ -151,38 +157,84 @@ class Server extends EventEmitter {
}
connectSocket() {
console.log('[SERVER] Connect Socket', this.url)
if (this.connected || this.socket) {
if (this.socket) console.error('[SOCKET] Socket already established', this.url)
else console.error('[SOCKET] Already connected to socket', this.url)
return
}
this.socket = io(this.url)
console.log('[SOCKET] Connect Socket', this.url)
const socketOptions = {
transports: ['websocket'],
upgrade: false,
// reconnectionAttempts: 3
}
this.socket = io(this.url, socketOptions)
this.socket.on('connect', () => {
console.log('[Server] Socket Connected')
console.log('[SOCKET] Socket Connected ' + this.socket.id)
// Authenticate socket with token
this.socket.emit('auth', this.token)
this.connected = true
this.emit('connected', true)
this.store.commit('setSocketConnected', true)
})
this.socket.on('disconnect', () => {
console.log('[Server] Socket Disconnected')
this.socket.on('disconnect', (reason) => {
console.log('[SOCKET] Socket Disconnected: ' + reason)
this.connected = false
this.emit('connected', false)
this.store.commit('setSocketConnected', false)
// this.socket.removeAllListeners()
// if (this.socket.io && this.socket.io.removeAllListeners) {
// console.log(`[SOCKET] Removing ALL IO listeners`)
// this.socket.io.removeAllListeners()
// }
})
this.socket.on('init', (data) => {
console.log('[Server] Initial socket data received', data)
console.log('[SOCKET] Initial socket data received', data)
if (data.stream) {
this.stream = data.stream
this.store.commit('setStreamAudiobook', data.stream.audiobook)
this.emit('initialStream', data.stream)
}
})
this.socket.on('user_updated', (user) => {
if (this.user && user.id === this.user.id) {
this.setUser(user)
}
})
this.socket.on('current_user_audiobook_update', (payload) => {
this.emit('currentUserAudiobookUpdate', payload)
})
this.socket.onAny((evt, args) => {
console.log(`[SOCKET] ${this.socket.id}: ${evt} ${JSON.stringify(args)}`)
})
this.socket.on('connect_error', (err) => {
console.error('[SOCKET] connection failed', err)
this.emit('socketConnectionFailed', err)
})
this.socket.io.on("reconnect_attempt", (attempt) => {
console.log(`[SOCKET] Reconnect Attempt ${this.socket.id}: ${attempt}`)
})
this.socket.io.on("reconnect_error", (err) => {
console.log(`[SOCKET] Reconnect Error ${this.socket.id}: ${err}`)
})
this.socket.io.on("reconnect_failed", () => {
console.log(`[SOCKET] Reconnect Failed ${this.socket.id}`)
})
this.socket.io.on("reconnect", () => {
console.log(`[SOCKET] Reconnect Success ${this.socket.id}`)
})
}
}

View file

@ -13,8 +13,8 @@ android {
applicationId "com.audiobookshelf.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 25
versionName "0.9.9-beta"
versionCode 26
versionName "0.9.10-beta"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.

View file

@ -72,7 +72,9 @@ export default {
bufferTrackWidth: 0,
playedTrackWidth: 0,
seekedTime: 0,
seekLoading: false
seekLoading: false,
onPlayingUpdateListener: null,
onMetadataListener: null
}
},
computed: {
@ -308,17 +310,15 @@ export default {
terminateStream() {
MyNativeAudio.terminateStream()
},
init() {
MyNativeAudio.addListener('onPlayingUpdate', (data) => {
onPlayingUpdate(data) {
this.isPaused = !data.value
if (!this.isPaused) {
this.startPlayInterval()
} else {
this.stopPlayInterval()
}
})
MyNativeAudio.addListener('onMetadata', (data) => {
},
onMetadata(data) {
console.log('Native Audio On Metadata', JSON.stringify(data))
this.totalDuration = Number((data.duration / 1000).toFixed(2))
this.currentTime = Number((data.currentTime / 1000).toFixed(2))
@ -329,7 +329,10 @@ export default {
}
this.timeupdate()
})
},
init() {
this.onPlayingUpdateListener = MyNativeAudio.addListener('onPlayingUpdate', this.onPlayingUpdate)
this.onMetadataListener = MyNativeAudio.addListener('onMetadata', this.onMetadata)
if (this.$refs.track) {
this.trackWidth = this.$refs.track.clientWidth
@ -342,6 +345,8 @@ export default {
this.$nextTick(this.init)
},
beforeDestroy() {
if (this.onPlayingUpdateListener) this.onPlayingUpdateListener.remove()
if (this.onMetadataListener) this.onMetadataListener.remove()
clearInterval(this.playInterval)
}
}

View file

@ -69,7 +69,6 @@ export default {
if (!this.networkConnected) return
this.$server.on('connected', this.socketConnected)
var localServerUrl = await this.$localStore.getServerUrl()
var localUserToken = await this.$localStore.getToken()
if (localServerUrl) {
@ -78,12 +77,16 @@ export default {
// Server and Token are stored
if (localUserToken) {
this.processing = true
var isSocketAlreadyEstablished = this.$server.socket
var success = await this.$server.connect(localServerUrl, localUserToken)
if (!success && !this.$server.url) {
this.processing = false
this.serverUrl = null
} else if (!success) {
this.processing = false
} else if (isSocketAlreadyEstablished) {
// No need to wait for connect event
this.processing = false
}
} else {
// Server only is stored
@ -97,7 +100,18 @@ export default {
}
},
mounted() {
if (!this.$server) {
console.error('Server not initalized in connection icon')
return
}
if (this.$server.connected) {
this.isConnected = true
}
this.$server.on('connected', this.socketConnected)
this.init()
},
beforeDestroy() {
if (this.$server) this.$server.off('connected', this.socketConnected)
}
}
</script>

View file

@ -32,18 +32,19 @@ export default {
},
methods: {
async connected(isConnected) {
if (this.$route.name === 'connect') {
if (isConnected) {
this.$router.push('/')
}
}
this.syncUserProgress()
// Load libraries
this.$store.dispatch('libraries/load')
}
},
socketConnectionFailed(err) {
this.$toast.error('Socket connection error: ' + err.message)
},
updateAudiobookProgressOnServer(audiobookProgress) {
if (this.$server.socket) {
console.log(`[PROGRESSSYNC] Updating AB Progress on server ${JSON.stringify(audiobookProgress)}`)
this.$server.socket.emit('progress_update', audiobookProgress)
}
},
@ -54,22 +55,27 @@ export default {
var localAudiobooks = this.$store.state.user.localUserAudiobooks
var localHasUpdates = false
// console.log('[PROGRESSSYNC] Starting Sync USER', JSON.stringify(userAudiobooks))
// console.log('[PROGRESSSYNC] Starting Sync LOCAL', JSON.stringify(localAudiobooks))
var newestLocal = { ...localAudiobooks }
for (const audiobookId in userAudiobooks) {
if (localAudiobooks[audiobookId]) {
if (!audiobookId || !userAudiobooks[audiobookId] || audiobookId === 'undefined') {
console.error(`[PROGRESSSYNC] Invalid audiobookId ${audiobookId} - ${JSON.stringify(userAudiobooks[audiobookId])}`)
} else if (localAudiobooks[audiobookId]) {
if (localAudiobooks[audiobookId].lastUpdate > userAudiobooks[audiobookId].lastUpdate) {
// Local progress is more recent than user progress
this.updateAudiobookProgressOnServer(localAudiobooks[audiobookId])
} else if (localAudiobooks[audiobookId].lastUpdate < userAudiobooks[audiobookId].lastUpdate) {
// Server is more recent than local
newestLocal[audiobookId] = userAudiobooks[audiobookId]
console.log('SYNCUSERPROGRESS Server IS MORE RECENT for', audiobookId)
// console.log('[PROGRESSSYNC] Server IS MORE RECENT for', audiobookId, JSON.stringify(newestLocal[audiobookId]))
localHasUpdates = true
}
} else {
// Not on local yet - store on local
newestLocal[audiobookId] = userAudiobooks[audiobookId]
console.log('SYNCUSERPROGRESS LOCAL Is NOT Stored YET for', audiobookId, JSON.stringify(newestLocal[audiobookId]))
// console.log('[PROGRESSSYNC] LOCAL Is NOT Stored YET for', audiobookId, JSON.stringify(newestLocal[audiobookId]))
localHasUpdates = true
}
}
@ -82,10 +88,17 @@ export default {
}
if (localHasUpdates) {
console.log('Local audiobook progress has updates from server')
// console.log('[PROGRESSSYNC] Local audiobook progress has updates from server')
this.$localStore.setAllAudiobookProgress(newestLocal)
}
},
currentUserAudiobookUpdate({ id, data }) {
if (data) {
this.$localStore.updateUserAudiobookProgress(data)
} else {
this.$localStore.removeAudiobookProgress(id)
}
},
initialStream(stream) {
if (this.$refs.streamContainer && this.$refs.streamContainer.audioPlayerReady) {
this.$refs.streamContainer.streamOpen(stream)
@ -368,9 +381,12 @@ export default {
},
mounted() {
if (!this.$server) return console.error('No Server')
// console.log(`Default Mounted set SOCKET listeners ${this.$server.connected}`)
this.$server.on('connected', this.connected)
this.$server.on('connectionFailed', this.socketConnectionFailed)
this.$server.on('initialStream', this.initialStream)
this.$server.on('currentUserAudiobookUpdate', this.currentUserAudiobookUpdate)
if (this.$store.state.isFirstLoad) {
this.$store.commit('setIsFirstLoad', false)
@ -379,7 +395,6 @@ export default {
this.initMediaStore()
}
// For Testing Android Auto
MyNativeAudio.addListener('onPrepareMedia', (data) => {
var audiobookId = data.audiobookId
var playWhenReady = data.playWhenReady
@ -403,8 +418,9 @@ export default {
console.error('No Server beforeDestroy')
return
}
console.log('Default Before Destroy remove listeners')
this.$server.off('connected', this.connected)
this.$server.off('connectionFailed', this.socketConnectionFailed)
this.$server.off('initialStream', this.initialStream)
}
}

View file

@ -1,6 +1,6 @@
{
"name": "audiobookshelf-app",
"version": "v0.9.9-beta",
"version": "v0.9.10-beta",
"author": "advplyr",
"scripts": {
"dev": "nuxt --hostname localhost --port 1337",