2021-11-01 21:06:51 -05:00
|
|
|
<template>
|
|
|
|
<div>
|
2022-12-11 11:09:50 -06:00
|
|
|
<app-audio-player ref="audioPlayer" :bookmarks="bookmarks" :sleep-timer-running="isSleepTimerRunning" :sleep-time-remaining="sleepTimeRemaining" :is-server-item="!!serverLibraryItemId" @selectPlaybackSpeed="showPlaybackSpeedModal = true" @updateTime="(t) => (currentTime = t)" @showSleepTimer="showSleepTimer" @showBookmarks="showBookmarks" />
|
2021-11-01 21:06:51 -05:00
|
|
|
|
2021-12-11 13:20:20 -06:00
|
|
|
<modals-playback-speed-modal v-model="showPlaybackSpeedModal" :playback-rate.sync="playbackSpeed" @update:playbackRate="updatePlaybackSpeed" @change="changePlaybackSpeed" />
|
2023-02-04 16:57:55 -06:00
|
|
|
<modals-sleep-timer-modal v-model="showSleepTimerModal" :current-time="sleepTimeRemaining" :sleep-timer-running="isSleepTimerRunning" :current-end-of-chapter-time="currentEndOfChapterTime" :is-auto="isAutoSleepTimer" @change="selectSleepTimeout" @cancel="cancelSleepTimer" @increase="increaseSleepTimer" @decrease="decreaseSleepTimer" />
|
2022-04-23 14:19:56 -05:00
|
|
|
<modals-bookmarks-modal v-model="showBookmarksModal" :bookmarks="bookmarks" :current-time="currentTime" :library-item-id="serverLibraryItemId" @select="selectBookmark" />
|
2021-11-01 21:06:51 -05:00
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2022-04-04 19:08:27 -05:00
|
|
|
import { AbsAudioPlayer } from '@/plugins/capacitor'
|
2022-04-17 16:59:49 -05:00
|
|
|
import { Dialog } from '@capacitor/dialog'
|
2021-11-01 21:06:51 -05:00
|
|
|
|
|
|
|
export default {
|
|
|
|
data() {
|
|
|
|
return {
|
2022-08-19 16:36:56 -04:00
|
|
|
isReady: false,
|
|
|
|
settingsLoaded: false,
|
2021-11-01 21:06:51 -05:00
|
|
|
audioPlayerReady: false,
|
|
|
|
stream: null,
|
|
|
|
download: null,
|
|
|
|
showPlaybackSpeedModal: false,
|
2021-11-02 19:44:42 -05:00
|
|
|
showBookmarksModal: false,
|
2021-11-01 21:06:51 -05:00
|
|
|
showSleepTimerModal: false,
|
|
|
|
playbackSpeed: 1,
|
|
|
|
currentTime: 0,
|
|
|
|
isSleepTimerRunning: false,
|
2021-11-26 18:27:18 -06:00
|
|
|
sleepTimerEndTime: 0,
|
2022-04-03 14:37:44 -05:00
|
|
|
sleepTimeRemaining: 0,
|
2023-02-04 16:57:55 -06:00
|
|
|
isAutoSleepTimer: false,
|
2022-04-09 12:03:37 -05:00
|
|
|
onLocalMediaProgressUpdateListener: null,
|
2021-11-01 21:06:51 -05:00
|
|
|
onSleepTimerEndedListener: null,
|
2021-11-26 18:27:18 -06:00
|
|
|
onSleepTimerSetListener: null,
|
2022-04-17 16:59:49 -05:00
|
|
|
onMediaPlayerChangedListener: null,
|
2021-11-01 21:06:51 -05:00
|
|
|
sleepInterval: null,
|
2022-04-23 14:19:56 -05:00
|
|
|
currentEndOfChapterTime: 0,
|
2022-08-11 17:36:27 -05:00
|
|
|
serverLibraryItemId: null,
|
|
|
|
serverEpisodeId: null
|
2021-11-01 21:06:51 -05:00
|
|
|
}
|
|
|
|
},
|
|
|
|
computed: {
|
2021-11-02 19:44:42 -05:00
|
|
|
bookmarks() {
|
2022-04-23 14:19:56 -05:00
|
|
|
if (!this.serverLibraryItemId) return []
|
|
|
|
return this.$store.getters['user/getUserBookmarksForItem'](this.serverLibraryItemId)
|
2021-11-01 21:06:51 -05:00
|
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
2021-11-02 19:44:42 -05:00
|
|
|
showBookmarks() {
|
|
|
|
this.showBookmarksModal = true
|
|
|
|
},
|
|
|
|
selectBookmark(bookmark) {
|
|
|
|
this.showBookmarksModal = false
|
|
|
|
if (!bookmark || isNaN(bookmark.time)) return
|
2022-12-11 11:09:50 -06:00
|
|
|
const bookmarkTime = Number(bookmark.time)
|
2021-11-02 19:44:42 -05:00
|
|
|
if (this.$refs.audioPlayer) {
|
|
|
|
this.$refs.audioPlayer.seek(bookmarkTime)
|
|
|
|
}
|
|
|
|
},
|
2021-11-01 21:06:51 -05:00
|
|
|
onSleepTimerEnded({ value: currentPosition }) {
|
|
|
|
this.isSleepTimerRunning = false
|
|
|
|
if (currentPosition) {
|
|
|
|
console.log('Sleep Timer Ended Current Position: ' + currentPosition)
|
|
|
|
}
|
|
|
|
},
|
2023-02-04 16:57:55 -06:00
|
|
|
onSleepTimerSet(payload) {
|
|
|
|
const { value: sleepTimeRemaining, isAuto } = payload
|
|
|
|
console.log('SLEEP TIMER SET', JSON.stringify(payload))
|
2022-02-03 09:19:27 -06:00
|
|
|
if (sleepTimeRemaining === 0) {
|
2021-11-26 18:27:18 -06:00
|
|
|
console.log('Sleep timer canceled')
|
|
|
|
this.isSleepTimerRunning = false
|
|
|
|
} else {
|
|
|
|
this.isSleepTimerRunning = true
|
|
|
|
}
|
|
|
|
|
2023-02-04 16:57:55 -06:00
|
|
|
this.isAutoSleepTimer = !!isAuto
|
2022-02-03 09:19:27 -06:00
|
|
|
this.sleepTimeRemaining = sleepTimeRemaining
|
2021-11-26 18:27:18 -06:00
|
|
|
},
|
2021-11-01 21:06:51 -05:00
|
|
|
showSleepTimer() {
|
2022-04-02 12:12:00 -05:00
|
|
|
if (this.$refs.audioPlayer && this.$refs.audioPlayer.currentChapter) {
|
|
|
|
this.currentEndOfChapterTime = Math.floor(this.$refs.audioPlayer.currentChapter.end)
|
2021-11-01 21:06:51 -05:00
|
|
|
} else {
|
|
|
|
this.currentEndOfChapterTime = 0
|
|
|
|
}
|
|
|
|
this.showSleepTimerModal = true
|
|
|
|
},
|
|
|
|
async selectSleepTimeout({ time, isChapterTime }) {
|
|
|
|
console.log('Setting sleep timer', time, isChapterTime)
|
2022-04-04 19:08:27 -05:00
|
|
|
var res = await AbsAudioPlayer.setSleepTimer({ time: String(time), isChapterTime })
|
2021-11-01 21:06:51 -05:00
|
|
|
if (!res.success) {
|
|
|
|
return this.$toast.error('Sleep timer did not set, invalid time')
|
|
|
|
}
|
|
|
|
},
|
2021-11-27 12:15:17 -06:00
|
|
|
increaseSleepTimer() {
|
|
|
|
// Default time to increase = 5 min
|
2022-04-04 19:08:27 -05:00
|
|
|
AbsAudioPlayer.increaseSleepTime({ time: '300000' })
|
2021-11-27 12:15:17 -06:00
|
|
|
},
|
|
|
|
decreaseSleepTimer() {
|
2022-04-04 19:08:27 -05:00
|
|
|
AbsAudioPlayer.decreaseSleepTime({ time: '300000' })
|
2021-11-27 12:15:17 -06:00
|
|
|
},
|
2021-11-01 21:06:51 -05:00
|
|
|
async cancelSleepTimer() {
|
|
|
|
console.log('Canceling sleep timer')
|
2022-04-04 19:08:27 -05:00
|
|
|
await AbsAudioPlayer.cancelSleepTimer()
|
2021-11-01 21:06:51 -05:00
|
|
|
},
|
2022-04-02 12:12:00 -05:00
|
|
|
streamClosed() {
|
2021-11-01 21:06:51 -05:00
|
|
|
console.log('Stream Closed')
|
|
|
|
},
|
|
|
|
streamProgress(data) {
|
|
|
|
if (!data.numSegments) return
|
|
|
|
var chunks = data.chunks
|
|
|
|
if (this.$refs.audioPlayer) {
|
|
|
|
this.$refs.audioPlayer.setChunksReady(chunks, data.numSegments)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
streamReady() {
|
|
|
|
console.log('[StreamContainer] Stream Ready')
|
|
|
|
if (this.$refs.audioPlayer) {
|
|
|
|
this.$refs.audioPlayer.setStreamReady()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
streamReset({ streamId, startTime }) {
|
2022-04-02 12:12:00 -05:00
|
|
|
console.log('received stream reset', streamId, startTime)
|
2021-11-01 21:06:51 -05:00
|
|
|
if (this.$refs.audioPlayer) {
|
|
|
|
if (this.stream && this.stream.id === streamId) {
|
|
|
|
this.$refs.audioPlayer.resetStream(startTime)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2021-12-11 13:20:20 -06:00
|
|
|
updatePlaybackSpeed(speed) {
|
2021-11-02 19:44:42 -05:00
|
|
|
if (this.$refs.audioPlayer) {
|
2021-12-11 13:20:20 -06:00
|
|
|
console.log(`[AudioPlayerContainer] Update Playback Speed: ${speed}`)
|
2021-11-02 19:44:42 -05:00
|
|
|
this.$refs.audioPlayer.setPlaybackSpeed(speed)
|
|
|
|
}
|
2021-12-11 13:20:20 -06:00
|
|
|
},
|
|
|
|
changePlaybackSpeed(speed) {
|
|
|
|
console.log(`[AudioPlayerContainer] Change Playback Speed: ${speed}`)
|
2021-11-01 21:06:51 -05:00
|
|
|
this.$store.dispatch('user/updateUserSettings', { playbackRate: speed })
|
|
|
|
},
|
|
|
|
settingsUpdated(settings) {
|
2021-11-02 19:44:42 -05:00
|
|
|
console.log(`[AudioPlayerContainer] Settings Update | PlaybackRate: ${settings.playbackRate}`)
|
|
|
|
this.playbackSpeed = settings.playbackRate
|
2021-11-01 21:06:51 -05:00
|
|
|
if (this.$refs.audioPlayer && this.$refs.audioPlayer.currentPlaybackRate !== settings.playbackRate) {
|
2021-11-02 19:44:42 -05:00
|
|
|
console.log(`[AudioPlayerContainer] PlaybackRate Updated: ${this.playbackSpeed}`)
|
|
|
|
this.$refs.audioPlayer.setPlaybackSpeed(this.playbackSpeed)
|
2021-11-01 21:06:51 -05:00
|
|
|
}
|
2022-08-19 16:36:56 -04:00
|
|
|
|
|
|
|
// Settings have been loaded (at least once, so it's safe to kickoff onReady)
|
2022-09-18 14:38:10 -04:00
|
|
|
if (!this.settingsLoaded) {
|
|
|
|
this.settingsLoaded = true
|
|
|
|
this.notifyOnReady()
|
|
|
|
}
|
2021-11-01 21:06:51 -05:00
|
|
|
},
|
2021-12-05 18:31:47 -06:00
|
|
|
closeStreamOnly() {
|
2022-04-02 12:12:00 -05:00
|
|
|
// If user logs out or disconnects from server and not playing local
|
|
|
|
if (this.$refs.audioPlayer && !this.$refs.audioPlayer.isLocalPlayMethod) {
|
2022-04-11 18:38:01 -05:00
|
|
|
this.$refs.audioPlayer.closePlayback()
|
2021-12-05 18:31:47 -06:00
|
|
|
}
|
2022-03-23 17:59:14 -05:00
|
|
|
},
|
2022-05-04 19:31:56 -05:00
|
|
|
castLocalItem() {
|
|
|
|
if (!this.serverLibraryItemId) {
|
|
|
|
this.$toast.error(`Cannot cast locally downloaded media`)
|
|
|
|
} else {
|
|
|
|
// Change to server library item
|
2022-08-11 17:36:27 -05:00
|
|
|
this.playServerLibraryItemAndCast(this.serverLibraryItemId, this.serverEpisodeId)
|
2022-05-04 19:31:56 -05:00
|
|
|
}
|
|
|
|
},
|
2022-08-11 17:36:27 -05:00
|
|
|
playServerLibraryItemAndCast(libraryItemId, episodeId) {
|
2022-05-04 19:31:56 -05:00
|
|
|
var playbackRate = 1
|
|
|
|
if (this.$refs.audioPlayer) {
|
|
|
|
playbackRate = this.$refs.audioPlayer.currentPlaybackRate || 1
|
|
|
|
}
|
2022-08-11 17:36:27 -05:00
|
|
|
AbsAudioPlayer.prepareLibraryItem({ libraryItemId, episodeId, playWhenReady: false, playbackRate })
|
2022-05-04 19:31:56 -05:00
|
|
|
.then((data) => {
|
2022-06-19 11:57:19 -05:00
|
|
|
if (data.error) {
|
|
|
|
const errorMsg = data.error || 'Failed to play'
|
|
|
|
this.$toast.error(errorMsg)
|
|
|
|
} else {
|
|
|
|
console.log('Library item play response', JSON.stringify(data))
|
|
|
|
AbsAudioPlayer.requestSession()
|
|
|
|
}
|
2022-05-04 19:31:56 -05:00
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
console.error('Failed', error)
|
2022-06-19 11:57:19 -05:00
|
|
|
this.$toast.error('Failed to play')
|
2022-05-04 19:31:56 -05:00
|
|
|
})
|
|
|
|
},
|
2022-04-10 20:31:47 -05:00
|
|
|
async playLibraryItem(payload) {
|
2022-12-11 11:09:50 -06:00
|
|
|
const libraryItemId = payload.libraryItemId
|
|
|
|
const episodeId = payload.episodeId
|
2023-01-15 14:58:26 -06:00
|
|
|
const startTime = payload.startTime
|
2023-02-11 22:57:06 +01:00
|
|
|
const startWhenReady = !payload.paused
|
2022-04-10 20:31:47 -05:00
|
|
|
|
2022-05-04 19:31:56 -05:00
|
|
|
// When playing local library item and can also play this item from the server
|
|
|
|
// then store the server library item id so it can be used if a cast is made
|
2022-12-11 11:09:50 -06:00
|
|
|
const serverLibraryItemId = payload.serverLibraryItemId || null
|
|
|
|
const serverEpisodeId = payload.serverEpisodeId || null
|
2022-05-04 19:31:56 -05:00
|
|
|
|
2022-04-17 16:59:49 -05:00
|
|
|
if (libraryItemId.startsWith('local') && this.$store.state.isCasting) {
|
|
|
|
const { value } = await Dialog.confirm({
|
|
|
|
title: 'Warning',
|
|
|
|
message: `Cannot cast downloaded media items. Confirm to close cast and play on your device.`
|
|
|
|
})
|
|
|
|
if (!value) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-15 14:58:26 -06:00
|
|
|
// if already playing this item then jump to start time
|
|
|
|
if (this.$store.getters['getIsMediaStreaming'](libraryItemId, episodeId)) {
|
|
|
|
console.log('Already streaming item', startTime)
|
|
|
|
if (startTime !== undefined && startTime !== null) {
|
|
|
|
// seek to start time
|
|
|
|
AbsAudioPlayer.seek({ value: Math.floor(startTime) })
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-04-23 14:19:56 -05:00
|
|
|
this.serverLibraryItemId = null
|
2022-08-11 17:36:27 -05:00
|
|
|
this.serverEpisodeId = null
|
2022-04-23 14:19:56 -05:00
|
|
|
|
2022-12-11 11:09:50 -06:00
|
|
|
let playbackRate = 1
|
2022-04-23 15:06:51 -05:00
|
|
|
if (this.$refs.audioPlayer) {
|
|
|
|
playbackRate = this.$refs.audioPlayer.currentPlaybackRate || 1
|
|
|
|
}
|
|
|
|
|
2022-04-08 18:07:31 -05:00
|
|
|
console.log('Called playLibraryItem', libraryItemId)
|
2023-02-11 22:57:06 +01:00
|
|
|
const preparePayload = { libraryItemId, episodeId, playWhenReady: startWhenReady, playbackRate }
|
2023-01-15 14:58:26 -06:00
|
|
|
if (startTime !== undefined && startTime !== null) preparePayload.startTime = startTime
|
|
|
|
AbsAudioPlayer.prepareLibraryItem(preparePayload)
|
2022-03-28 19:53:53 -05:00
|
|
|
.then((data) => {
|
2022-06-19 11:57:19 -05:00
|
|
|
if (data.error) {
|
|
|
|
const errorMsg = data.error || 'Failed to play'
|
|
|
|
this.$toast.error(errorMsg)
|
2022-05-04 19:31:56 -05:00
|
|
|
} else {
|
2022-06-19 11:57:19 -05:00
|
|
|
console.log('Library item play response', JSON.stringify(data))
|
|
|
|
if (!libraryItemId.startsWith('local')) {
|
|
|
|
this.serverLibraryItemId = libraryItemId
|
|
|
|
} else {
|
|
|
|
this.serverLibraryItemId = serverLibraryItemId
|
|
|
|
}
|
2022-08-11 17:36:27 -05:00
|
|
|
if (episodeId && !episodeId.startsWith('local')) {
|
|
|
|
this.serverEpisodeId = episodeId
|
|
|
|
} else {
|
|
|
|
this.serverEpisodeId = serverEpisodeId
|
|
|
|
}
|
2022-04-23 14:19:56 -05:00
|
|
|
}
|
2022-03-28 19:53:53 -05:00
|
|
|
})
|
|
|
|
.catch((error) => {
|
2022-04-08 18:07:31 -05:00
|
|
|
console.error('Failed', error)
|
2022-06-19 11:57:19 -05:00
|
|
|
this.$toast.error('Failed to play')
|
2022-03-28 19:53:53 -05:00
|
|
|
})
|
2022-04-09 12:03:37 -05:00
|
|
|
},
|
2022-04-10 20:31:47 -05:00
|
|
|
pauseItem() {
|
|
|
|
if (this.$refs.audioPlayer && !this.$refs.audioPlayer.isPaused) {
|
|
|
|
this.$refs.audioPlayer.pause()
|
|
|
|
}
|
|
|
|
},
|
2022-04-09 12:03:37 -05:00
|
|
|
onLocalMediaProgressUpdate(localMediaProgress) {
|
|
|
|
console.log('Got local media progress update', localMediaProgress.progress, JSON.stringify(localMediaProgress))
|
|
|
|
this.$store.commit('globals/updateLocalMediaProgress', localMediaProgress)
|
2022-04-17 16:59:49 -05:00
|
|
|
},
|
|
|
|
onMediaPlayerChanged(data) {
|
|
|
|
var mediaPlayer = data.value
|
|
|
|
this.$store.commit('setMediaPlayer', mediaPlayer)
|
2022-08-19 16:36:56 -04:00
|
|
|
},
|
|
|
|
onReady() {
|
|
|
|
// The UI is reporting elsewhere we are ready
|
|
|
|
this.isReady = true
|
|
|
|
this.notifyOnReady()
|
|
|
|
},
|
|
|
|
notifyOnReady() {
|
|
|
|
// If settings aren't loaded yet, native player will receive incorrect settings
|
|
|
|
console.log('Notify on ready... settingsLoaded:', this.settingsLoaded, 'isReady:', this.isReady)
|
2022-12-11 11:09:50 -06:00
|
|
|
if (this.settingsLoaded && this.isReady) {
|
2022-08-19 16:36:56 -04:00
|
|
|
AbsAudioPlayer.onReady()
|
|
|
|
}
|
2021-11-01 21:06:51 -05:00
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted() {
|
2022-04-09 12:03:37 -05:00
|
|
|
this.onLocalMediaProgressUpdateListener = AbsAudioPlayer.addListener('onLocalMediaProgressUpdate', this.onLocalMediaProgressUpdate)
|
2022-04-04 19:08:27 -05:00
|
|
|
this.onSleepTimerEndedListener = AbsAudioPlayer.addListener('onSleepTimerEnded', this.onSleepTimerEnded)
|
|
|
|
this.onSleepTimerSetListener = AbsAudioPlayer.addListener('onSleepTimerSet', this.onSleepTimerSet)
|
2022-04-17 16:59:49 -05:00
|
|
|
this.onMediaPlayerChangedListener = AbsAudioPlayer.addListener('onMediaPlayerChanged', this.onMediaPlayerChanged)
|
2021-11-01 21:06:51 -05:00
|
|
|
|
|
|
|
this.playbackSpeed = this.$store.getters['user/getUserSetting']('playbackRate')
|
2021-11-02 19:44:42 -05:00
|
|
|
console.log(`[AudioPlayerContainer] Init Playback Speed: ${this.playbackSpeed}`)
|
2021-11-01 21:06:51 -05:00
|
|
|
|
2022-08-19 16:36:56 -04:00
|
|
|
this.$eventBus.$on('abs-ui-ready', this.onReady)
|
2022-03-23 17:59:14 -05:00
|
|
|
this.$eventBus.$on('play-item', this.playLibraryItem)
|
2022-04-10 20:31:47 -05:00
|
|
|
this.$eventBus.$on('pause-item', this.pauseItem)
|
2022-04-02 12:12:00 -05:00
|
|
|
this.$eventBus.$on('close-stream', this.closeStreamOnly)
|
2022-05-04 19:31:56 -05:00
|
|
|
this.$eventBus.$on('cast-local-item', this.castLocalItem)
|
2022-12-17 14:48:56 -06:00
|
|
|
this.$eventBus.$on('user-settings', this.settingsUpdated)
|
2021-11-01 21:06:51 -05:00
|
|
|
},
|
|
|
|
beforeDestroy() {
|
2022-04-09 12:03:37 -05:00
|
|
|
if (this.onLocalMediaProgressUpdateListener) this.onLocalMediaProgressUpdateListener.remove()
|
2021-11-01 21:06:51 -05:00
|
|
|
if (this.onSleepTimerEndedListener) this.onSleepTimerEndedListener.remove()
|
2021-11-26 18:27:18 -06:00
|
|
|
if (this.onSleepTimerSetListener) this.onSleepTimerSetListener.remove()
|
2022-04-17 16:59:49 -05:00
|
|
|
if (this.onMediaPlayerChangedListener) this.onMediaPlayerChangedListener.remove()
|
2021-11-01 21:06:51 -05:00
|
|
|
|
2022-08-19 16:36:56 -04:00
|
|
|
this.$eventBus.$off('abs-ui-ready', this.onReady)
|
2022-03-23 17:59:14 -05:00
|
|
|
this.$eventBus.$off('play-item', this.playLibraryItem)
|
2022-04-10 20:31:47 -05:00
|
|
|
this.$eventBus.$off('pause-item', this.pauseItem)
|
2022-04-02 12:12:00 -05:00
|
|
|
this.$eventBus.$off('close-stream', this.closeStreamOnly)
|
2022-05-04 19:31:56 -05:00
|
|
|
this.$eventBus.$off('cast-local-item', this.castLocalItem)
|
2022-12-17 14:48:56 -06:00
|
|
|
this.$eventBus.$off('user-settings', this.settingsUpdated)
|
2021-11-01 21:06:51 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|