use async task for building tags (#195)
* use threading for building tags * change tag cache to use asyncio * sleep 0 is not effective, change to 0.001
This commit is contained in:
parent
917c6d21c8
commit
609cb4f10f
@ -73,6 +73,7 @@ class XiaoMusic:
|
|||||||
self.devices = {} # key 为 did
|
self.devices = {} # key 为 did
|
||||||
self.running_task = []
|
self.running_task = []
|
||||||
self.all_music_tags = {} # 歌曲额外信息
|
self.all_music_tags = {} # 歌曲额外信息
|
||||||
|
self._tag_generation_task = False
|
||||||
self._extra_index_search = {}
|
self._extra_index_search = {}
|
||||||
|
|
||||||
# 初始化配置
|
# 初始化配置
|
||||||
@ -440,6 +441,8 @@ class XiaoMusic:
|
|||||||
|
|
||||||
# 给前端调用
|
# 给前端调用
|
||||||
def refresh_music_tag(self):
|
def refresh_music_tag(self):
|
||||||
|
if not self.ensure_single_thread_for_tag():
|
||||||
|
return
|
||||||
filename = self.config.tag_cache_path
|
filename = self.config.tag_cache_path
|
||||||
if filename is not None:
|
if filename is not None:
|
||||||
# 清空 cache
|
# 清空 cache
|
||||||
@ -449,8 +452,8 @@ class XiaoMusic:
|
|||||||
else:
|
else:
|
||||||
self.log.info("刷新:tag cache 未启用")
|
self.log.info("刷新:tag cache 未启用")
|
||||||
# TODO: 优化性能?
|
# TODO: 优化性能?
|
||||||
self._gen_all_music_list()
|
self.try_gen_all_music_tag()
|
||||||
self.log.debug("刷新:已重建 tag cache")
|
self.log.info("刷新:已启动重建 tag cache")
|
||||||
|
|
||||||
def try_load_from_tag_cache(self) -> dict:
|
def try_load_from_tag_cache(self) -> dict:
|
||||||
filename = self.config.tag_cache_path
|
filename = self.config.tag_cache_path
|
||||||
@ -478,10 +481,50 @@ class XiaoMusic:
|
|||||||
else:
|
else:
|
||||||
self.log.info("保存:tag cache 未启用")
|
self.log.info("保存:tag cache 未启用")
|
||||||
|
|
||||||
|
def ensure_single_thread_for_tag(self):
|
||||||
|
if self._tag_generation_task:
|
||||||
|
self.log.info(f"tag 更新中,请等待")
|
||||||
|
return not self._tag_generation_task
|
||||||
|
|
||||||
|
def try_gen_all_music_tag(self, only_items: dict = None):
|
||||||
|
if self.ensure_single_thread_for_tag():
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
if loop.is_running():
|
||||||
|
asyncio.ensure_future(self._gen_all_music_tag(only_items))
|
||||||
|
self.log.info("启动后台构建 tag cache")
|
||||||
|
else:
|
||||||
|
self.log.info("协程时间循环未启动")
|
||||||
|
|
||||||
|
async def _gen_all_music_tag(self, only_items: dict = None):
|
||||||
|
self._tag_generation_task = True
|
||||||
|
if only_items is None:
|
||||||
|
only_items = self.all_music # 默认更新全部
|
||||||
|
|
||||||
|
all_music_tags = self.try_load_from_tag_cache()
|
||||||
|
all_music_tags.update(self.all_music_tags) # 保证最新
|
||||||
|
for name, file_or_url in only_items.items():
|
||||||
|
await asyncio.sleep(0.001)
|
||||||
|
if name not in all_music_tags:
|
||||||
|
try:
|
||||||
|
if self.is_web_music(name):
|
||||||
|
# TODO: 网络歌曲获取歌曲额外信息
|
||||||
|
pass
|
||||||
|
elif os.path.exists(file_or_url):
|
||||||
|
all_music_tags[name] = get_audio_metadata(file_or_url)
|
||||||
|
else:
|
||||||
|
self.log.info(f"{name}/{file_or_url} 无法更新 tag")
|
||||||
|
except BaseException as e:
|
||||||
|
self.log.info(f"{e} {file_or_url} error {type(file_or_url)}!")
|
||||||
|
# 全部更新结束后,一次性赋值
|
||||||
|
self.all_music_tags = all_music_tags
|
||||||
|
# 刷新 tag cache
|
||||||
|
self.try_save_tag_cache()
|
||||||
|
self._tag_generation_task = False
|
||||||
|
self.log.info(f"tag 更新完成")
|
||||||
|
|
||||||
# 获取目录下所有歌曲,生成随机播放列表
|
# 获取目录下所有歌曲,生成随机播放列表
|
||||||
def _gen_all_music_list(self):
|
def _gen_all_music_list(self):
|
||||||
self.all_music = {}
|
self.all_music = {}
|
||||||
self.all_music_tags = self.try_load_from_tag_cache()
|
|
||||||
all_music_by_dir = {}
|
all_music_by_dir = {}
|
||||||
local_musics = traverse_music_directory(
|
local_musics = traverse_music_directory(
|
||||||
self.music_path,
|
self.music_path,
|
||||||
@ -505,8 +548,6 @@ class XiaoMusic:
|
|||||||
filename = os.path.basename(file)
|
filename = os.path.basename(file)
|
||||||
(name, _) = os.path.splitext(filename)
|
(name, _) = os.path.splitext(filename)
|
||||||
self.all_music[name] = file
|
self.all_music[name] = file
|
||||||
if name not in self.all_music_tags:
|
|
||||||
self.all_music_tags[name] = get_audio_metadata(file)
|
|
||||||
all_music_by_dir[dir_name][name] = True
|
all_music_by_dir[dir_name][name] = True
|
||||||
self.log.debug(f"_gen_all_music_list {name}:{dir_name}:{file}")
|
self.log.debug(f"_gen_all_music_list {name}:{dir_name}:{file}")
|
||||||
|
|
||||||
@ -547,8 +588,8 @@ class XiaoMusic:
|
|||||||
if not (v.startswith("http") or v.startswith("https")):
|
if not (v.startswith("http") or v.startswith("https")):
|
||||||
self._extra_index_search[v] = k
|
self._extra_index_search[v] = k
|
||||||
|
|
||||||
# 刷新 tag cache
|
# all_music 更新,重建 tag
|
||||||
self.try_save_tag_cache()
|
self.try_gen_all_music_tag()
|
||||||
|
|
||||||
def _append_custom_play_list(self):
|
def _append_custom_play_list(self):
|
||||||
if not self.config.custom_play_list_json:
|
if not self.config.custom_play_list_json:
|
||||||
@ -581,9 +622,6 @@ class XiaoMusic:
|
|||||||
if (not name) or (not url):
|
if (not name) or (not url):
|
||||||
continue
|
continue
|
||||||
self.all_music[name] = url
|
self.all_music[name] = url
|
||||||
# TODO: 网络歌曲获取歌曲额外信息
|
|
||||||
# if name not in self.all_music_tags:
|
|
||||||
# self.all_music_tags[name] = get_audio_metadata(url)
|
|
||||||
one_music_list.append(name)
|
one_music_list.append(name)
|
||||||
|
|
||||||
# 处理电台列表
|
# 处理电台列表
|
||||||
@ -605,6 +643,7 @@ class XiaoMusic:
|
|||||||
await asyncio.sleep(3600)
|
await asyncio.sleep(3600)
|
||||||
|
|
||||||
async def run_forever(self):
|
async def run_forever(self):
|
||||||
|
self.try_gen_all_music_tag() # 事件循环开始后调用一次
|
||||||
self.crontab.start()
|
self.crontab.start()
|
||||||
await self.analytics.send_startup_event()
|
await self.analytics.send_startup_event()
|
||||||
analytics_task = asyncio.create_task(self.analytics_task_daily())
|
analytics_task = asyncio.create_task(self.analytics_task_daily())
|
||||||
@ -1395,7 +1434,10 @@ class XiaoMusicDevice:
|
|||||||
|
|
||||||
# 把下载的音乐加入播放列表
|
# 把下载的音乐加入播放列表
|
||||||
def add_download_music(self, name):
|
def add_download_music(self, name):
|
||||||
self.xiaomusic.all_music[name] = os.path.join(self.download_path, f"{name}.mp3")
|
filepath = os.path.join(self.download_path, f"{name}.mp3")
|
||||||
|
self.xiaomusic.all_music[name] = filepath
|
||||||
|
# 应该很快,直接运行
|
||||||
|
self.xiaomusic._gen_all_music_tag({name: filepath})
|
||||||
if name not in self._play_list:
|
if name not in self._play_list:
|
||||||
self._play_list.append(name)
|
self._play_list.append(name)
|
||||||
self.log.info(f"add_download_music add_music {name}")
|
self.log.info(f"add_download_music add_music {name}")
|
||||||
|
Loading…
Reference in New Issue
Block a user