|
|
@@ -118,6 +118,8 @@ import { CommonConstants2 } from '../common/util/CommonConstants2';
|
|
|
import { hilog } from '@kit.PerformanceAnalysisKit';
|
|
|
import { LazyDataSource } from '../common/util/LazyDataSource';
|
|
|
import MediaTable, { PageQueryOptions, PageQueryResult, RandomSongQueryOptions } from '../common/util/MediaTable';
|
|
|
+import { requestPlaybackPlayerOpen, setPlaybackRuntimeReady } from '../playback/PlaybackHostState';
|
|
|
+import { BackgroundAudioPlaybackHost } from '../playback/BackgroundAudioPlaybackHost'
|
|
|
import FileDeletionWatcher from '../common/util/FileDeletionWatcher';
|
|
|
import NetAxiosUtil from '../common/util/NetAxiosUtil';
|
|
|
import { ringtone } from '@kit.RingtoneKit';
|
|
|
@@ -127,9 +129,13 @@ import { deviceInfo } from '@kit.BasicServicesKit';
|
|
|
import '../common/network/RemoteCacheRegistry';
|
|
|
import { shouldWrapLocalMusicMenuInScroll } from '../common/util/LocalMusicMenuScrollHelper';
|
|
|
import { ServerLogUtil } from '../common/util/ServerLogUtil';
|
|
|
-import { MusicPlaybackController, MusicPlaybackControllerActions } from '../controller/MusicPlaybackController';
|
|
|
-import { PlaybackCoordinator, PlaybackRuntime } from '../controller/PlaybackCoordinator'
|
|
|
-import { PlaybackStateBridge } from '../controller/PlaybackStateBridge'
|
|
|
+import { MusicPlaybackController } from '../controller/MusicPlaybackController';
|
|
|
+import { PlaybackRuntime } from '../controller/PlaybackCoordinator'
|
|
|
+import { PlaybackSnapshot as PlaybackStateBridgeSnapshot, PlaybackStateBridge } from '../controller/PlaybackStateBridge'
|
|
|
+import { clearRegisteredPlaybackRuntime, registerPlaybackRuntime } from '../playback/PlaybackRuntimeRegistry';
|
|
|
+import { consumePendingPlaybackActivation } from '../playback/PlaybackActivationStore';
|
|
|
+import { PlaybackSnapshotStore } from '../playback/PlaybackSnapshotStore'
|
|
|
+import { resolvePlaybackSnapshotProgressValue } from '../playback/model/PlaybackSnapshot'
|
|
|
import { lyricService, SongData } from '../common/service/LyricService';
|
|
|
import { shouldResolveRemoteLyricOnPlay, tryResolveRemotePlaybackLyric } from '../common/util/RemotePlaybackLyricUtil';
|
|
|
import { resolvePlayerDismissMorphTarget } from '../common/util/PlayerDismissHelper';
|
|
|
@@ -501,26 +507,9 @@ export struct LocalMusic {
|
|
|
private contentNode?: ComponentContent<Object> = undefined;
|
|
|
private skipNextPlaylistPersist: boolean = false
|
|
|
private playbackController: MusicPlaybackController = MusicPlaybackController.getInstance()
|
|
|
- private playbackCoordinator: PlaybackCoordinator = PlaybackCoordinator.getInstance()
|
|
|
private playbackStateBridge: PlaybackStateBridge = PlaybackStateBridge.getInstance()
|
|
|
+ private playbackSnapshotStore: PlaybackSnapshotStore = new PlaybackSnapshotStore()
|
|
|
private pendingInternalLoopModeReport: number = -1
|
|
|
- private readonly playbackControllerActions: MusicPlaybackControllerActions = {
|
|
|
- playOrPause: async () => {
|
|
|
- await this.playOrPause()
|
|
|
- },
|
|
|
- playNext: async () => {
|
|
|
- await this.playNext()
|
|
|
- },
|
|
|
- playPrevious: async () => {
|
|
|
- await this.playPrevious()
|
|
|
- },
|
|
|
- setLoopMode: () => {
|
|
|
- this.setLoopMode()
|
|
|
- },
|
|
|
- seekTo: async (value: string, source?: string) => {
|
|
|
- await this.seekTo(value, source ?? 'controller')
|
|
|
- }
|
|
|
- }
|
|
|
private playbackRuntime: PlaybackRuntime = {
|
|
|
playQueue: async (queue: VideoItem[], startIndex: number, source: string, playType?: number) => {
|
|
|
const safeIndex = queue.length <= 0 ? -1 : Math.max(0, Math.min(startIndex, queue.length - 1))
|
|
|
@@ -545,7 +534,7 @@ export struct LocalMusic {
|
|
|
this.currentSong = queue[safeIndex]
|
|
|
AppStorage.setOrCreate('currentSong', this.currentSong)
|
|
|
if (source === 'controller-open') {
|
|
|
- this.setShowPlayTrue()
|
|
|
+ requestPlaybackPlayerOpen()
|
|
|
}
|
|
|
await this.doPlay(queue[safeIndex], safeIndex, true)
|
|
|
this.playbackStateBridge.replaceQueue(this.songList, this.curIndex)
|
|
|
@@ -654,6 +643,10 @@ export struct LocalMusic {
|
|
|
@State lyricTextWeight: number = 400
|
|
|
@State lyricTextWeightPip: number = 400
|
|
|
@State currentSwiperIndex: number = 0
|
|
|
+ @StorageLink('playbackHostOpenRequestToken') @Watch('onPlaybackHostOpenRequestChange')
|
|
|
+ playbackHostOpenRequestToken: number = 0
|
|
|
+ @StorageLink('playbackHostPlaylistRequestToken') @Watch('onPlaybackHostPlaylistRequestChange')
|
|
|
+ playbackHostPlaylistRequestToken: number = 0
|
|
|
@State blurValue: number = 0 //背景模糊
|
|
|
@State bgBrightness: number = 0 //背景亮度
|
|
|
private listScroller: ListScroller = new ListScroller()
|
|
|
@@ -708,12 +701,16 @@ export struct LocalMusic {
|
|
|
private gridVisibleEnd: number = -1
|
|
|
private waterVisibleStart: number = -1
|
|
|
private waterVisibleEnd: number = -1
|
|
|
+ private lastHandledPlaybackHostOpenRequestToken: number = 0
|
|
|
+ private lastHandledPlaybackHostPlaylistRequestToken: number = 0
|
|
|
private titleBarToggleMinDelta: number = 12
|
|
|
private titleBarLastCheckTs: number = 0
|
|
|
@State private coverThumbVersion: number = 0
|
|
|
private coverThumbCache: CoverThumbCache = new CoverThumbCache(1, 960)
|
|
|
private coverThumbCacheReady: boolean = false
|
|
|
private pendingCoverThumbRefresh: boolean = false
|
|
|
+ private playbackSnapshotHydrated: boolean = false
|
|
|
+ private isHostSnapshotDisplayOnly: boolean = false
|
|
|
private playQueueScope: 'view' | 'history' | 'fav' | 'playlist' | 'single' | 'find_paged_local' = 'view'
|
|
|
private isHydratingPlayList: boolean = false
|
|
|
private preserveExistingQueueOnNextPlay: boolean = false
|
|
|
@@ -882,7 +879,7 @@ export struct LocalMusic {
|
|
|
// @Consume currentSong: VideoItem | undefined;
|
|
|
@StorageLink('currentSong') @Watch('onHomeBgCurrentSongChange') currentSong: VideoItem | undefined = undefined;
|
|
|
// @StorageLink('isPlay') isPlay: boolean = false;
|
|
|
- @Consume isShowPlay: boolean ;
|
|
|
+ @StorageLink('isShowPlay') isShowPlay: boolean = false;
|
|
|
@State isShowCoverScaleGuide: boolean = false
|
|
|
@StorageLink('songList') songList: Array<VideoItem> = [];
|
|
|
@State translateY: number = 0;
|
|
|
@@ -1111,61 +1108,53 @@ export struct LocalMusic {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
- private canConsumePendingMusicCardAction(action: string): boolean {
|
|
|
- if (action === MusicCardActionConstants.ACTION_PLAY_PAUSE) {
|
|
|
- if (this.CONTROL_PlayStatus === PlayStatus.PAUSE || this.CONTROL_PlayStatus === PlayStatus.PLAY) {
|
|
|
- return true
|
|
|
- }
|
|
|
- return !!this.currentSong && StrUtil.isNotEmpty(this.videoUrl)
|
|
|
+ private onPlaybackHostOpenRequestChange(): void {
|
|
|
+ if (this.playbackHostOpenRequestToken === this.lastHandledPlaybackHostOpenRequestToken) {
|
|
|
+ return
|
|
|
}
|
|
|
- if (action === MusicCardActionConstants.ACTION_PREVIOUS || action === MusicCardActionConstants.ACTION_NEXT) {
|
|
|
- return ArrayUtil.isNotEmpty(this.songList)
|
|
|
+ this.lastHandledPlaybackHostOpenRequestToken = this.playbackHostOpenRequestToken
|
|
|
+ if (!this.isShowPlay) {
|
|
|
+ this.setShowPlayTrue()
|
|
|
}
|
|
|
- return true
|
|
|
+ this.showPlayerView()
|
|
|
}
|
|
|
|
|
|
- private consumePendingMusicCardAction(): boolean {
|
|
|
- const pendingAction = AppStorage.get(MusicCardActionConstants.PENDING_ACTION_STORAGE_KEY) as string | undefined
|
|
|
- if (!pendingAction || pendingAction.length === 0) {
|
|
|
- return false
|
|
|
+ private onPlaybackHostPlaylistRequestChange(): void {
|
|
|
+ if (this.playbackHostPlaylistRequestToken === this.lastHandledPlaybackHostPlaylistRequestToken) {
|
|
|
+ return
|
|
|
}
|
|
|
- if (!this.canConsumePendingMusicCardAction(pendingAction)) {
|
|
|
- Logger.info(TAG, `skip consume pending music card action because playback not ready action=${pendingAction}`)
|
|
|
- return false
|
|
|
+ this.lastHandledPlaybackHostPlaylistRequestToken = this.playbackHostPlaylistRequestToken
|
|
|
+ this.openPlayList()
|
|
|
+ }
|
|
|
+
|
|
|
+ private consumePendingPlaybackActivationAfterRestore(): void {
|
|
|
+ const activation = consumePendingPlaybackActivation()
|
|
|
+ if (!activation) {
|
|
|
+ return
|
|
|
}
|
|
|
- AppStorage.setOrCreate(MusicCardActionConstants.PENDING_ACTION_STORAGE_KEY, '')
|
|
|
- if (pendingAction === MusicCardActionConstants.ACTION_PLAY_PAUSE) {
|
|
|
+ if (activation.actionType === 'resume_play') {
|
|
|
void this.playbackController.playOrPause()
|
|
|
- return true
|
|
|
+ return
|
|
|
}
|
|
|
- if (pendingAction === MusicCardActionConstants.ACTION_PREVIOUS) {
|
|
|
+ if (activation.actionType === 'play_previous') {
|
|
|
void this.playbackController.playPrevious()
|
|
|
- return true
|
|
|
+ return
|
|
|
}
|
|
|
- if (pendingAction === MusicCardActionConstants.ACTION_NEXT) {
|
|
|
+ if (activation.actionType === 'play_next') {
|
|
|
void this.playbackController.playNext()
|
|
|
- return true
|
|
|
- }
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- private consumePendingMusicCardOpenRequest(): void {
|
|
|
- const pendingOpen = AppStorage.get(MusicCardActionConstants.PENDING_OPEN_STORAGE_KEY) as boolean | undefined
|
|
|
- if (pendingOpen !== true) {
|
|
|
return
|
|
|
}
|
|
|
- AppStorage.setOrCreate(MusicCardActionConstants.PENDING_OPEN_STORAGE_KEY, false)
|
|
|
- if (!this.isShowPlay) {
|
|
|
- this.setShowPlayTrue()
|
|
|
+ if (activation.actionType === 'open_player') {
|
|
|
+ requestPlaybackPlayerOpen()
|
|
|
}
|
|
|
- this.showPlayerView()
|
|
|
}
|
|
|
// 组件生命周期
|
|
|
aboutToAppear() {
|
|
|
- this.playbackCoordinator.setRuntime(this.playbackRuntime)
|
|
|
- this.playbackController.setActions(this.playbackControllerActions)
|
|
|
- this.consumePendingMusicCardAction()
|
|
|
- this.consumePendingMusicCardOpenRequest()
|
|
|
+ registerPlaybackRuntime(this.playbackRuntime)
|
|
|
+ setPlaybackRuntimeReady(true)
|
|
|
+ this.playbackSnapshotHydrated = this.hydrateFromPlaybackSnapshot()
|
|
|
+ this.onPlaybackHostOpenRequestChange()
|
|
|
+ this.onPlaybackHostPlaylistRequestChange()
|
|
|
|
|
|
console.info('onecold aboutToAppear sdkApiVersion = '+deviceInfo.sdkApiVersion)
|
|
|
if(ArrayUtil.isNotEmpty(this.videoLocalList)&&this.modeType==0){
|
|
|
@@ -1392,51 +1381,6 @@ export struct LocalMusic {
|
|
|
this.syncLyricPositionNow();
|
|
|
}
|
|
|
});
|
|
|
-
|
|
|
- //NewIndex的博空调收到eventHub消息控制播放
|
|
|
- this.getUIContext().getHostContext()!.eventHub.on('playOrPause', () => {
|
|
|
- if (ArrayUtil.isNotEmpty(this.songList)) {
|
|
|
- this.playbackController.playOrPause();
|
|
|
- } else {
|
|
|
- ToastUtil.showToast('当前播放列表为空,请先导入音乐。')
|
|
|
- }
|
|
|
- });
|
|
|
- this.getUIContext().getHostContext()!.eventHub.on('playPrevious', () => {
|
|
|
- if (ArrayUtil.isNotEmpty(this.songList)) {
|
|
|
- void this.playbackController.playPrevious();
|
|
|
- } else {
|
|
|
- ToastUtil.showToast('当前播放列表为空,请先导入音乐。')
|
|
|
- }
|
|
|
- });
|
|
|
- this.getUIContext().getHostContext()!.eventHub.on('playNext', () => {
|
|
|
- if (ArrayUtil.isNotEmpty(this.songList)) {
|
|
|
- void this.playbackController.playNext();
|
|
|
- } else {
|
|
|
- ToastUtil.showToast('当前播放列表为空,请先导入音乐。')
|
|
|
- }
|
|
|
-
|
|
|
- });
|
|
|
- this.getUIContext().getHostContext()!.eventHub.on('showPlayerView', () => {
|
|
|
- if (!this.isShowPlay) {
|
|
|
- this.setShowPlayTrue()
|
|
|
- }
|
|
|
- this.showPlayerView();
|
|
|
- });
|
|
|
- this.getUIContext().getHostContext()!.eventHub.on('openPlayerViewFromMiniBar', () => {
|
|
|
- if (ArrayUtil.isEmpty(this.songList)) {
|
|
|
- ToastUtil.showToast('当前播放列表为空,请先导入音乐。');
|
|
|
- return
|
|
|
- }
|
|
|
- this.setShowPlayTrue()
|
|
|
- this.showPlayerView();
|
|
|
- });
|
|
|
- this.getUIContext().getHostContext()!.eventHub.on('dismissPlayerView', () => {
|
|
|
- this.setShowPlayFalse()
|
|
|
- });
|
|
|
- this.getUIContext().getHostContext()!.eventHub.on('openPlayList', () => {
|
|
|
- this.openPlayList();
|
|
|
- });
|
|
|
-
|
|
|
}
|
|
|
//载入媒体库,艺术家,专辑等缓存
|
|
|
initLoadCache(){
|
|
|
@@ -2313,33 +2257,39 @@ export struct LocalMusic {
|
|
|
// this.loadBannerAd(CSJUtil.getBannerID())
|
|
|
|
|
|
this.restoreLastPlayContext();
|
|
|
- this.songList = PreferencesUtil.getSync('LastMusicList', []) as Array<VideoItem>
|
|
|
- this.currentSong = PreferencesUtil.getSync('LastMusicInfo', undefined) as VideoItem
|
|
|
- if (ArrayUtil.isEmpty(this.songList)) {
|
|
|
- this.songList = this.videoLocalList.filter(item =>
|
|
|
- item.type === CommonConstants.TYPE_LOCAL && !this.isIsoLocalFile(item))
|
|
|
- } else {
|
|
|
- this.curIndex = Utility.getIndexFromList(this.songList, this.currentSong.filePath)
|
|
|
- }
|
|
|
- if (ArrayUtil.isNotEmpty(this.songList)) {
|
|
|
- this.isFirstStartPlay = true
|
|
|
- this.sonDataSource.pushArrayData(this.songList)
|
|
|
- if (this.currentSong === undefined) {
|
|
|
- this.isFirstStartPlay = false
|
|
|
- this.currentSong = this.songList[0]
|
|
|
+ const hydratedFromSnapshot = this.playbackSnapshotHydrated || this.hydrateFromPlaybackSnapshot()
|
|
|
+ if (!hydratedFromSnapshot) {
|
|
|
+ this.songList = PreferencesUtil.getSync('LastMusicList', []) as Array<VideoItem>
|
|
|
+ this.currentSong = PreferencesUtil.getSync('LastMusicInfo', undefined) as VideoItem
|
|
|
+ if (ArrayUtil.isEmpty(this.songList)) {
|
|
|
+ this.songList = this.videoLocalList.filter(item =>
|
|
|
+ item.type === CommonConstants.TYPE_LOCAL && !this.isIsoLocalFile(item))
|
|
|
+ } else if (this.currentSong !== undefined) {
|
|
|
+ this.curIndex = Utility.getIndexFromList(this.songList, this.currentSong.filePath)
|
|
|
+ } else {
|
|
|
+ this.curIndex = 0
|
|
|
}
|
|
|
- const restoredUrl = await this.resolvePlaybackUrlForCurrentSong('restore-last-song');
|
|
|
- if (!restoredUrl) {
|
|
|
- return;
|
|
|
+ if (ArrayUtil.isNotEmpty(this.songList)) {
|
|
|
+ this.isFirstStartPlay = true
|
|
|
+ this.sonDataSource.pushArrayData(this.songList)
|
|
|
+ if (this.currentSong === undefined) {
|
|
|
+ this.isFirstStartPlay = false
|
|
|
+ this.currentSong = this.songList[0]
|
|
|
+ }
|
|
|
+ const restoredUrl = await this.resolvePlaybackUrlForCurrentSong('restore-last-song');
|
|
|
+ if (!restoredUrl) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.videoUrl = restoredUrl;
|
|
|
+ Logger.info(TAG, `WebDAV URL同步构建完成: ${this.videoUrl}`);
|
|
|
+ this.name = this.currentSong.name
|
|
|
+ this.cover = this.currentSong.pixelMapPath
|
|
|
+ this.playbackStateBridge.replaceQueue(this.songList, this.curIndex)
|
|
|
+ AppStorage.setOrCreate('currentSong',this.currentSong) ;
|
|
|
+ this.consumePendingPlaybackActivationAfterRestore()
|
|
|
+ } else {
|
|
|
+ this.name = '空空如也'
|
|
|
}
|
|
|
- this.videoUrl = restoredUrl;
|
|
|
- Logger.info(TAG, `WebDAV URL同步构建完成: ${this.videoUrl}`);
|
|
|
- this.name = this.currentSong.name
|
|
|
- this.cover = this.currentSong.pixelMapPath
|
|
|
- AppStorage.setOrCreate('currentSong',this.currentSong) ;
|
|
|
- this.consumePendingMusicCardAction()
|
|
|
- } else {
|
|
|
- this.name = '空空如也'
|
|
|
}
|
|
|
})
|
|
|
|
|
|
@@ -2375,8 +2325,9 @@ export struct LocalMusic {
|
|
|
// 组件消失生命周期
|
|
|
aboutToDisappear() {
|
|
|
console.info('LifeCycleComponent aboutToDisappear');
|
|
|
- this.playbackCoordinator.clearRuntime(this.playbackRuntime)
|
|
|
- this.playbackController.clearActions(this.playbackControllerActions)
|
|
|
+ clearRegisteredPlaybackRuntime(this.playbackRuntime)
|
|
|
+ setPlaybackRuntimeReady(false)
|
|
|
+ this.playbackSnapshotHydrated = false
|
|
|
this.pendingInternalLoopModeReport = -1
|
|
|
if (this.alphaBetHideTimer) {
|
|
|
clearTimeout(this.alphaBetHideTimer);
|
|
|
@@ -2425,9 +2376,10 @@ export struct LocalMusic {
|
|
|
this.mDestroyPage = true;
|
|
|
this.audioInterruptResumePending = false;
|
|
|
this.mIjkMediaPlayer.setScreenOnWhilePlaying(false);
|
|
|
- if (this.CONTROL_PlayStatus != PlayStatus.INIT) {
|
|
|
+ if (this.CONTROL_PlayStatus != PlayStatus.INIT && !this.isHostSnapshotDisplayOnly) {
|
|
|
this.stop();
|
|
|
}
|
|
|
+ this.isHostSnapshotDisplayOnly = false;
|
|
|
this.mIjkMediaPlayer.off('audioInterrupt');
|
|
|
this.mIjkMediaPlayer.off('deviceChange');
|
|
|
if (this.audioRoutingManager && this.outputDeviceChangeCallback) {
|
|
|
@@ -2445,13 +2397,6 @@ export struct LocalMusic {
|
|
|
|
|
|
this.stopPip();
|
|
|
this.destroyPipController()
|
|
|
- this.getUIContext().getHostContext()!.eventHub.off('playOrPause');
|
|
|
- this.getUIContext().getHostContext()!.eventHub.off('playPrevious');
|
|
|
- this.getUIContext().getHostContext()!.eventHub.off('playNext');
|
|
|
- this.getUIContext().getHostContext()!.eventHub.off('showPlayerView');
|
|
|
- this.getUIContext().getHostContext()!.eventHub.off('openPlayerViewFromMiniBar');
|
|
|
- this.getUIContext().getHostContext()!.eventHub.off('dismissPlayerView');
|
|
|
- this.getUIContext().getHostContext()!.eventHub.off('openPlayList');
|
|
|
this.eventHub.off('onStateChange');
|
|
|
}
|
|
|
|
|
|
@@ -2928,6 +2873,67 @@ export struct LocalMusic {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private hydrateFromPlaybackSnapshot(): boolean {
|
|
|
+ if (this.playbackSnapshotHydrated) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ const snapshot = this.playbackSnapshotStore.read()
|
|
|
+ if (!snapshot) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ const recovered = this.playbackSnapshotStore.recoverQueueState(snapshot)
|
|
|
+ if (ArrayUtil.isEmpty(recovered.queue) || recovered.currentSong === undefined) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ this.songList = recovered.queue
|
|
|
+ this.currentSongList = [...recovered.queue]
|
|
|
+ this.curIndex = recovered.currentIndex
|
|
|
+ this.currentSong = recovered.currentSong
|
|
|
+ if (snapshot.cover && StrUtil.isEmpty(this.currentSong.pixelMapPath)) {
|
|
|
+ this.currentSong.pixelMapPath = snapshot.cover
|
|
|
+ }
|
|
|
+ this.playType = snapshot.playType
|
|
|
+ this.isFirstStartPlay = true
|
|
|
+ this.videoUrl = this.currentSong.filePath
|
|
|
+ this.name = snapshot.currentSongName !== '' ? snapshot.currentSongName : this.currentSong.name
|
|
|
+ this.artist = snapshot.currentArtist ?? this.currentSong.artist ?? ''
|
|
|
+ this.cover = snapshot.cover ?? this.currentSong.pixelMapPath
|
|
|
+ this.CONTROL_PlayStatus = snapshot.isPlaying ? PlayStatus.PLAY : PlayStatus.PAUSE
|
|
|
+ this.progressValue = resolvePlaybackSnapshotProgressValue(
|
|
|
+ snapshot.positionMs,
|
|
|
+ snapshot.durationMs,
|
|
|
+ this.PROGRESS_MAX_VALUE
|
|
|
+ )
|
|
|
+ this.slideEnable = snapshot.durationMs > 0
|
|
|
+ this.currentTime = this.stringForTime(snapshot.positionMs)
|
|
|
+ this.totalTime = this.stringForTime(snapshot.durationMs)
|
|
|
+ this.duration = snapshot.durationMs
|
|
|
+ this.durationTime = Math.floor(snapshot.durationMs / 1000)
|
|
|
+ this.sonDataSource.pushArrayData(this.songList)
|
|
|
+ const bridgeSnapshot: PlaybackStateBridgeSnapshot = {
|
|
|
+ queue: this.songList,
|
|
|
+ currentIndex: this.curIndex,
|
|
|
+ currentSong: this.currentSong,
|
|
|
+ isPlaying: snapshot.isPlaying,
|
|
|
+ positionMs: snapshot.positionMs,
|
|
|
+ durationMs: snapshot.durationMs
|
|
|
+ }
|
|
|
+ this.playbackStateBridge.restoreSnapshot(bridgeSnapshot)
|
|
|
+ AppStorage.setOrCreate('songList', this.songList)
|
|
|
+ AppStorage.setOrCreate('currIndex', this.curIndex)
|
|
|
+ AppStorage.setOrCreate('currentSong', this.currentSong)
|
|
|
+ AppStorage.setOrCreate('CONTROL_PlayStatus', this.CONTROL_PlayStatus)
|
|
|
+ AppStorage.setOrCreate('progressValue', this.progressValue)
|
|
|
+ AppStorage.setOrCreate('cover', this.cover ?? '')
|
|
|
+ this.playbackSnapshotHydrated = true
|
|
|
+ this.isHostSnapshotDisplayOnly = true
|
|
|
+ Logger.info(TAG,
|
|
|
+ `从后台宿主快照恢复页面状态 song=${this.currentSong.name}, index=${this.curIndex}, ` +
|
|
|
+ `isPlaying=${snapshot.isPlaying}, position=${snapshot.positionMs}`)
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
private resetFindPagedLocalQueueState(): void {
|
|
|
// 退出“随心所欲”分页队列时,避免旧分页状态污染后续普通播放队列。
|
|
|
this.findPagedLocalQueuePageIndex = 0;
|
|
|
@@ -12955,7 +12961,7 @@ export struct LocalMusic {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
- @Consume progressValue: number ;
|
|
|
+ @StorageLink('progressValue') progressValue: number = 0;
|
|
|
@State currentTime: string = "00:00";
|
|
|
@State totalTime: string = "00:00";
|
|
|
@State loadingVisible: Visibility = Visibility.None;
|
|
|
@@ -12978,7 +12984,7 @@ export struct LocalMusic {
|
|
|
private last: number = 0;
|
|
|
@State videoParentAspectRatio: number = this.initAspectRatio;
|
|
|
private mIjkMediaPlayer = IjkMediaPlayer.getInstance();
|
|
|
- @Consume CONTROL_PlayStatus: number ;
|
|
|
+ @StorageLink('CONTROL_PlayStatus') CONTROL_PlayStatus: number = PlayStatus.INIT;
|
|
|
@State PROGRESS_MAX_VALUE: number = 100;
|
|
|
@State updateProgressTimer: number = 0;
|
|
|
private readonly progressUpdateIntervalMs: number = 120;
|
|
|
@@ -13045,7 +13051,7 @@ export struct LocalMusic {
|
|
|
// @State isBgPlayOpen:boolean = true //是否启用后台播放
|
|
|
@State rotateAngle2: number = -9
|
|
|
@StorageLink('imageColor') imageColor: string = 'rgba(0, 0, 2, 1.00)';
|
|
|
- @Consume cover: string | undefined ;
|
|
|
+ @StorageLink('cover') cover: string | undefined = '';
|
|
|
@State artist: string | undefined = ''
|
|
|
// 1.初始化controller
|
|
|
private lyricController: LyricController = new LyricController()
|
|
|
@@ -17239,6 +17245,7 @@ export struct LocalMusic {
|
|
|
|
|
|
//startOffset 从cue分轨时间开始播
|
|
|
private startPlayOrResumePlay(startOffset?:number) {
|
|
|
+ this.isHostSnapshotDisplayOnly = false
|
|
|
let finalStartOffset = startOffset
|
|
|
if ((finalStartOffset === undefined || finalStartOffset === null) && this.currentSong && isCueSplitItem(this.currentSong)) {
|
|
|
finalStartOffset = 0
|
|
|
@@ -19345,6 +19352,10 @@ export struct LocalMusic {
|
|
|
};
|
|
|
|
|
|
private async playOrPause() {
|
|
|
+ if (this.isHostSnapshotDisplayOnly) {
|
|
|
+ await BackgroundAudioPlaybackHost.getInstance().getRuntime().playOrPause()
|
|
|
+ return
|
|
|
+ }
|
|
|
if (!this.debounce()) {
|
|
|
return;
|
|
|
}
|
|
|
@@ -19591,6 +19602,12 @@ export struct LocalMusic {
|
|
|
}
|
|
|
|
|
|
private async pause(clearInterruptResumeFlag: boolean = true) {
|
|
|
+ if (this.isHostSnapshotDisplayOnly) {
|
|
|
+ if (this.CONTROL_PlayStatus === PlayStatus.PLAY) {
|
|
|
+ await BackgroundAudioPlaybackHost.getInstance().getRuntime().playOrPause()
|
|
|
+ }
|
|
|
+ return
|
|
|
+ }
|
|
|
if (clearInterruptResumeFlag) {
|
|
|
this.audioInterruptResumePending = false;
|
|
|
}
|
|
|
@@ -19758,6 +19775,10 @@ export struct LocalMusic {
|
|
|
}
|
|
|
|
|
|
private async seekTo(value: string, source: string = 'internal') {
|
|
|
+ if (this.isHostSnapshotDisplayOnly) {
|
|
|
+ await BackgroundAudioPlaybackHost.getInstance().getRuntime().seekTo(value, source)
|
|
|
+ return
|
|
|
+ }
|
|
|
// if (StrUtil.isNotEmpty(this.videoUrl) && this.videoUrl.toLowerCase().endsWith('.wma')) {
|
|
|
// ToastUtil.showToast('wma格式不支持拖动快进。')
|
|
|
// return
|
|
|
@@ -19924,6 +19945,10 @@ export struct LocalMusic {
|
|
|
|
|
|
//下一个
|
|
|
private async playNext() {
|
|
|
+ if (this.isHostSnapshotDisplayOnly) {
|
|
|
+ await BackgroundAudioPlaybackHost.getInstance().getRuntime().playNext()
|
|
|
+ return
|
|
|
+ }
|
|
|
this.lyricController.setLyric(null)
|
|
|
this.lyricControllerXF.setLyric(null)
|
|
|
this.lyricControllerSingle.setLyric(null)
|
|
|
@@ -20331,6 +20356,10 @@ export struct LocalMusic {
|
|
|
|
|
|
//上一个
|
|
|
private async playPrevious() {
|
|
|
+ if (this.isHostSnapshotDisplayOnly) {
|
|
|
+ await BackgroundAudioPlaybackHost.getInstance().getRuntime().playPrevious()
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
if (!this.debounce()) {
|
|
|
return;
|