feat: 增加 tags 缓存 (#193)

This commit is contained in:
Gao, Ruiyuan 2024-09-23 02:31:28 +08:00 committed by GitHub
parent 3110c2221b
commit 7c9576874b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 60 additions and 3 deletions

View File

@ -235,6 +235,7 @@ docker build -t xiaomusic .
- XIAOMUSIC_HTTPAUTH_USERNAME 配置 web 控制台用户,对应后台的 【web控制台账户】
- XIAOMUSIC_HTTPAUTH_PASSWORD 配置 web 控制台密码,对应后台的 【web控制台密码】
- XIAOMUSIC_CONF_PATH 用来存放配置文件的目录,对应后台的 【配置文件目录】,记得把目录映射到主机,默认为 `/app/config` ,具体见 <https://github.com/hanxi/xiaomusic/issues/74>
- XIAOMUSIC_TAG_CACHE_DIR 用来音乐 tag 缓存,默认为空(不缓存)
- XIAOMUSIC_DISABLE_DOWNLOAD 设为 true 时关闭下载功能,对应后台的 【关闭下载功能】,见 <https://github.com/hanxi/xiaomusic/issues/82>
- XIAOMUSIC_USE_MUSIC_API 设为 true 时使用 player_play_music 接口播放音乐,对应后台的 【触屏版兼容模式】,用于兼容不能播放的型号,如果发现需要设置这个选项的时候请告知我加一下设备型号,方便以后不用设置。 见 <https://github.com/hanxi/xiaomusic/issues/30>
- XIAOMUSIC_KEYWORDS_PLAY 用来播放歌曲的口令前缀,对应后台的 【播放歌曲口令】,默认是 "播放歌曲,放歌曲" ,可以用英文逗号分割配置多个

View File

@ -7,6 +7,7 @@
"music_path": "music",
"download_path": "",
"conf_path": null,
"tag_cache_dir": null,
"hostname": "192.168.2.5",
"port": 8090,
"public_port": 0,

View File

@ -84,6 +84,7 @@ class Config:
) # 只能是music目录下的子目录
download_path: str = os.getenv("XIAOMUSIC_DOWNLOAD_PATH", "music/download")
conf_path: str = os.getenv("XIAOMUSIC_CONF_PATH", "conf")
tag_cache_dir: str = os.getenv("XIAOMUSIC_TAG_CACHE_DIR", None)
hostname: str = os.getenv("XIAOMUSIC_HOSTNAME", "192.168.2.5")
port: int = int(os.getenv("XIAOMUSIC_PORT", "8090")) # 监听端口
public_port: int = int(os.getenv("XIAOMUSIC_PUBLIC_PORT", 0)) # 歌曲访问端口
@ -246,3 +247,13 @@ class Config:
os.makedirs(self.conf_path)
filename = os.path.join(self.conf_path, "setting.json")
return filename
@property
def tag_cache_path(self):
if self.tag_cache_dir is None:
return None
if not os.path.exists(self.tag_cache_dir):
os.makedirs(self.tag_cache_dir)
filename = os.path.join(self.tag_cache_dir, "tag_cache.json")
return filename

View File

@ -437,10 +437,47 @@ class XiaoMusic:
encoded_name = urllib.parse.quote(filename)
return f"{self.hostname}:{self.public_port}/music/{encoded_name}"
# 给前端调用
def refresh_music_tag(self):
filename = self.config.tag_cache_path
if filename is not None:
# 清空 cache
with open(filename, "w", encoding="utf-8") as f:
json.dump({}, f, ensure_ascii=False, indent=2)
self.log.info(f"刷新:已清空 tag cache")
else:
self.log.info(f"刷新tag cache 未启用")
#TODO: 优化性能?
self._gen_all_music_list()
self.log.debug(f"刷新:已重建 tag cache")
def try_load_from_tag_cache(self) -> dict:
filename = self.config.tag_cache_path
tag_cache = {}
if filename is not None:
if os.path.exists(filename):
with open(filename, "r", encoding="utf-8") as f:
tag_cache = json.load(f)
self.log.info(f"已从【{filename}】加载 tag cache")
else:
self.log.info(f"{filename}】tag cache 已启用,但文件不存在")
else:
self.log.info(f"加载tag cache 未启用")
return tag_cache
def try_save_tag_cache(self):
filename = self.config.tag_cache_path
if filename is not None:
with open(filename, "w", encoding="utf-8") as f:
json.dump(self.all_music_tags, f, ensure_ascii=False, indent=2)
self.log.info(f"保存tag cache 已保存到【{filename}")
else:
self.log.info(f"保存tag cache 未启用")
# 获取目录下所有歌曲,生成随机播放列表
def _gen_all_music_list(self):
self.all_music = {}
self.all_music_tags = {}
self.all_music_tags = self.try_load_from_tag_cache()
all_music_by_dir = {}
local_musics = traverse_music_directory(
self.music_path,
@ -464,7 +501,10 @@ class XiaoMusic:
filename = os.path.basename(file)
(name, _) = os.path.splitext(filename)
self.all_music[name] = file
self.all_music_tags[name] = get_audio_metadata(file)
if name not in self.all_music_tags:
self.all_music_tags[name] = {
k: str(v) for k, v in get_audio_metadata(file).items()}
print(f"加载 {name} tag")
all_music_by_dir[dir_name][name] = True
self.log.debug(f"_gen_all_music_list {name}:{dir_name}:{file}")
@ -505,6 +545,9 @@ class XiaoMusic:
if not (v.startswith("http") or v.startswith("https")):
self._extra_index_search[v] = k
# 刷新 tag cache
self.try_save_tag_cache()
def _append_custom_play_list(self):
if not self.config.custom_play_list_json:
return
@ -537,7 +580,8 @@ class XiaoMusic:
continue
self.all_music[name] = url
# TODO: 网络歌曲获取歌曲额外信息
# self.all_music_tags[name] = get_audio_metadata(url)
# if name not in self.all_music_tags:
# self.all_music_tags[name] = get_audio_metadata(url)
one_music_list.append(name)
# 处理电台列表