| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- import { PreferencesUtil } from '@pura/harmony-utils'
- import { VideoItem } from '../viewmodel/VideoItem'
- import { PlaybackSnapshot, PlaybackSnapshotSong } from './model/PlaybackSnapshot'
- export const PLAYBACK_SNAPSHOT_PREFERENCES_KEY = 'playback.host.snapshot'
- export interface RecoveredPlaybackSnapshotState {
- queue: VideoItem[]
- currentIndex: number
- currentSong: VideoItem | undefined
- }
- export class PlaybackSnapshotStore {
- public write(snapshot: PlaybackSnapshot): void {
- PreferencesUtil.putSync(PLAYBACK_SNAPSHOT_PREFERENCES_KEY, JSON.stringify(snapshot))
- }
- public read(): PlaybackSnapshot | undefined {
- const text = PreferencesUtil.getStringSync(PLAYBACK_SNAPSHOT_PREFERENCES_KEY, '')
- if (text.length === 0) {
- return undefined
- }
- try {
- const parsedSnapshot = JSON.parse(text) as Object | null
- if (!this.isValidSnapshot(parsedSnapshot)) {
- this.clear()
- return undefined
- }
- return parsedSnapshot
- } catch (_error) {
- this.clear()
- return undefined
- }
- }
- public clear(): void {
- PreferencesUtil.putSync(PLAYBACK_SNAPSHOT_PREFERENCES_KEY, '')
- }
- public restoreQueue(snapshot: PlaybackSnapshot): VideoItem[] {
- return this.recoverQueueState(snapshot).queue
- }
- public restoreCurrentSong(snapshot: PlaybackSnapshot): VideoItem | undefined {
- return this.recoverQueueState(snapshot).currentSong
- }
- public recoverQueueState(snapshot: PlaybackSnapshot): RecoveredPlaybackSnapshotState {
- const snapshotQueue = Array.isArray(snapshot.queue) ? snapshot.queue : []
- const queue: VideoItem[] = []
- for (let index = 0; index < snapshotQueue.length; index++) {
- const snapshotSong = snapshotQueue[index] as Object | null
- if (!this.isValidSnapshotSong(snapshotSong)) {
- continue
- }
- queue.push(this.buildVideoItem(snapshotSong))
- }
- const currentIndex = this.resolveCurrentIndex(snapshot, queue)
- const currentSong = currentIndex >= 0 ? queue[currentIndex] : undefined
- return {
- queue,
- currentIndex,
- currentSong
- }
- }
- private resolveCurrentIndex(snapshot: PlaybackSnapshot, queue: VideoItem[]): number {
- if (queue.length <= 0) {
- return -1
- }
- if (snapshot.currentSongKey && snapshot.currentSongKey !== '') {
- const matchedIndex = queue.findIndex((item: VideoItem): boolean => item.filePath === snapshot.currentSongKey)
- if (matchedIndex >= 0) {
- return matchedIndex
- }
- }
- const requestedIndex = typeof snapshot.currentIndex === 'number' ? snapshot.currentIndex : 0
- return Math.max(0, Math.min(requestedIndex, queue.length - 1))
- }
- private isValidSnapshot(snapshot: Object | null): snapshot is PlaybackSnapshot {
- if (!snapshot || Array.isArray(snapshot)) {
- return false
- }
- const candidate = snapshot as PlaybackSnapshot
- return Array.isArray(candidate.queue) &&
- typeof candidate.currentIndex === 'number' &&
- typeof candidate.currentSongKey === 'string' &&
- typeof candidate.currentSongName === 'string' &&
- typeof candidate.isPlaying === 'boolean' &&
- typeof candidate.positionMs === 'number' &&
- typeof candidate.durationMs === 'number' &&
- typeof candidate.playType === 'number' &&
- typeof candidate.playlistContext === 'string' &&
- typeof candidate.updatedAt === 'number' &&
- typeof candidate.shouldResumeWhenActivated === 'boolean'
- }
- private isValidSnapshotSong(snapshotSong: Object | null): snapshotSong is PlaybackSnapshotSong {
- if (!snapshotSong || Array.isArray(snapshotSong)) {
- return false
- }
- const candidate = snapshotSong as PlaybackSnapshotSong
- return typeof candidate.filePath === 'string' &&
- typeof candidate.name === 'string' &&
- typeof candidate.type === 'number'
- }
- private buildVideoItem(song: PlaybackSnapshotSong): VideoItem {
- const item = new VideoItem(song.name, song.id ?? '', song.filePath, song.type, 0, '')
- item.artist = song.artist
- item.album = song.album
- item.duration = song.duration
- item.pixelMapPath = song.pixelMapPath
- item.lyricContent = song.lyricContent
- item.remote_rel_path = song.remote_rel_path
- item.webdav_account_id = song.webdav_account_id
- return item
- }
- }
|