feat: 新增播放上一首歌曲功能 #90
This commit is contained in:
parent
d7385405d9
commit
d71f99de53
@ -16,6 +16,7 @@ def default_key_word_dict():
|
||||
"播放本地歌曲": "playlocal",
|
||||
"关机": "stop",
|
||||
"下一首": "play_next",
|
||||
"上一首": "play_prev",
|
||||
"单曲循环": "set_play_type_one",
|
||||
"全部循环": "set_play_type_all",
|
||||
"随机播放": "set_random_play",
|
||||
@ -46,6 +47,7 @@ def default_key_match_order():
|
||||
"分钟后关机",
|
||||
"播放歌曲",
|
||||
"下一首",
|
||||
"上一首",
|
||||
"单曲循环",
|
||||
"全部循环",
|
||||
"随机播放",
|
||||
|
@ -1,6 +1,9 @@
|
||||
$(function(){
|
||||
$container=$("#cmds");
|
||||
|
||||
append_op_button_name("加入收藏");
|
||||
append_op_button_name("取消收藏");
|
||||
|
||||
const PLAY_TYPE_ONE = 0; // 单曲循环
|
||||
const PLAY_TYPE_ALL = 1; // 全部循环
|
||||
const PLAY_TYPE_RND = 2; // 随机播放
|
||||
@ -8,12 +11,11 @@ $(function(){
|
||||
append_op_button("play_type_one", "单曲循环", "单曲循环");
|
||||
append_op_button("play_type_rnd", "随机播放", "随机播放");
|
||||
|
||||
append_op_button_name("刷新列表");
|
||||
append_op_button_name("下一首");
|
||||
append_op_button_name("上一首");
|
||||
append_op_button_name("关机");
|
||||
append_op_button_name("下一首");
|
||||
|
||||
append_op_button_name("加入收藏");
|
||||
append_op_button_name("取消收藏");
|
||||
append_op_button_name("刷新列表");
|
||||
|
||||
$container.append($("<hr>"));
|
||||
|
||||
@ -100,8 +102,7 @@ $(function(){
|
||||
const selectedValue = $(this).val();
|
||||
localStorage.setItem('cur_playlist', selectedValue);
|
||||
$('#music_name').empty();
|
||||
const sorted_musics = data[selectedValue].sort(custom_sort_key);
|
||||
$.each(sorted_musics, function(index, item) {
|
||||
$.each(data[selectedValue], function(index, item) {
|
||||
$('#music_name').append($('<option></option>').val(item).text(item));
|
||||
});
|
||||
});
|
||||
@ -273,23 +274,4 @@ $(function(){
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function custom_sort_key(a, b) {
|
||||
// 使用正则表达式提取数字前缀
|
||||
const numericPrefixA = a.match(/^(\d+)/) ? parseInt(a.match(/^(\d+)/)[1], 10) : null;
|
||||
const numericPrefixB = b.match(/^(\d+)/) ? parseInt(b.match(/^(\d+)/)[1], 10) : null;
|
||||
|
||||
// 如果两个键都有数字前缀,则按数字大小排序
|
||||
if (numericPrefixA !== null && numericPrefixB !== null) {
|
||||
return numericPrefixA - numericPrefixB;
|
||||
}
|
||||
|
||||
// 如果一个键有数字前缀而另一个没有,则有数字前缀的键排在前面
|
||||
if (numericPrefixA !== null) return -1;
|
||||
if (numericPrefixB !== null) return 1;
|
||||
|
||||
// 如果两个键都没有数字前缀,则按照常规字符串排序
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
import asyncio
|
||||
import copy
|
||||
import json
|
||||
import logging
|
||||
import math
|
||||
@ -721,6 +722,9 @@ class XiaoMusic:
|
||||
async def play_next(self, did="", **kwargs):
|
||||
return await self.devices[did].play_next()
|
||||
|
||||
async def play_prev(self, did="", **kwargs):
|
||||
return await self.devices[did].play_prev()
|
||||
|
||||
# 停止
|
||||
async def stop(self, did="", arg1="", **kwargs):
|
||||
return await self.devices[did].stop(arg1=arg1)
|
||||
@ -797,7 +801,7 @@ class XiaoMusic:
|
||||
|
||||
# 正在播放中的音乐
|
||||
def playingmusic(self, did):
|
||||
cur_music = self.devices[did].cur_music
|
||||
cur_music = self.devices[did].get_cur_music()
|
||||
self.log.debug(f"playingmusic. cur_music:{cur_music}")
|
||||
return cur_music
|
||||
|
||||
@ -841,7 +845,6 @@ class XiaoMusic:
|
||||
def save_cur_config(self):
|
||||
for did in self.config.devices.keys():
|
||||
deviceobj = self.devices.get(did)
|
||||
self.log.info(deviceobj.device)
|
||||
if deviceobj is not None:
|
||||
self.config.devices[did] = deviceobj.device
|
||||
data = asdict(self.config)
|
||||
@ -917,7 +920,6 @@ class XiaoMusicDevice:
|
||||
self.ffmpeg_location = self.config.ffmpeg_location
|
||||
|
||||
self._download_proc = None # 下载对象
|
||||
self.cur_music = self.device.cur_music
|
||||
self._next_timer = None
|
||||
self._timeout = 0
|
||||
self._playing = False
|
||||
@ -926,12 +928,21 @@ class XiaoMusicDevice:
|
||||
self._last_cmd = None
|
||||
self.update_playlist()
|
||||
|
||||
def get_cur_music(self):
|
||||
return self.device.cur_music
|
||||
|
||||
# 初始化播放列表
|
||||
def update_playlist(self):
|
||||
self._cur_play_list = self.device.cur_playlist
|
||||
if self._cur_play_list not in self.xiaomusic.music_list:
|
||||
self._cur_play_list = "全部"
|
||||
self._play_list = self.xiaomusic.music_list.get(self._cur_play_list)
|
||||
if self.device.cur_playlist not in self.xiaomusic.music_list:
|
||||
self.device.cur_playlist = "全部"
|
||||
|
||||
list_name = self.device.cur_playlist
|
||||
self._play_list = copy.copy(self.xiaomusic.music_list[list_name])
|
||||
if self.device.play_type == PLAY_TYPE_RND:
|
||||
random.shuffle(self._play_list)
|
||||
self.log.info(f"随机打乱 {list_name} {self._play_list}")
|
||||
else:
|
||||
self.log.info(f"没打乱 {list_name} {self._play_list}")
|
||||
|
||||
# 播放歌曲
|
||||
async def play(self, name="", search_key=""):
|
||||
@ -944,7 +955,7 @@ class XiaoMusicDevice:
|
||||
await self._play_next()
|
||||
return
|
||||
else:
|
||||
name = self.cur_music
|
||||
name = self.get_cur_music()
|
||||
self.log.info(f"play. search_key:{search_key} name:{name}")
|
||||
|
||||
# 本地歌曲不存在时下载
|
||||
@ -966,7 +977,7 @@ class XiaoMusicDevice:
|
||||
|
||||
async def _play_next(self):
|
||||
self.log.info("开始播放下一首")
|
||||
name = self.cur_music
|
||||
name = self.get_cur_music()
|
||||
if (
|
||||
self.device.play_type == PLAY_TYPE_ALL
|
||||
or self.device.play_type == PLAY_TYPE_RND
|
||||
@ -974,7 +985,27 @@ class XiaoMusicDevice:
|
||||
or (name not in self._play_list)
|
||||
):
|
||||
name = self.get_next_music()
|
||||
self.log.info(f"_play_next. name:{name}, cur_music:{self.cur_music}")
|
||||
self.log.info(f"_play_next. name:{name}, cur_music:{self.get_cur_music()}")
|
||||
if name == "":
|
||||
await self.do_tts("本地没有歌曲")
|
||||
return
|
||||
await self._play(name)
|
||||
|
||||
# 上一首
|
||||
async def play_prev(self):
|
||||
return await self._play_prev()
|
||||
|
||||
async def _play_prev(self):
|
||||
self.log.info("开始播放上一首")
|
||||
name = self.get_cur_music()
|
||||
if (
|
||||
self.device.play_type == PLAY_TYPE_ALL
|
||||
or self.device.play_type == PLAY_TYPE_RND
|
||||
or name == ""
|
||||
or (name not in self._play_list)
|
||||
):
|
||||
name = self.get_prev_music()
|
||||
self.log.info(f"_play_prev. name:{name}, cur_music:{self.get_cur_music()}")
|
||||
if name == "":
|
||||
await self.do_tts("本地没有歌曲")
|
||||
return
|
||||
@ -988,7 +1019,7 @@ class XiaoMusicDevice:
|
||||
await self._play_next()
|
||||
return
|
||||
else:
|
||||
name = self.cur_music
|
||||
name = self.get_cur_music()
|
||||
|
||||
self.log.info(f"playlocal. name:{name}")
|
||||
|
||||
@ -1004,10 +1035,9 @@ class XiaoMusicDevice:
|
||||
self.cancel_group_next_timer()
|
||||
|
||||
self._playing = True
|
||||
self.cur_music = name
|
||||
self.device.cur_music = name
|
||||
|
||||
self.log.info(f"cur_music {self.cur_music}")
|
||||
self.log.info(f"cur_music {self.get_cur_music()}")
|
||||
sec, url = await self.xiaomusic.get_music_sec_url(name)
|
||||
await self.group_force_stop_xiaoai()
|
||||
self.log.info(f"播放 {url}")
|
||||
@ -1041,7 +1071,7 @@ class XiaoMusicDevice:
|
||||
# 最大等8秒
|
||||
sec = min(8, int(len(value) / 3))
|
||||
await asyncio.sleep(sec)
|
||||
self.log.info(f"do_tts ok. cur_music:{self.cur_music}")
|
||||
self.log.info(f"do_tts ok. cur_music:{self.get_cur_music()}")
|
||||
await self.check_replay()
|
||||
|
||||
async def force_stop_xiaoai(self, device_id):
|
||||
@ -1143,51 +1173,62 @@ class XiaoMusicDevice:
|
||||
self.log.info(f"add_download_music add_music {name}")
|
||||
self.log.debug(self._play_list)
|
||||
|
||||
# 获取下一首
|
||||
def get_next_music(self):
|
||||
def get_music(self, direction="next"):
|
||||
play_list_len = len(self._play_list)
|
||||
if play_list_len == 0:
|
||||
self.log.warning("当前播放列表没有歌曲")
|
||||
return ""
|
||||
index = 0
|
||||
try:
|
||||
index = self._play_list.index(self.cur_music)
|
||||
index = self._play_list.index(self.get_cur_music())
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if play_list_len == 1:
|
||||
next_index = index # 当只有一首歌曲时保持当前索引不变
|
||||
new_index = index # 当只有一首歌曲时保持当前索引不变
|
||||
else:
|
||||
# 顺序往后找1个
|
||||
next_index = index + 1
|
||||
if next_index >= play_list_len:
|
||||
next_index = 0
|
||||
# 排除当前歌曲随机找1个
|
||||
if self.device.play_type == PLAY_TYPE_RND:
|
||||
indices = list(range(play_list_len))
|
||||
indices.remove(index)
|
||||
next_index = random.choice(indices)
|
||||
name = self._play_list[next_index]
|
||||
if direction == "next":
|
||||
new_index = index + 1
|
||||
if new_index >= play_list_len:
|
||||
new_index = 0
|
||||
elif direction == "prev":
|
||||
new_index = index - 1
|
||||
if new_index < 0:
|
||||
new_index = play_list_len - 1
|
||||
else:
|
||||
self.log.error("无效的方向参数")
|
||||
return ""
|
||||
|
||||
name = self._play_list[new_index]
|
||||
if not self.xiaomusic.is_music_exist(name):
|
||||
self._play_list.pop(next_index)
|
||||
self.log.info(f"pop not exist music:{name}")
|
||||
return self.get_next_music()
|
||||
self._play_list.pop(new_index)
|
||||
self.log.info(f"pop not exist music: {name}")
|
||||
return self.get_music(direction)
|
||||
return name
|
||||
|
||||
# 获取下一首
|
||||
def get_next_music(self):
|
||||
return self.get_music(direction="next")
|
||||
|
||||
# 获取上一首
|
||||
def get_prev_music(self):
|
||||
return self.get_music(direction="prev")
|
||||
|
||||
# 判断是否播放下一首歌曲
|
||||
def check_play_next(self):
|
||||
# 当前歌曲不在当前播放列表
|
||||
if self.cur_music not in self._play_list:
|
||||
self.log.info(f"当前歌曲 {self.cur_music} 不在当前播放列表")
|
||||
if self.get_cur_music() not in self._play_list:
|
||||
self.log.info(f"当前歌曲 {self.get_cur_music()} 不在当前播放列表")
|
||||
return True
|
||||
|
||||
# 当前没我在播放的歌曲
|
||||
if self.cur_music == "":
|
||||
if self.get_cur_music() == "":
|
||||
self.log.info("当前没我在播放的歌曲")
|
||||
return True
|
||||
else:
|
||||
# 当前播放的歌曲不存在了
|
||||
if not self.xiaomusic.is_music_exist(self.cur_music):
|
||||
self.log.info(f"当前播放的歌曲 {self.cur_music} 不存在了")
|
||||
if not self.xiaomusic.is_music_exist(self.get_cur_music()):
|
||||
self.log.info(f"当前播放的歌曲 {self.get_cur_music()} 不存在了")
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -1289,12 +1330,12 @@ class XiaoMusicDevice:
|
||||
self.xiaomusic.save_cur_config()
|
||||
tts = PLAY_TYPE_TTS[play_type]
|
||||
await self.do_tts(tts)
|
||||
self.update_playlist()
|
||||
|
||||
async def play_music_list(self, list_name, music_name):
|
||||
self._last_cmd = "play_music_list"
|
||||
self._cur_play_list = list_name
|
||||
self.device.cur_playlist = list_name
|
||||
self._play_list = self.xiaomusic.music_list[list_name]
|
||||
self.update_playlist()
|
||||
self.log.info(f"开始播放列表{list_name}")
|
||||
await self._play(music_name)
|
||||
|
||||
@ -1344,7 +1385,7 @@ class XiaoMusicDevice:
|
||||
device.cancel_next_timer()
|
||||
|
||||
def get_cur_play_list(self):
|
||||
return self._cur_play_list
|
||||
return self.device.cur_playlist
|
||||
|
||||
# 清空所有定时器
|
||||
def cancel_all_timer(self):
|
||||
|
Loading…
Reference in New Issue
Block a user