|
@@ -1,3 +1,11 @@
|
|
|
|
|
+import { emitter } from '@kit.BasicServicesKit'
|
|
|
|
|
+import { EventConstants } from '../common/constants/EventConstants'
|
|
|
|
|
+import { buildPlaylistDispatchFilePaths } from '../common/util/PlaylistPlayDispatchHelper'
|
|
|
|
|
+import { PlaylistPlayRequest, savePendingPlaylistPlay } from '../common/util/PlaylistPlayRequestStore'
|
|
|
|
|
+import { setFindPlaylist } from '../common/util/FindPlaylistStore'
|
|
|
|
|
+import { PlaybackCoordinator } from './PlaybackCoordinator'
|
|
|
|
|
+import { VideoItem } from '../viewmodel/VideoItem'
|
|
|
|
|
+
|
|
|
export interface MusicPlaybackControllerActions {
|
|
export interface MusicPlaybackControllerActions {
|
|
|
playOrPause: () => void | Promise<void>
|
|
playOrPause: () => void | Promise<void>
|
|
|
playNext: () => void | Promise<void>
|
|
playNext: () => void | Promise<void>
|
|
@@ -6,6 +14,15 @@ export interface MusicPlaybackControllerActions {
|
|
|
seekTo: (value: string, source?: string) => void | Promise<void>
|
|
seekTo: (value: string, source?: string) => void | Promise<void>
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+export interface InMemoryPlaylistPlaybackOptions {
|
|
|
|
|
+ playlistId: string
|
|
|
|
|
+ playlistName: string
|
|
|
|
|
+ songs: VideoItem[]
|
|
|
|
|
+ startIndex: number
|
|
|
|
|
+ isJump?: boolean
|
|
|
|
|
+ playType?: number
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
export interface LoopModeResolution {
|
|
export interface LoopModeResolution {
|
|
|
playType: number
|
|
playType: number
|
|
|
toastText: string
|
|
toastText: string
|
|
@@ -53,6 +70,7 @@ export type ItemPlaybackToggleAction = 'toggle_current' | 'play_target'
|
|
|
export class MusicPlaybackController {
|
|
export class MusicPlaybackController {
|
|
|
private static instance?: MusicPlaybackController
|
|
private static instance?: MusicPlaybackController
|
|
|
private actions?: MusicPlaybackControllerActions
|
|
private actions?: MusicPlaybackControllerActions
|
|
|
|
|
+ private playbackCoordinator: PlaybackCoordinator = PlaybackCoordinator.getInstance()
|
|
|
|
|
|
|
|
public static getInstance(): MusicPlaybackController {
|
|
public static getInstance(): MusicPlaybackController {
|
|
|
if (!MusicPlaybackController.instance) {
|
|
if (!MusicPlaybackController.instance) {
|
|
@@ -241,6 +259,23 @@ export class MusicPlaybackController {
|
|
|
return 'play_target'
|
|
return 'play_target'
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ public static buildInMemoryPlaylistPlayRequest(options: InMemoryPlaylistPlaybackOptions): PlaylistPlayRequest {
|
|
|
|
|
+ const songs = options.songs ?? []
|
|
|
|
|
+ const playlistId = options.playlistId.indexOf('find-') === 0 ? options.playlistId : `find-${options.playlistId}`
|
|
|
|
|
+ const maxIndex = Math.max(songs.length - 1, 0)
|
|
|
|
|
+ const safeStartIndex = songs.length <= 0 ? 0 : Math.max(0, Math.min(options.startIndex, maxIndex))
|
|
|
|
|
+
|
|
|
|
|
+ return new PlaylistPlayRequest(
|
|
|
|
|
+ playlistId,
|
|
|
|
|
+ options.playlistName,
|
|
|
|
|
+ songs.length,
|
|
|
|
|
+ safeStartIndex,
|
|
|
|
|
+ buildPlaylistDispatchFilePaths(playlistId, songs),
|
|
|
|
|
+ options.isJump,
|
|
|
|
|
+ options.playType
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public setActions(actions: MusicPlaybackControllerActions): void {
|
|
public setActions(actions: MusicPlaybackControllerActions): void {
|
|
|
this.actions = actions
|
|
this.actions = actions
|
|
|
}
|
|
}
|
|
@@ -251,16 +286,48 @@ export class MusicPlaybackController {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ public async playSong(song: VideoItem, source: string = 'controller'): Promise<void> {
|
|
|
|
|
+ await this.playbackCoordinator.playSong(song, source)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public async playQueue(queue: VideoItem[], startIndex: number, source: string = 'controller'): Promise<void> {
|
|
|
|
|
+ await this.playbackCoordinator.playQueue(queue, startIndex, source)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public async playOrPauseDirect(): Promise<void> {
|
|
|
|
|
+ await this.playbackCoordinator.playOrPause()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public async playNextDirect(): Promise<void> {
|
|
|
|
|
+ await this.playbackCoordinator.playNext()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public async playPreviousDirect(): Promise<void> {
|
|
|
|
|
+ await this.playbackCoordinator.playPrevious()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public playOrPause(): void {
|
|
public playOrPause(): void {
|
|
|
- this.actions?.playOrPause()
|
|
|
|
|
|
|
+ if (this.actions) {
|
|
|
|
|
+ this.actions.playOrPause()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ void this.playbackCoordinator.playOrPause()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public async playNext(): Promise<void> {
|
|
public async playNext(): Promise<void> {
|
|
|
- await this.actions?.playNext?.()
|
|
|
|
|
|
|
+ if (this.actions) {
|
|
|
|
|
+ await this.actions.playNext?.()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ await this.playNextDirect()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public async playPrevious(): Promise<void> {
|
|
public async playPrevious(): Promise<void> {
|
|
|
- await this.actions?.playPrevious?.()
|
|
|
|
|
|
|
+ if (this.actions) {
|
|
|
|
|
+ await this.actions.playPrevious?.()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ await this.playPreviousDirect()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public async setLoopMode(): Promise<void> {
|
|
public async setLoopMode(): Promise<void> {
|
|
@@ -268,6 +335,21 @@ export class MusicPlaybackController {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public async seekTo(value: string, source?: string): Promise<void> {
|
|
public async seekTo(value: string, source?: string): Promise<void> {
|
|
|
- await this.actions?.seekTo?.(value, source)
|
|
|
|
|
|
|
+ if (this.actions) {
|
|
|
|
|
+ await this.actions.seekTo?.(value, source)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ await this.playbackCoordinator.seekTo(value, source)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public playInMemoryPlaylist(options: InMemoryPlaylistPlaybackOptions): void {
|
|
|
|
|
+ if (!options.songs || options.songs.length <= 0) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const request = MusicPlaybackController.buildInMemoryPlaylistPlayRequest(options)
|
|
|
|
|
+ setFindPlaylist(request.playlistId, request.playlistName, options.songs, request.startIndex)
|
|
|
|
|
+ savePendingPlaylistPlay(request)
|
|
|
|
|
+ emitter.emit({ eventId: EventConstants.EVENT_PLAYLIST_PLAY }, { data: request })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|