2023-08-28 22:47:22 +00:00
|
|
|
import axios from '@nextcloud/axios'
|
2024-01-16 22:13:07 +00:00
|
|
|
import { decodeUrl } from '../utils/url.js'
|
2024-01-29 14:47:50 +00:00
|
|
|
import { formatEpisodeTimestamp } from '../utils/time.js'
|
2023-08-28 22:47:22 +00:00
|
|
|
import { generateUrl } from '@nextcloud/router'
|
|
|
|
import router from '../router.js'
|
|
|
|
import store from './main.js'
|
|
|
|
|
|
|
|
const audio = new Audio()
|
|
|
|
audio.ondurationchange = () => store.commit('player/duration', audio.duration)
|
|
|
|
audio.onended = () => store.dispatch('player/stop')
|
|
|
|
audio.onloadeddata = () => store.commit('player/loaded', true)
|
|
|
|
audio.onplay = () => store.commit('player/paused', false)
|
|
|
|
audio.onpause = () => store.commit('player/paused', true)
|
2024-01-16 21:12:07 +00:00
|
|
|
audio.onratechange = () => store.commit('player/rate', audio.playbackRate)
|
2023-08-28 22:47:22 +00:00
|
|
|
audio.onseeked = () => store.commit('player/currentTime', audio.currentTime)
|
|
|
|
audio.ontimeupdate = () => store.commit('player/currentTime', audio.currentTime)
|
|
|
|
audio.onvolumechange = () => store.commit('player/volume', audio.volume)
|
|
|
|
|
|
|
|
export const player = {
|
|
|
|
namespaced: true,
|
|
|
|
state: {
|
|
|
|
currentTime: null,
|
|
|
|
duration: null,
|
|
|
|
episode: null,
|
|
|
|
loaded: false,
|
|
|
|
paused: null,
|
|
|
|
podcastUrl: null,
|
2023-08-29 09:43:17 +00:00
|
|
|
volume: 1,
|
2024-01-16 21:12:07 +00:00
|
|
|
rate: 1,
|
2024-01-16 22:13:07 +00:00
|
|
|
started: 0,
|
2023-08-28 22:47:22 +00:00
|
|
|
},
|
|
|
|
mutations: {
|
2023-08-29 06:48:54 +00:00
|
|
|
action: (state, action) => {
|
2023-08-29 10:07:23 +00:00
|
|
|
state.episode.action = action
|
2023-08-29 06:48:54 +00:00
|
|
|
|
2023-08-30 17:59:20 +00:00
|
|
|
if (action && action.position && action.position < action.total) {
|
2023-08-29 06:48:54 +00:00
|
|
|
audio.currentTime = action.position
|
2024-01-16 21:36:01 +00:00
|
|
|
state.started = audio.currentTime
|
2023-08-29 06:48:54 +00:00
|
|
|
}
|
|
|
|
},
|
2023-08-28 22:47:22 +00:00
|
|
|
currentTime: (state, currentTime) => {
|
|
|
|
state.currentTime = currentTime
|
|
|
|
},
|
|
|
|
duration: (state, duration) => {
|
|
|
|
state.duration = duration
|
|
|
|
},
|
2023-08-29 06:48:54 +00:00
|
|
|
episode: (state, episode) => {
|
2023-08-28 22:47:22 +00:00
|
|
|
state.episode = episode
|
|
|
|
|
|
|
|
if (episode) {
|
2024-01-16 22:13:07 +00:00
|
|
|
state.podcastUrl = decodeUrl(router.currentRoute.params.url)
|
2024-02-07 17:23:00 +00:00
|
|
|
const proxyUrl = new URL(episode.url)
|
|
|
|
audio.src = location.protocol === 'https:' && proxyUrl.protocol === 'http:'
|
|
|
|
? generateUrl('/apps/repod/episodes/proxy?url={url}', { url: episode.url })
|
|
|
|
: episode.url
|
2023-08-28 22:47:22 +00:00
|
|
|
audio.load()
|
|
|
|
audio.play()
|
2023-08-29 10:07:23 +00:00
|
|
|
|
2023-08-30 17:59:20 +00:00
|
|
|
if (episode.action && episode.action.position && episode.action.position < episode.action.total) {
|
2023-08-29 10:07:23 +00:00
|
|
|
audio.currentTime = episode.action.position
|
2024-01-16 22:13:07 +00:00
|
|
|
state.started = audio.currentTime
|
2023-08-29 10:07:23 +00:00
|
|
|
}
|
2023-08-28 22:47:22 +00:00
|
|
|
} else {
|
|
|
|
state.loaded = false
|
|
|
|
state.podcastUrl = null
|
|
|
|
audio.src = ''
|
|
|
|
}
|
|
|
|
},
|
|
|
|
loaded: (state, loaded) => {
|
|
|
|
state.loaded = loaded
|
|
|
|
},
|
|
|
|
paused: (state, paused) => {
|
|
|
|
state.paused = paused
|
|
|
|
},
|
|
|
|
volume: (state, volume) => {
|
|
|
|
state.volume = volume
|
|
|
|
},
|
2024-01-16 21:12:07 +00:00
|
|
|
rate: (state, rate) => {
|
|
|
|
state.rate = rate
|
|
|
|
},
|
2024-01-16 22:13:07 +00:00
|
|
|
started: (state, started) => {
|
|
|
|
state.started = started
|
|
|
|
},
|
2023-08-28 22:47:22 +00:00
|
|
|
},
|
|
|
|
actions: {
|
2023-08-29 06:48:54 +00:00
|
|
|
load: async (context, episode) => {
|
|
|
|
context.commit('episode', episode)
|
2023-08-29 09:43:17 +00:00
|
|
|
try {
|
2024-01-10 23:14:15 +00:00
|
|
|
const action = await axios.get(generateUrl('/apps/repod/episodes/action?url={url}', { url: episode.url }))
|
2023-08-29 09:43:17 +00:00
|
|
|
context.commit('action', action.data)
|
|
|
|
} catch {}
|
2023-08-29 06:48:54 +00:00
|
|
|
},
|
2023-08-28 22:47:22 +00:00
|
|
|
pause: (context) => {
|
|
|
|
audio.pause()
|
2023-12-24 10:45:37 +00:00
|
|
|
context.dispatch('time')
|
2023-08-28 22:47:22 +00:00
|
|
|
},
|
2024-01-16 21:36:01 +00:00
|
|
|
play: (context) => {
|
|
|
|
audio.play()
|
|
|
|
context.commit('started', audio.currentTime)
|
|
|
|
},
|
2023-08-28 22:47:22 +00:00
|
|
|
seek: (context, currentTime) => {
|
|
|
|
audio.currentTime = currentTime
|
2023-12-24 10:45:37 +00:00
|
|
|
context.dispatch('time')
|
2023-08-28 22:47:22 +00:00
|
|
|
},
|
|
|
|
stop: (context) => {
|
|
|
|
context.dispatch('pause')
|
2023-08-29 06:48:54 +00:00
|
|
|
context.commit('episode', null)
|
2023-08-28 22:47:22 +00:00
|
|
|
},
|
2023-12-24 10:45:37 +00:00
|
|
|
time: async (context) => axios.post(generateUrl('/apps/gpoddersync/episode_action/create'), [{
|
|
|
|
podcast: context.state.podcastUrl,
|
2024-01-10 23:14:15 +00:00
|
|
|
episode: context.state.episode.url,
|
|
|
|
guid: context.state.episode.guid,
|
2023-12-24 10:45:37 +00:00
|
|
|
action: 'play',
|
2024-01-29 14:47:50 +00:00
|
|
|
timestamp: formatEpisodeTimestamp(new Date()),
|
2024-01-16 21:36:01 +00:00
|
|
|
started: Math.round(context.state.started),
|
2023-12-24 10:45:37 +00:00
|
|
|
position: Math.round(audio.currentTime),
|
|
|
|
total: Math.round(audio.duration),
|
|
|
|
}]),
|
2024-01-10 23:14:15 +00:00
|
|
|
volume: (_, volume) => {
|
2023-08-28 22:47:22 +00:00
|
|
|
audio.volume = volume
|
|
|
|
},
|
2024-01-16 21:12:07 +00:00
|
|
|
rate: (_, rate) => {
|
|
|
|
audio.playbackRate = rate
|
|
|
|
},
|
2023-08-28 22:47:22 +00:00
|
|
|
},
|
|
|
|
}
|
2024-01-14 18:56:11 +00:00
|
|
|
|
|
|
|
setInterval(() => {
|
|
|
|
if (player.state.paused === false) {
|
|
|
|
store.dispatch('player/time')
|
|
|
|
}
|
|
|
|
}, 40000)
|