实现了对播放列表的随机播放功能

pull/2369/head
QiuLiang-99 2025-05-03 17:14:26 +08:00
parent 5ba914c162
commit e32f6ef871
3 changed files with 119 additions and 44 deletions

View File

@ -1,5 +1,5 @@
import { isEmpty, setPause, setPlay, setResource, setStop } from '@renderer/plugins/player' import { isEmpty, setPause, setPlay, setResource, setStop } from '@renderer/plugins/player'
import { isPlay, playedList, playInfo, playMusicInfo, tempPlayList, musicInfo as _musicInfo, currentPlayIndex } from '@renderer/store/player/state' import { isPlay, playedList, playInfo, playMusicInfo, tempPlayList, musicInfo as _musicInfo, currentPlayIndex, currentPlaybackOrder } from '@renderer/store/player/state'
import { import {
getList, getList,
clearPlayedList, clearPlayedList,
@ -148,6 +148,7 @@ export const setMusicUrl = (musicInfo: LX.Music.MusicInfo | LX.Download.ListItem
// 恢复上次播放的状态 // 恢复上次播放的状态
const handleRestorePlay = async(restorePlayInfo: LX.Player.SavedPlayInfo) => { const handleRestorePlay = async(restorePlayInfo: LX.Player.SavedPlayInfo) => {
// todo 恢复软件关闭时tempplaylist的状态
const musicInfo = playMusicInfo.musicInfo const musicInfo = playMusicInfo.musicInfo
if (!musicInfo) return if (!musicInfo) return
@ -364,7 +365,7 @@ export const getNextPlayMusicInfo = async(): Promise<LX.Player.PlayMusicInfo | n
return nextPlayMusicInfo return nextPlayMusicInfo
} }
const handlePlayNext = (playMusicInfo: LX.Player.PlayMusicInfo) => { export const handlePlayNext = (playMusicInfo: LX.Player.PlayMusicInfo) => {
// pause() // pause()
setPlayMusicInfo(playMusicInfo.listId, playMusicInfo.musicInfo, playMusicInfo.isTempPlay)//todo 设置播放音乐 setPlayMusicInfo(playMusicInfo.listId, playMusicInfo.musicInfo, playMusicInfo.isTempPlay)//todo 设置播放音乐
handlePlay() handlePlay()
@ -376,9 +377,35 @@ const handlePlayNext = (playMusicInfo: LX.Player.PlayMusicInfo) => {
*/ */
export const playNext = async(isAutoToggle = false): Promise<void> => { export const playNext = async(isAutoToggle = false): Promise<void> => {
console.log('skip next', isAutoToggle) console.log('skip next', isAutoToggle)
//todo 需要修改逻辑,不要删除 let togglePlayMethod = appSetting['player.togglePlayMethod']
if (!isAutoToggle) {
switch (togglePlayMethod) {
case 'list':
case 'singleLoop':
case 'none':
togglePlayMethod = 'listLoop'
}
}
switch (togglePlayMethod) {
case 'listLoop':
currentPlayIndex.value++
// bug 实际上不是列表循环...
break
case 'random':
currentPlayIndex.value++
break
case 'list':
currentPlayIndex.value++
break
case 'singleLoop':
break
default:
currentPlayIndex.value = -1
console.log('stop toggle play', togglePlayMethod, isAutoToggle)
return
}
if (tempPlayList.length) { // 如果稍后播放列表存在歌曲则直接播放改列表的歌曲 if (tempPlayList.length) { // 如果稍后播放列表存在歌曲则直接播放改列表的歌曲
const playMusicInfo = tempPlayList[++(currentPlayIndex.value) ] const playMusicInfo = tempPlayList[currentPlaybackOrder.value[currentPlayIndex.value]]
// removeTempPlayList(0) // removeTempPlayList(0)
handlePlayNext(playMusicInfo) handlePlayNext(playMusicInfo)
console.log('play temp list') console.log('play temp list')
@ -448,32 +475,32 @@ export const playNext = async(isAutoToggle = false): Promise<void> => {
if (playerIndex == -1 && filteredList.length) playerIndex = 0 if (playerIndex == -1 && filteredList.length) playerIndex = 0
let nextIndex = playerIndex let nextIndex = playerIndex
let togglePlayMethod = appSetting['player.togglePlayMethod'] // let togglePlayMethod = appSetting['player.togglePlayMethod']
if (!isAutoToggle) { // if (!isAutoToggle) {
switch (togglePlayMethod) { // switch (togglePlayMethod) {
case 'list': // case 'list':
case 'singleLoop': // case 'singleLoop':
case 'none': // case 'none':
togglePlayMethod = 'listLoop' // togglePlayMethod = 'listLoop'
} // }
} // }
switch (togglePlayMethod) { // switch (togglePlayMethod) {
case 'listLoop': // case 'listLoop':
nextIndex = playerIndex === filteredList.length - 1 ? 0 : playerIndex + 1 // nextIndex = playerIndex === filteredList.length - 1 ? 0 : playerIndex + 1
break // break
case 'random': // case 'random':
nextIndex = getRandom(0, filteredList.length) // nextIndex = getRandom(0, filteredList.length)
break // break
case 'list': // case 'list':
nextIndex = playerIndex === filteredList.length - 1 ? -1 : playerIndex + 1 // nextIndex = playerIndex === filteredList.length - 1 ? -1 : playerIndex + 1
break // break
case 'singleLoop': // case 'singleLoop':
break // break
default: // default:
nextIndex = -1 // nextIndex = -1
console.log('stop toggle play', togglePlayMethod, isAutoToggle) // console.log('stop toggle play', togglePlayMethod, isAutoToggle)
return // return
} // }
if (nextIndex < 0) { if (nextIndex < 0) {
console.log('next index empty') console.log('next index empty')
return return
@ -490,8 +517,36 @@ export const playNext = async(isAutoToggle = false): Promise<void> => {
* *
*/ */
export const playPrev = async(isAutoToggle = false): Promise<void> => { export const playPrev = async(isAutoToggle = false): Promise<void> => {
// todo 重复代码块,可以提取
let togglePlayMethod = appSetting['player.togglePlayMethod']
if (!isAutoToggle) {
switch (togglePlayMethod) {
case 'list':
case 'singleLoop':
case 'none':
togglePlayMethod = 'listLoop'
}
}
switch (togglePlayMethod) {
case 'listLoop':
currentPlayIndex.value--
// bug 实际上不是列表循环...
break
case 'random':
currentPlayIndex.value--
break
case 'list':
currentPlayIndex.value--
break
case 'singleLoop':
break
default:
currentPlayIndex.value = -1
console.log('stop toggle play', togglePlayMethod, isAutoToggle)
return
}
if (currentPlayIndex.value > 0) { // 如果稍后播放列表存在歌曲则直接播放改列表的歌曲 if (currentPlayIndex.value > 0) { // 如果稍后播放列表存在歌曲则直接播放改列表的歌曲
const playMusicInfo = tempPlayList[--(currentPlayIndex.value) ] const playMusicInfo = tempPlayList[currentPlaybackOrder.value[currentPlayIndex.value]]
// removeTempPlayList(0) // removeTempPlayList(0)
handlePlayNext(playMusicInfo) handlePlayNext(playMusicInfo)
console.log('play temp list') console.log('play temp list')

View File

@ -3,6 +3,7 @@ import {
computed, computed,
} from '@common/utils/vueTools' } from '@common/utils/vueTools'
import { useI18n } from '@renderer/plugins/i18n' import { useI18n } from '@renderer/plugins/i18n'
import { tempPlayList, currentPlayIndex, currentPlaybackOrder } from '@renderer/store/player/state'
// const playNextModes = [ // const playNextModes = [
// 'listLoop', // 'listLoop',
@ -28,6 +29,20 @@ export default () => {
if (mode == appSetting['player.togglePlayMethod']) return if (mode == appSetting['player.togglePlayMethod']) return
// let index = playNextModes.indexOf(appSetting['player.togglePlayMethod']) // let index = playNextModes.indexOf(appSetting['player.togglePlayMethod'])
// if (++index >= playNextModes.length) index = 0 // if (++index >= playNextModes.length) index = 0
const N = tempPlayList.length
const prevPlayIndex = currentPlaybackOrder.value[currentPlayIndex.value]
if (mode === 'random') {
const allIndexes = Array.from({ length: N }, (_, i) => i).filter(i => i !== prevPlayIndex)
for (let i = allIndexes.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1))
;[allIndexes[i], allIndexes[j]] = [allIndexes[j], allIndexes[i]]
}
currentPlaybackOrder.value = [prevPlayIndex, ...allIndexes]
} else {
currentPlaybackOrder.value = Array.from({ length: N }, (_, i) => i)
currentPlayIndex.value = prevPlayIndex
}
// todo 因为只有此函数会修改播放类别,所以直接在这里应用修改效果
setTogglePlayMode(mode) setTogglePlayMode(mode)
} }

View File

@ -1,6 +1,6 @@
import { addTempPlayList, clearTempPlayeList, getList } from '@renderer/store/player/action' import { addTempPlayList, clearTempPlayeList, getList } from '@renderer/store/player/action'
import { tempPlayList, currentPlayIndex, currentPlaybackOrder } from '@renderer/store/player/state' import { tempPlayList, currentPlayIndex, currentPlaybackOrder } from '@renderer/store/player/state'
import { playNext } from '@renderer/core/player' import { handlePlayNext } from '@renderer/core/player'
import { appSetting } from '@renderer/store/setting' import { appSetting } from '@renderer/store/setting'
// import { arrShuffle } from '@common/utils/common' // import { arrShuffle } from '@common/utils/common'
// setup 函数或组件初始化中 // setup 函数或组件初始化中
@ -11,12 +11,7 @@ export default ({ props, selectedList, list, removeAllSelect }) => {
let clickIndex = -1 let clickIndex = -1
const handlePlayMusic = (index) => { const handlePlayMusic = (index) => {
currentPlayIndex.value = index currentPlayIndex.value = 0
// todo 播放选中的歌曲
// todo 修改播放歌曲逻辑
// playList(props.listId, index)
// handlePlayMusicLater(index, true)
// todo 歌单本身就有乱序排序功能
if (tempPlayList.length > 0) { // 双击操作会切换到当前歌单 if (tempPlayList.length > 0) { // 双击操作会切换到当前歌单
clearTempPlayeList() clearTempPlayeList()
} }
@ -24,11 +19,21 @@ export default ({ props, selectedList, list, removeAllSelect }) => {
for (let music of currentchooselist) { for (let music of currentchooselist) {
addTempPlayList([{ listId: props.listId, musicInfo: music }]) addTempPlayList([{ listId: props.listId, musicInfo: music }])
} }
if (appSetting['player.togglePlayMethod'] == 'random') { // todo 重复代码块,可提取
// todo 随机播放 const N = tempPlayList.length
// arrShuffle(tempPlayList) if (appSetting['player.togglePlayMethod'] === 'random') {
const allIndexes = Array.from({ length: N }, (_, i) => i).filter(i => i !== index)
for (let i = allIndexes.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1))
;[allIndexes[i], allIndexes[j]] = [allIndexes[j], allIndexes[i]]
} }
playNext() currentPlaybackOrder.value = [index, ...allIndexes]
} else {
currentPlaybackOrder.value = Array.from({ length: N }, (_, i) => i)
currentPlayIndex.value = index
}
const playMusicInfo = tempPlayList[currentPlaybackOrder.value[currentPlayIndex.value]]
handlePlayNext(playMusicInfo)
} }
const handlePlayMusicLater = (index, single) => { const handlePlayMusicLater = (index, single) => {