fix: 修复在长时间暂停后无法播放的问题 (#1627)

* fix: 修复在长时间暂停后无法播放的问题

* 增加doc
master
memorydream 2 years ago committed by GitHub
parent b9cdade832
commit 6b690baef6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -14,6 +14,15 @@ import { decode as base642Buffer } from '@/utils/base64';
const PLAY_PAUSE_FADE_DURATION = 200; const PLAY_PAUSE_FADE_DURATION = 200;
/**
* @readonly
* @enum {string}
*/
const UNPLAYABLE_CONDITION = {
PLAY_NEXT_TRACK: 'playNextTrack',
PLAY_PREV_TRACK: 'playPrevTrack',
};
const electron = const electron =
process.env.IS_ELECTRON === true ? window.require('electron') : null; process.env.IS_ELECTRON === true ? window.require('electron') : null;
const ipcRenderer = const ipcRenderer =
@ -164,6 +173,9 @@ export default class {
get currentTrack() { get currentTrack() {
return this._currentTrack; return this._currentTrack;
} }
get currentTrackID() {
return this._currentTrack?.id ?? 0;
}
get playlistSource() { get playlistSource() {
return this._playlistSource; return this._playlistSource;
} }
@ -199,7 +211,7 @@ export default class {
if (this._enabled) { if (this._enabled) {
// 恢复当前播放歌曲 // 恢复当前播放歌曲
this._replaceCurrentTrack(this._currentTrack.id, false).then(() => { this._replaceCurrentTrack(this.currentTrackID, false).then(() => {
this._howler?.seek(localStorage.getItem('playerCurrentTrackTime') ?? 0); this._howler?.seek(localStorage.getItem('playerCurrentTrackTime') ?? 0);
}); // update audio source and init howler }); // update audio source and init howler
this._initMediaSession(); this._initMediaSession();
@ -278,7 +290,7 @@ export default class {
// 返回 [trackID, index] // 返回 [trackID, index]
return [this.list[next], next]; return [this.list[next], next];
} }
async _shuffleTheList(firstTrackID = this._currentTrack.id) { async _shuffleTheList(firstTrackID = this.currentTrackID) {
let list = this._list.filter(tid => tid !== firstTrackID); let list = this._list.filter(tid => tid !== firstTrackID);
if (firstTrackID === 'first') list = this._list; if (firstTrackID === 'first') list = this._list;
this._shuffledList = shuffle(list); this._shuffledList = shuffle(list);
@ -321,6 +333,25 @@ export default class {
this._nextTrackCallback(); this._nextTrackCallback();
}, },
}); });
this._howler.on('loaderror', (_, errCode) => {
// https://developer.mozilla.org/en-US/docs/Web/API/MediaError/code
// code 3: MEDIA_ERR_DECODE
if (errCode === 3) {
this._playNextTrack(this._isPersonalFM);
} else {
const t = this.progress;
this._replaceCurrentTrackAudio(this.currentTrack, false, false).then(
replaced => {
// 如果 replaced 为 false代表当前的 track 已经不是这里想要替换的track
// 此时则不修改当前的歌曲进度
if (replaced) {
this._howler?.seek(t);
this.play();
}
}
);
}
});
if (autoplay) { if (autoplay) {
this.play(); this.play();
if (this._currentTrack.name) { if (this._currentTrack.name) {
@ -452,33 +483,61 @@ export default class {
_replaceCurrentTrack( _replaceCurrentTrack(
id, id,
autoplay = true, autoplay = true,
ifUnplayableThen = 'playNextTrack' ifUnplayableThen = UNPLAYABLE_CONDITION.PLAY_NEXT_TRACK
) { ) {
if (autoplay && this._currentTrack.name) { if (autoplay && this._currentTrack.name) {
this._scrobble(this.currentTrack, this._howler?.seek()); this._scrobble(this.currentTrack, this._howler?.seek());
} }
return getTrackDetail(id).then(data => { return getTrackDetail(id).then(data => {
let track = data.songs[0]; const track = data.songs[0];
this._currentTrack = track; this._currentTrack = track;
this._updateMediaSessionMetaData(track); this._updateMediaSessionMetaData(track);
return this._getAudioSource(track).then(source => { return this._replaceCurrentTrackAudio(
if (source) { track,
autoplay,
true,
ifUnplayableThen
);
});
}
/**
* @returns 是否成功加载音频并使用加载完成的音频替换了howler实例
*/
_replaceCurrentTrackAudio(
track,
autoplay,
isCacheNextTrack,
ifUnplayableThen = UNPLAYABLE_CONDITION.PLAY_NEXT_TRACK
) {
return this._getAudioSource(track).then(source => {
if (source) {
let replaced = false;
if (track.id === this.currentTrackID) {
this._playAudioSource(source, autoplay); this._playAudioSource(source, autoplay);
replaced = true;
}
if (isCacheNextTrack) {
this._cacheNextTrack(); this._cacheNextTrack();
return source; }
} else { return replaced;
store.dispatch('showToast', `无法播放 ${track.name}`); } else {
if (ifUnplayableThen === 'playNextTrack') { store.dispatch('showToast', `无法播放 ${track.name}`);
if (this.isPersonalFM) { switch (ifUnplayableThen) {
this.playNextFMTrack(); case UNPLAYABLE_CONDITION.PLAY_NEXT_TRACK:
} else { this._playNextTrack(this.isPersonalFM);
this.playNextTrack(); break;
} case UNPLAYABLE_CONDITION.PLAY_PREV_TRACK:
} else {
this.playPrevTrack(); this.playPrevTrack();
} break;
default:
store.dispatch(
'showToast',
`undefined Unplayable condition: ${ifUnplayableThen}`
);
break;
} }
}); return false;
}
}); });
} }
_cacheNextTrack() { _cacheNextTrack() {
@ -511,11 +570,7 @@ export default class {
this.playPrevTrack(); this.playPrevTrack();
}); });
navigator.mediaSession.setActionHandler('nexttrack', () => { navigator.mediaSession.setActionHandler('nexttrack', () => {
if (this.isPersonalFM) { this._playNextTrack(this.isPersonalFM);
this.playNextFMTrack();
} else {
this.playNextTrack();
}
}); });
navigator.mediaSession.setActionHandler('stop', () => { navigator.mediaSession.setActionHandler('stop', () => {
this.pause(); this.pause();
@ -579,11 +634,9 @@ export default class {
_nextTrackCallback() { _nextTrackCallback() {
this._scrobble(this._currentTrack, 0, true); this._scrobble(this._currentTrack, 0, true);
if (!this.isPersonalFM && this.repeatMode === 'one') { if (!this.isPersonalFM && this.repeatMode === 'one') {
this._replaceCurrentTrack(this._currentTrack.id); this._replaceCurrentTrack(this.currentTrackID);
} else if (this.isPersonalFM) {
this.playNextFMTrack();
} else { } else {
this.playNextTrack(); this._playNextTrack(this.isPersonalFM);
} }
} }
_loadPersonalFMNextTrack() { _loadPersonalFMNextTrack() {
@ -628,11 +681,14 @@ export default class {
} }
ipcRenderer?.send('pauseDiscordPresence', track); ipcRenderer?.send('pauseDiscordPresence', track);
} }
_playNextTrack(isPersonal) {
currentTrackID() { if (isPersonal) {
const { list, current } = this._getListAndCurrent(); this.playNextFMTrack();
return list[current]; } else {
this.playNextTrack();
}
} }
appendTrack(trackID) { appendTrack(trackID) {
this.list.append(trackID); this.list.append(trackID);
} }
@ -697,7 +753,11 @@ export default class {
const [trackID, index] = this._getPrevTrack(); const [trackID, index] = this._getPrevTrack();
if (trackID === undefined) return false; if (trackID === undefined) return false;
this.current = index; this.current = index;
this._replaceCurrentTrack(trackID, true, 'playPrevTrack'); this._replaceCurrentTrack(
trackID,
true,
UNPLAYABLE_CONDITION.PLAY_PREV_TRACK
);
return true; return true;
} }
saveSelfToLocalStorage() { saveSelfToLocalStorage() {
@ -838,20 +898,14 @@ export default class {
addTrackToPlayNext(trackID, playNow = false) { addTrackToPlayNext(trackID, playNow = false) {
this._playNextList.push(trackID); this._playNextList.push(trackID);
if (playNow) { if (playNow) {
if (this.isPersonalFM) { this.playNextTrack();
this.playNextFMTrack();
} else {
this.playNextTrack();
}
} }
} }
playPersonalFM() { playPersonalFM() {
this._isPersonalFM = true; this._isPersonalFM = true;
if (!this._enabled) this._enabled = true; if (!this._enabled) this._enabled = true;
if (this._currentTrack.id !== this._personalFMTrack.id) { if (this.currentTrackID !== this._personalFMTrack.id) {
this._replaceCurrentTrack(this._personalFMTrack.id).then(() => this._replaceCurrentTrack(this._personalFMTrack.id, true);
this.playOrPause()
);
} else { } else {
this.playOrPause(); this.playOrPause();
} }

Loading…
Cancel
Save